示例#1
0
		public IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			var varDecl = GetVariableDeclarationStatement(context);
			IType type;
			if (varDecl != null) {
				type = context.Resolve(varDecl.Variables.First().Initializer).Type;
			} else {
				var foreachStatement = GetForeachStatement(context);
				if (foreachStatement == null) {
					yield break;
				}
				type = context.Resolve(foreachStatement.VariableType).Type;
			}
			
			if (!(!type.Equals(SpecialType.NullType) && !type.Equals(SpecialType.UnknownType))) {
				yield break;
			}
			yield return new CodeAction (context.TranslateString("Use explicit type"), script => {
				if (varDecl != null) {
					script.Replace (varDecl.Type, context.CreateShortType (type));
				} else {
					var foreachStatement = GetForeachStatement (context);
					script.Replace (foreachStatement.VariableType, context.CreateShortType (type));
				}
			});
		}
		public void Run (RefactoringContext context)
		{
			var switchStatement = GetSwitchStatement (context);
			
			var result = context.Resolve (switchStatement.Expression);
			var type = result.Type;
			var newSwitch = (SwitchStatement)switchStatement.Clone ();
			
			var target = new TypeReferenceExpression (context.CreateShortType (result.Type.Resolve (context.TypeResolveContext)));
			foreach (var field in type.GetFields (context.TypeResolveContext)) {
				if (field.IsSynthetic || !field.IsConst)
					continue;
				newSwitch.SwitchSections.Add (new SwitchSection () {
					CaseLabels = {
						new CaseLabel (new MemberReferenceExpression (target.Clone (), field.Name))
					},
					Statements = {
						new BreakStatement ()
					}
				});
			}
			
			newSwitch.SwitchSections.Add (new SwitchSection () {
				CaseLabels = {
					new CaseLabel ()
				},
				Statements = {
					new ThrowStatement (new ObjectCreateExpression (context.CreateShortType ("System", "ArgumentOutOfRangeException")))
				}
			});
			
			using (var script = context.StartScript ()) {
				script.Replace (switchStatement, newSwitch);
			}
		}
 static TypeDeclaration AddBaseTypesAccordingToNamingRules(RefactoringContext context, NamingConventionService service, TypeDeclaration result)
 {
     if (service.HasValidRule(result.Name, AffectedEntity.CustomAttributes, Modifiers.Public)) {
         result.BaseTypes.Add(context.CreateShortType("System", "Attribute"));
     } else if (service.HasValidRule(result.Name, AffectedEntity.CustomEventArgs, Modifiers.Public)) {
         result.BaseTypes.Add(context.CreateShortType("System", "EventArgs"));
     } else if (service.HasValidRule(result.Name, AffectedEntity.CustomExceptions, Modifiers.Public)) {
         result.BaseTypes.Add(context.CreateShortType("System", "Exception"));
     }
     return result;
 }
示例#4
0
		public IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			var pexpr = context.GetNode<PrimitiveExpression>();
			if (pexpr == null)
				yield break;
			var statement = context.GetNode<Statement>();
			if (statement == null) {
				yield break;
			}

			var resolveResult = context.Resolve(pexpr);

			yield return new CodeAction(context.TranslateString("Create local constant"), script => {
				string name = CreateMethodDeclarationAction.CreateBaseName(pexpr, resolveResult.Type);
				var service = (NamingConventionService)context.GetService(typeof(NamingConventionService));
				if (service != null)
					name = service.CheckName(context, name, AffectedEntity.LocalConstant);

				var initializer = new VariableInitializer(name, pexpr.Clone());
				var decl = new VariableDeclarationStatement() {
					Type = context.CreateShortType(resolveResult.Type),
					Modifiers = Modifiers.Const,
					Variables = { initializer }
				};

				script.InsertBefore(statement, decl);
				var variableUsage = new IdentifierExpression(name);
				script.Replace(pexpr, variableUsage);
				script.Link(initializer.NameToken, variableUsage);
			});

			yield return new CodeAction(context.TranslateString("Create constant field"), script => {
				string name = CreateMethodDeclarationAction.CreateBaseName(pexpr, resolveResult.Type);
				var service = (NamingConventionService)context.GetService(typeof(NamingConventionService));
				if (service != null)
					name = service.CheckName(context, name, AffectedEntity.ConstantField);

				var initializer = new VariableInitializer(name, pexpr.Clone());

				var decl = new FieldDeclaration() {
					ReturnType = context.CreateShortType(resolveResult.Type),
					Modifiers = Modifiers.Const,
					Variables = { initializer }
				};

				var variableUsage = new IdentifierExpression(name);
				script.Replace(pexpr, variableUsage);
//				script.Link(initializer.NameToken, variableUsage);
				script.InsertWithCursor(context.TranslateString("Create constant"), Script.InsertPosition.Before, decl);
			});
		}
		public void Run (RefactoringContext context)
		{
			VariableInitializer initializer;
			var eventDeclaration = GetEventDeclaration (context, out initializer);
			var type = context.GetDefinition (context.ResolveType (eventDeclaration.ReturnType));
			if (type == null)
				return;
			var invokeMethod = type.Methods.Where (m => m.Name == "Invoke").FirstOrDefault ();
			if (invokeMethod == null)
				return;
			
			bool hasSenderParam = false;
			IEnumerable<IParameter> pars = invokeMethod.Parameters;
			if (invokeMethod.Parameters.Any ()) {
				var first = invokeMethod.Parameters [0];
				if (first.Name == "sender" /*&& first.Type == "System.Object"*/) {
					hasSenderParam = true;
					pars = invokeMethod.Parameters.Skip (1);
				}
			}
			const string handlerName = "handler";
					
			var arguments = new List<Expression> ();
			if (hasSenderParam)
				arguments.Add (new ThisReferenceExpression ());
			foreach (var par in pars)
				arguments.Add (new IdentifierExpression (par.Name));
			
			var methodDeclaration = new MethodDeclaration () {
				Name = "On" + initializer.Name,
				ReturnType = context.CreateShortType (eventDeclaration.ReturnType),
				Modifiers = ICSharpCode.NRefactory.CSharp.Modifiers.Protected | ICSharpCode.NRefactory.CSharp.Modifiers.Virtual,
				Body = new BlockStatement () {
					new VariableDeclarationStatement (context.CreateShortType (eventDeclaration.ReturnType), handlerName, new MemberReferenceExpression (new ThisReferenceExpression (), initializer.Name)),
					new IfElseStatement () {
						Condition = new BinaryOperatorExpression (new IdentifierExpression (handlerName), BinaryOperatorType.InEquality, new PrimitiveExpression (null)),
						TrueStatement = new ExpressionStatement (new InvocationExpression (new IdentifierExpression (handlerName), arguments))
					}
				}
			};
			
			foreach (var par in pars) {
				var typeName = context.CreateShortType (par.Type.Resolve (context.TypeResolveContext));
				var decl = new ParameterDeclaration (typeName, par.Name);
				methodDeclaration.Parameters.Add (decl);
			}
			
			using (var script = context.StartScript ()) {
				script.InsertWithCursor ("Create event invocator", methodDeclaration, Script.InsertPosition.After);
			}
		}
示例#6
0
		public void Run (RefactoringContext context)
		{
			using (var script = context.StartScript ()) {
				var varDecl = GetVariableDeclarationStatement (context);
				if (varDecl != null) {
					var type = context.Resolve (varDecl.Variables.First ().Initializer).Type;
					script.Replace (varDecl.Type, context.CreateShortType (type));
				} else {
					var foreachStatement = GetForeachStatement (context);
					var type = context.Resolve (foreachStatement.VariableType).Type;
					script.Replace (foreachStatement.VariableType, context.CreateShortType (type));
				}
			}
		}
		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 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);
		}
        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);
        }
        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);
        }
        static void AddImplementation(RefactoringContext context, TypeDeclaration result, ICSharpCode.NRefactory.TypeSystem.IType guessedType)
        {
            foreach (var property in guessedType.GetProperties ()) {
                if (!property.IsAbstract)
                    continue;
                if (property.IsIndexer) {
                    var indexerDecl = new IndexerDeclaration() {
                        ReturnType = context.CreateShortType(property.ReturnType),
                        Modifiers = GetModifiers(property),
                        Name = property.Name
                    };
                    indexerDecl.Parameters.AddRange(ConvertParameters(context, property.Parameters));
                    if (property.CanGet)
                        indexerDecl.Getter = new Accessor();
                    if (property.CanSet)
                        indexerDecl.Setter = new Accessor();
                    result.AddChild(indexerDecl, Roles.TypeMemberRole);
                    continue;
                }
                var propDecl = new PropertyDeclaration() {
                    ReturnType = context.CreateShortType(property.ReturnType),
                    Modifiers = GetModifiers (property),
                    Name = property.Name
                };
                if (property.CanGet)
                    propDecl.Getter = new Accessor();
                if (property.CanSet)
                    propDecl.Setter = new Accessor();
                result.AddChild(propDecl, Roles.TypeMemberRole);
            }

            foreach (var method in guessedType.GetMethods ()) {
                if (!method.IsAbstract)
                    continue;
                var decl = new MethodDeclaration() {
                    ReturnType = context.CreateShortType(method.ReturnType),
                    Modifiers = GetModifiers (method),
                    Name = method.Name,
                    Body = new BlockStatement() {
                        new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
                    }
                };
                decl.Parameters.AddRange(ConvertParameters(context, method.Parameters));
                result.AddChild(decl, Roles.TypeMemberRole);
            }

            foreach (var evt in guessedType.GetEvents ()) {
                if (!evt.IsAbstract)
                    continue;
                var decl = new EventDeclaration() {
                    ReturnType = context.CreateShortType(evt.ReturnType),
                    Modifiers = GetModifiers (evt),
                    Name = evt.Name
                };
                result.AddChild(decl, Roles.TypeMemberRole);
            }
        }
示例#12
0
 public static AstType GuessAstType(RefactoringContext context, AstNode expr)
 {
     var type = GetValidTypes(context.Resolver, expr).ToArray();
     var typeInference = new TypeInference(context.Compilation);
     typeInference.Algorithm = TypeInferenceAlgorithm.Improved;
     var inferedType = typeInference.FindTypeInBounds(type, emptyTypes);
     if (inferedType.Kind == TypeKind.Unknown)
         return new PrimitiveType("object");
     return context.CreateShortType(inferedType);
 }
        public override IEnumerable<CodeAction> GetActions(RefactoringContext context)
        {
            var switchStatement = GetSwitchStatement(context);
            if (switchStatement == null) {
                yield break;
            }
            var result = context.Resolve(switchStatement.Expression);
            if (result.Type.Kind != TypeKind.Enum) {
                yield break;
            }
            yield return new CodeAction (context.TranslateString("Create switch labels"), script => {
                var type = result.Type;
                var newSwitch = (SwitchStatement)switchStatement.Clone();

                var target = new TypeReferenceExpression (context.CreateShortType(result.Type));
                foreach (var field in type.GetFields ()) {
                    if (field.IsSynthetic || !field.IsConst) {
                        continue;
                    }
                    newSwitch.SwitchSections.Add(new SwitchSection () {
                        CaseLabels = {
                            new CaseLabel (new MemberReferenceExpression (target.Clone(), field.Name))
                        },
                        Statements = {
                            new BreakStatement ()
                        }
                    });
                }

                newSwitch.SwitchSections.Add(new SwitchSection () {
                    CaseLabels = {
                        new CaseLabel ()
                    },
                    Statements = {
                        new ThrowStatement (new ObjectCreateExpression (context.CreateShortType("System", "ArgumentOutOfRangeException")))
                    }
                });

                script.Replace(switchStatement, newSwitch);
            }, switchStatement);
        }
示例#14
0
		EventDeclaration CreateChangedEventDeclaration (RefactoringContext context, PropertyDeclaration propertyDeclaration)
		{
			return new EventDeclaration {
				Modifiers = propertyDeclaration.HasModifier (Modifiers.Static) ? Modifiers.Public | Modifiers.Static : Modifiers.Public,
				ReturnType = context.CreateShortType("System", "EventHandler"),
				Variables = {
					new VariableInitializer {
						Name = propertyDeclaration.Name + "Changed"
					}
				}
			};
		}
示例#15
0
        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 usedVariables = VariableLookupVisitor.Analyze(context, expression);

                var inExtractedRegion = new VariableUsageAnalyzation (context, usedVariables);

                usedVariables.Sort ((l, r) => l.Region.Begin.CompareTo (r.Region.Begin));
                var target = new IdentifierExpression(methodName);
                var invocation = new InvocationExpression(target);
                foreach (var variable in usedVariables) {
                    Expression argumentExpression = new IdentifierExpression(variable.Name);

                    var mod = ParameterModifier.None;
                    if (inExtractedRegion.GetStatus (variable) == VariableState.Changed) {
                        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);
                }

                var task = script.InsertWithCursor(context.TranslateString("Extract method"), Script.InsertPosition.Before, method);

                Action<Task> replaceStatements = delegate {
                    script.Replace(expression, invocation);
                    script.Link(target, method.NameToken);
                };

                if (task.IsCompleted) {
                    replaceStatements (null);
                } else {
                    task.ContinueWith (replaceStatements, TaskScheduler.FromCurrentSynchronizationContext ());
                }
            }, expression);
        }
		static DelegateDeclaration CreateType(RefactoringContext context, SimpleType simpleType)
		{
			var result = new DelegateDeclaration() {
				Name = simpleType.Identifier,
				Modifiers = ((EntityDeclaration)simpleType.Parent).Modifiers,
				ReturnType = new PrimitiveType("void"),
				Parameters = {
					new ParameterDeclaration(new PrimitiveType("object"), "sender"),
					new ParameterDeclaration(context.CreateShortType("System", "EventArgs"), "e")
				}
			};
			return result;
		}
		static VariableInitializer GetVariableDeclarationStatement (RefactoringContext context, out AstType resolvedType, CancellationToken cancellationToken = default(CancellationToken))
		{
			var result = context.GetNode<VariableInitializer> ();
			if (result != null && !result.Initializer.IsNull && context.Location <= result.Initializer.StartLocation) {
				var type = context.Resolve(result).Type;
				if (type.Equals(SpecialType.NullType) || type.Equals(SpecialType.UnknownType)) {
					resolvedType = new PrimitiveType ("object");
				} else {
					resolvedType = context.CreateShortType (type);
				}
				return result;
			}
			resolvedType = null;
			return null;
		}
 static VariableDeclarationStatement GetVariableDeclarationStatement(RefactoringContext context, out AstType resolvedType, CancellationToken cancellationToken = default(CancellationToken))
 {
     var result = context.GetNode<VariableDeclarationStatement> ();
     if (result != null && result.Variables.Count == 1 && !result.Variables.First ().Initializer.IsNull && result.Variables.First ().NameToken.Contains (context.Location.Line, context.Location.Column)) {
         var type = context.Resolve(result.Variables.First ().Initializer).Type;
         if (type.Equals(SpecialType.NullType) || type.Equals(SpecialType.UnknownType)) {
             resolvedType = new PrimitiveType ("object");
         } else {
             resolvedType = context.CreateShortType (type);
         }
         return result;
     }
     resolvedType = null;
     return null;
 }
		static Statement BuildAccessorStatement (RefactoringContext context, PropertyDeclaration pdecl)
		{
			if (pdecl.Setter.IsNull && !pdecl.Getter.IsNull) {
				var field = RemoveBackingStore.ScanGetter (context, pdecl);
				if (field != null) 
					return new ExpressionStatement (new AssignmentExpression (new IdentifierExpression (field.Name), AssignmentOperatorType.Assign, new IdentifierExpression ("value")));
			}
			
			if (!pdecl.Setter.IsNull && pdecl.Getter.IsNull) {
				var field = RemoveBackingStore.ScanSetter (context, pdecl);
				if (field != null) 
					return new ReturnStatement (new IdentifierExpression (field.Name));
			}
			
			return new ThrowStatement (new ObjectCreateExpression (context.CreateShortType ("System", "NotImplementedException")));
		}
        public static AstType GuessAstType(RefactoringContext context, AstNode expr)
        {
            var type          = GetValidTypes(context.Resolver, expr).ToArray();
            var typeInference = new TypeInference(context.Compilation);

            typeInference.Algorithm = TypeInferenceAlgorithm.Improved;
            var inferedType = typeInference.FindTypeInBounds(type, emptyTypes);

            if (inferedType.Kind == TypeKind.ByReference)
            {
                inferedType = ((ByReferenceType)inferedType).ElementType;
            }
            if (inferedType.Kind == TypeKind.Unknown)
            {
                return(new PrimitiveType("object"));
            }
            return(context.CreateShortType(inferedType));
        }
        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)
		{
			var catchClause = context.GetNode<CatchClause>();
			if (catchClause == null)
				yield break;
			if (!catchClause.Type.IsNull)
				yield break;
			yield return new CodeAction(context.TranslateString("Add type specifier"), script => {
				var newIdentifier = Identifier.Create("e");
				var newType = context.CreateShortType("System", "Exception");
				script.Replace(catchClause, new CatchClause() {
					Type = newType,
					VariableNameToken = newIdentifier,
					Body = catchClause.Body.Clone() as BlockStatement
				});
				script.Link(newType);
				script.Link(newIdentifier);
			});
		}
        static VariableInitializer GetVariableDeclarationStatement(RefactoringContext context, out AstType resolvedType, CancellationToken cancellationToken = default(CancellationToken))
        {
            var result = context.GetNode <VariableInitializer> ();

            if (result != null && !result.Initializer.IsNull && context.Location <= result.Initializer.StartLocation)
            {
                var type = context.Resolve(result).Type;
                if (type.Equals(SpecialType.NullType) || type.Equals(SpecialType.UnknownType))
                {
                    resolvedType = new PrimitiveType("object");
                }
                else
                {
                    resolvedType = context.CreateShortType(type);
                }
                return(result);
            }
            resolvedType = null;
            return(null);
        }
 static IEnumerable <ParameterDeclaration> ConvertParameters(RefactoringContext context, IList <IParameter> parameters)
 {
     foreach (var param in parameters)
     {
         ParameterModifier mod = ParameterModifier.None;
         if (param.IsOut)
         {
             mod = ParameterModifier.Out;
         }
         else if (param.IsRef)
         {
             mod = ParameterModifier.Ref;
         }
         else if (param.IsParams)
         {
             mod = ParameterModifier.Params;
         }
         yield return(new ParameterDeclaration(context.CreateShortType(param.Type), param.Name, mod));
     }
 }
		public static ICSharpCode.NRefactory.CSharp.Attribute GenerateExportAttribute (RefactoringContext ctx, IMember member)
		{
			if (member == null)
				return null;
			var astType = ctx.CreateShortType ("MonoTouch.Foundation", "ExportAttribute");
			if (astType is SimpleType) {
				astType = new SimpleType ("Export");
			} else {
				astType = new MemberType (new MemberType (new SimpleType ("MonoTouch"), "Foundation"), "Export");
			}

			var attr = new ICSharpCode.NRefactory.CSharp.Attribute {
				Type = astType,
			};
			var exportAttribute = member.GetAttribute (new FullTypeName (new TopLevelTypeName ("MonoTouch.Foundation", "ExportAttribute"))); 
			if (exportAttribute == null || exportAttribute.PositionalArguments.Count == 0)
				return null;
			attr.Arguments.Add (new PrimitiveExpression (exportAttribute.PositionalArguments.First ().ConstantValue)); 
			return attr;

		}
        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, property);

            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),
                                                       context.CreateShortType("System", "EventArgs").Member("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));
        }
示例#27
0
        static Statement BuildAccessorStatement(RefactoringContext context, PropertyDeclaration pdecl)
        {
            if (pdecl.Setter.IsNull && !pdecl.Getter.IsNull)
            {
                var field = RemoveBackingStore.ScanGetter(context, pdecl);
                if (field != null)
                {
                    return(new ExpressionStatement(new AssignmentExpression(new IdentifierExpression(field.Name), AssignmentOperatorType.Assign, new IdentifierExpression("value"))));
                }
            }

            if (!pdecl.Setter.IsNull && pdecl.Getter.IsNull)
            {
                var field = RemoveBackingStore.ScanSetter(context, pdecl);
                if (field != null)
                {
                    return(new ReturnStatement(new IdentifierExpression(field.Name)));
                }
            }

            return(new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException"))));
        }
        protected override CodeAction GetAction(RefactoringContext context, MethodDeclaration node)
        {
            if (!node.PrivateImplementationType.IsNull)
            {
                return(null);
            }

            if (!node.NameToken.Contains(context.Location))
            {
                return(null);
            }

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

            if (memberResolveResult == null)
            {
                return(null);
            }
            var method = memberResolveResult.Member as IMethod;

            if (method == null || method.ImplementedInterfaceMembers.Count != 1 || method.DeclaringType.Kind == TypeKind.Interface)
            {
                return(null);
            }

            return(new CodeAction(context.TranslateString("Convert implict to explicit implementation"),
                                  script =>
            {
                var explicitImpl = (MethodDeclaration)node.Clone();
                // remove visibility modifier
                explicitImpl.Modifiers &= ~Modifiers.VisibilityMask;
                var implementedInterface = method.ImplementedInterfaceMembers [0].DeclaringType;
                explicitImpl.PrivateImplementationType = context.CreateShortType(implementedInterface);
                script.Replace(node, explicitImpl);
            },
                                  node.NameToken
                                  ));
        }
示例#29
0
		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;
				script.InsertWithCursor(context.TranslateString("Extract method"), method, Script.InsertPosition.Before);
				var target = new IdentifierExpression(methodName);
				script.Replace(expression, new InvocationExpression(target));
//				script.Link(target, method.NameToken);
			});
		}
示例#30
0
        protected override CodeAction GetAction(RefactoringContext context, VariableInitializer node)
        {
            var eventDecl = node.Parent as EventDeclaration;

            if (eventDecl == null)
            {
                return(null);
            }
            return(new CodeAction(context.TranslateString("Create custom event implementation"),
                                  script =>
            {
                var accessor = new Accessor
                {
                    Body = new BlockStatement
                    {
                        new ThrowStatement(
                            new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
                    }
                };
                var e = new CustomEventDeclaration
                {
                    Name = node.Name,
                    Modifiers = eventDecl.Modifiers,
                    ReturnType = eventDecl.ReturnType.Clone(),
                    AddAccessor = accessor,
                    RemoveAccessor = (Accessor)accessor.Clone(),
                };
                if (eventDecl.Variables.Count > 1)
                {
                    var newEventDecl = (EventDeclaration)eventDecl.Clone();
                    newEventDecl.Variables.Remove(
                        newEventDecl.Variables.FirstOrNullObject(v => v.Name == node.Name));
                    script.InsertBefore(eventDecl, newEventDecl);
                }
                script.Replace(eventDecl, e);
            }));
        }
        protected override CodeAction GetAction(RefactoringContext context, ParameterDeclaration parameter)
        {
            if (!parameter.NameToken.Contains(context.Location))
            {
                return(null);
            }
            BlockStatement bodyStatement;

            if (parameter.Parent is LambdaExpression)
            {
                bodyStatement = parameter.Parent.GetChildByRole(LambdaExpression.BodyRole) as BlockStatement;
            }
            else
            {
                bodyStatement = parameter.Parent.GetChildByRole(Roles.Body);
            }
            if (bodyStatement == null || bodyStatement.IsNull)
            {
                return(null);
            }
            var type = context.ResolveType(parameter.Type);

            if (type.IsReferenceType == false || HasNullCheck(parameter))
            {
                return(null);
            }

            return(new CodeAction(context.TranslateString("Add null check for parameter"), script => {
                var statement = new IfElseStatement()
                {
                    Condition = new BinaryOperatorExpression(new IdentifierExpression(parameter.Name), BinaryOperatorType.Equality, new NullReferenceExpression()),
                    TrueStatement = new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "ArgumentNullException"), new PrimitiveExpression(parameter.Name)))
                };
                script.AddTo(bodyStatement, statement);
            }, parameter.NameToken));
        }
		public void Run (RefactoringContext context)
		{
			IType type;
			var anonymousMethodExpression = GetAnonymousMethodExpression (context, out type);
			
			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 (")");
			
			using (var script = context.StartScript ()) {
				script.InsertText (context.GetOffset (anonymousMethodExpression.DelegateToken.EndLocation), sb.ToString ());
			}
		}
		static MethodDeclaration GetMethod (RefactoringContext context, LambdaResolveResult lambda, BlockStatement body,
			bool noReturnValue = false)
		{
			var method = new MethodDeclaration { Name = "Method" };

			if (noReturnValue) {
				method.ReturnType = new PrimitiveType ("void"); 
			} else {
				var type = lambda.GetInferredReturnType (lambda.Parameters.Select (p => p.Type).ToArray ());
				method.ReturnType = type.Name == "?" ? new PrimitiveType ("void") : context.CreateShortType (type);
			}

			foreach (var param in lambda.Parameters)
				method.Parameters.Add (new ParameterDeclaration (context.CreateShortType (param.Type), param.Name));

			method.Body = body;
			if (lambda.IsAsync)
				method.Modifiers |= Modifiers.Async;

			return method;
		}
		CodeAction CreateFromStatements(RefactoringContext context, List<Statement> 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("void"),
					Name = methodName,
					Body = new BlockStatement()
				};
				bool usesNonStaticMember = false;
				foreach (Statement node in statements) {
					usesNonStaticMember |= StaticVisitor.UsesNotStaticMember(context, node);
					method.Body.Add(node.Clone());
				}
				if (!usesNonStaticMember)
					method.Modifiers |= Modifiers.Static;
				
				var target = new IdentifierExpression(methodName);
				var invocation = new InvocationExpression(target);
				
				var usedVariables = VariableLookupVisitor.Analyze(context, statements);
				
				var extractedCodeAnalysis = new DefiniteAssignmentAnalysis(
					(Statement)statements [0].Parent,
					context.Resolver,
					context.CancellationToken);
				var lastStatement = statements [statements.Count - 1];
				extractedCodeAnalysis.SetAnalyzedRange(statements [0], lastStatement);
				var statusAfterMethod = new List<Tuple<IVariable, DefiniteAssignmentStatus>>();
				
				foreach (var variable in usedVariables) {
					extractedCodeAnalysis.Analyze(
						variable.Name,
						DefiniteAssignmentStatus.PotentiallyAssigned,
						context.CancellationToken);
					statusAfterMethod.Add(Tuple.Create(variable, extractedCodeAnalysis.GetStatusAfter(lastStatement)));
				}
				var stmt = statements [0].GetParent<BlockStatement>();
				while (stmt.GetParent<BlockStatement> () != null) {
					stmt = stmt.GetParent<BlockStatement>();
				}
				
				var wholeCodeAnalysis = new DefiniteAssignmentAnalysis(stmt, context.Resolver, context.CancellationToken);
				var statusBeforeMethod = new Dictionary<IVariable, DefiniteAssignmentStatus>();
				foreach (var variable in usedVariables) {
					wholeCodeAnalysis.Analyze(variable.Name, DefiniteAssignmentStatus.PotentiallyAssigned, context.CancellationToken);
					statusBeforeMethod [variable] = extractedCodeAnalysis.GetStatusBefore(statements [0]);
				}
				
				var afterCodeAnalysis = new DefiniteAssignmentAnalysis(stmt, context.Resolver, context.CancellationToken);
				var statusAtEnd = new Dictionary<IVariable, DefiniteAssignmentStatus>();
				afterCodeAnalysis.SetAnalyzedRange(lastStatement, stmt.Statements.Last(), false, true);
				
				foreach (var variable in usedVariables) {
					afterCodeAnalysis.Analyze(variable.Name, DefiniteAssignmentStatus.PotentiallyAssigned, context.CancellationToken);
					statusBeforeMethod [variable] = extractedCodeAnalysis.GetStatusBefore(statements [0]);
				}
				var beforeVisitor = new VariableLookupVisitor(context);
				beforeVisitor.SetAnalyzedRange(stmt, statements [0], true, false);
				stmt.AcceptVisitor(beforeVisitor);
				var afterVisitor = new VariableLookupVisitor(context);
				afterVisitor.SetAnalyzedRange(lastStatement, stmt, false, true);
				stmt.AcceptVisitor(afterVisitor);
				
				foreach (var status in statusAfterMethod) {
					if (!beforeVisitor.UsedVariables.Contains(status.Item1) && !afterVisitor.UsedVariables.Contains(status.Item1))
						continue;
					Expression argumentExpression = new IdentifierExpression(status.Item1.Name); 
					
					ParameterModifier mod;
					switch (status.Item2) {
						case DefiniteAssignmentStatus.AssignedAfterTrueExpression:
						case DefiniteAssignmentStatus.AssignedAfterFalseExpression:
						case DefiniteAssignmentStatus.PotentiallyAssigned:
							mod = ParameterModifier.Ref;
							argumentExpression = new DirectionExpression(FieldDirection.Ref, argumentExpression);
							break;
						case DefiniteAssignmentStatus.DefinitelyAssigned:
							if (statusBeforeMethod [status.Item1] != DefiniteAssignmentStatus.PotentiallyAssigned)
								goto case DefiniteAssignmentStatus.PotentiallyAssigned;
							mod = ParameterModifier.Out;
							argumentExpression = new DirectionExpression(FieldDirection.Out, argumentExpression);
							break;
							//						case DefiniteAssignmentStatus.Unassigned:
						default:
							mod = ParameterModifier.None;
							break;
					}
					method.Parameters.Add(
						new ParameterDeclaration(context.CreateShortType(status.Item1.Type), status.Item1.Name, mod));
					invocation.Arguments.Add(argumentExpression);
				}
				var task = script.InsertWithCursor(context.TranslateString("Extract method"), Script.InsertPosition.Before, method);
				task.ContinueWith (delegate {
					foreach (var node in statements.Skip (1)) {
						script.Remove(node);
					}
					script.Replace(statements [0], new ExpressionStatement(invocation));
					script.Link(target, method.NameToken);
				}, TaskScheduler.FromCurrentSynchronizationContext ());
			});
		}
		IEnumerable<CodeAction> GetActionsFromMemberReferenceExpression(RefactoringContext context, MemberReferenceExpression invocation)
		{
			if (!(context.Resolve(invocation).IsError)) 
					yield break;

			var methodName = invocation.MemberName;
			var guessedType = TypeGuessing.GuessType(context, invocation);
			if (guessedType.Kind != TypeKind.Delegate)
					yield break;
			var invocationMethod = guessedType.GetDelegateInvokeMethod();
			var state = context.GetResolverStateBefore(invocation);
			if (state.CurrentTypeDefinition == null)
				yield break;
			ResolveResult targetResolveResult = context.Resolve(invocation.Target);
			bool createInOtherType = !state.CurrentTypeDefinition.Equals(targetResolveResult.Type.GetDefinition());

			bool isStatic;
			if (createInOtherType) {
				if (targetResolveResult.Type.GetDefinition() == null || targetResolveResult.Type.GetDefinition().Region.IsEmpty)
					yield break;
				isStatic = targetResolveResult is TypeResolveResult;
				if (isStatic && targetResolveResult.Type.Kind == TypeKind.Interface || targetResolveResult.Type.Kind == TypeKind.Enum)
					yield break;
			} else {
				if (state.CurrentMember == null)
					yield break;
				isStatic = state.CurrentMember.IsStatic || state.CurrentTypeDefinition.IsStatic;
			}

//			var service = (NamingConventionService)context.GetService(typeof(NamingConventionService));
//			if (service != null && !service.IsValidName(methodName, AffectedEntity.Method, Modifiers.Private, isStatic)) { 
//				yield break;
//			}

			yield return CreateAction(
				context, 
				invocation,
				methodName, 
				context.CreateShortType(invocationMethod.ReturnType),
				invocationMethod.Parameters.Select(parameter => new ParameterDeclaration(context.CreateShortType(parameter.Type), parameter.Name) { 
					ParameterModifier = GetModifiers(parameter)
				}),
				createInOtherType,
				isStatic,
				targetResolveResult);
		}
示例#36
0
        public override IEnumerable <CodeAction> GetActions(RefactoringContext context)
        {
            if (!context.IsSomethingSelected)
            {
                yield break;
            }
            var selected = new List <AstNode>(context.GetSelectedNodes());

            if (selected.Count != 1 || !(selected [0] is Expression))
            {
                yield break;
            }

            var expr = selected [0] as Expression;

            if (expr is ArrayInitializerExpression)
            {
                var arr = (ArrayInitializerExpression)expr;
                if (arr.IsSingleElement)
                {
                    expr = arr.Elements.First();
                }
                else
                {
                    yield break;
                }
            }

            var visitor = new SearchNodeVisitior(expr);

            var node = context.GetNode <BlockStatement>();

            if (node != null)
            {
                node.AcceptVisitor(visitor);
            }

            yield return(new CodeAction(context.TranslateString("Declare local variable"), script => {
                var resolveResult = context.Resolve(expr);
                var guessedType = resolveResult.Type;
                if (resolveResult is MethodGroupResolveResult)
                {
                    guessedType = GetDelegateType(context, ((MethodGroupResolveResult)resolveResult).Methods.First(), expr);
                }
                var name = CreateMethodDeclarationAction.CreateBaseName(expr, guessedType);
                name = context.GetLocalNameProposal(name, expr.StartLocation);
                var type = context.UseExplicitTypes ? context.CreateShortType(guessedType) : new SimpleType("var");
                var varDecl = new VariableDeclarationStatement(type, name, expr.Clone());
                var replaceNode = visitor.Matches.First() as Expression;
                if (replaceNode.Parent is ExpressionStatement)
                {
                    script.Replace(replaceNode.Parent, varDecl);
                    script.Select(varDecl.Variables.First().NameToken);
                }
                else
                {
                    var containing = replaceNode.Parent;
                    while (!(containing.Parent is BlockStatement))
                    {
                        containing = containing.Parent;
                    }

                    script.InsertBefore(containing, varDecl);
                    var identifierExpression = new IdentifierExpression(name);
                    script.Replace(replaceNode, identifierExpression);
                    script.Link(varDecl.Variables.First().NameToken, identifierExpression);
                }
            }, expr));

            if (visitor.Matches.Count > 1)
            {
                yield return(new CodeAction(string.Format(context.TranslateString("Declare local variable (replace '{0}' occurrences)"), visitor.Matches.Count), script => {
                    var resolveResult = context.Resolve(expr);
                    var guessedType = resolveResult.Type;
                    if (resolveResult is MethodGroupResolveResult)
                    {
                        guessedType = GetDelegateType(context, ((MethodGroupResolveResult)resolveResult).Methods.First(), expr);
                    }
                    var linkedNodes = new List <AstNode>();
                    var name = CreateMethodDeclarationAction.CreateBaseName(expr, guessedType);
                    name = context.GetLocalNameProposal(name, expr.StartLocation);
                    var type = context.UseExplicitTypes ? context.CreateShortType(guessedType) : new SimpleType("var");
                    var varDecl = new VariableDeclarationStatement(type, name, expr.Clone());
                    linkedNodes.Add(varDecl.Variables.First().NameToken);
                    var first = visitor.Matches [0];
                    if (first.Parent is ExpressionStatement)
                    {
                        script.Replace(first.Parent, varDecl);
                    }
                    else
                    {
                        var containing = first.Parent;
                        while (!(containing.Parent is BlockStatement))
                        {
                            containing = containing.Parent;
                        }

                        script.InsertBefore(containing, varDecl);
                        var identifierExpression = new IdentifierExpression(name);
                        linkedNodes.Add(identifierExpression);
                        script.Replace(first, identifierExpression);
                    }
                    for (int i = 1; i < visitor.Matches.Count; i++)
                    {
                        var identifierExpression = new IdentifierExpression(name);
                        linkedNodes.Add(identifierExpression);
                        script.Replace(visitor.Matches [i], identifierExpression);
                    }
                    script.Link(linkedNodes.ToArray());
                }, expr));
            }
        }
		CodeAction CreateFromStatements(RefactoringContext context, List<Statement> 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("void"),
					Name = methodName,
					Body = new BlockStatement()
				};
				bool usesNonStaticMember = false;
				foreach (Statement node in statements) {
					usesNonStaticMember |= StaticVisitor.UsesNotStaticMember(context, node);
					method.Body.Add(node.Clone());
				}
				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;
				}

				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);
						} 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);
				}
				var task = script.InsertWithCursor(context.TranslateString("Extract method"), Script.InsertPosition.Before, method);
				Action<Task> replaceStatements = delegate {
					foreach (var node in statements.Skip (1)) {
						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));
					}
					AstNode invocationStatement;

					if (generatedReturnVariable != null) {
						invocationStatement = new VariableDeclarationStatement (new SimpleType ("var"), generatedReturnVariable.Name, invocation);
					} else {
						invocationStatement = new ExpressionStatement(invocation);
					}
					script.Replace(statements [0], invocationStatement);


					script.Link(target, method.NameToken);
				};

				if (task.IsCompleted) {
					replaceStatements (null);
				} else {
					task.ContinueWith (replaceStatements, TaskScheduler.FromCurrentSynchronizationContext ());
				}
			});
		}
        public override IEnumerable <CodeAction> GetActions(RefactoringContext context)
        {
            var pexpr = context.GetNode <PrimitiveExpression>();

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

            var visitor = new DeclareLocalVariableAction.SearchNodeVisitior(pexpr);

            if (pexpr.Parent is VariableInitializer)
            {
                var varDec = pexpr.Parent.Parent as VariableDeclarationStatement;
                if (varDec != null && (varDec.Modifiers & Modifiers.Const) != 0)
                {
                    yield break;
                }
                var fieldDecl = pexpr.Parent.Parent as FieldDeclaration;
                if (fieldDecl != null && (fieldDecl.Modifiers & Modifiers.Const) != 0)
                {
                    yield break;
                }
            }

            var node = context.GetNode <BlockStatement>();

            if (node != null)
            {
                node.AcceptVisitor(visitor);
            }

            var resolveResult = context.Resolve(pexpr);
            var statement     = context.GetNode <Statement>();

            if (statement != null)
            {
                yield return(new CodeAction(context.TranslateString("Create local constant"), script => {
                    string name = CreateMethodDeclarationAction.CreateBaseName(pexpr, resolveResult.Type);
                    var service = (NamingConventionService)context.GetService(typeof(NamingConventionService));
                    if (service != null)
                    {
                        name = service.CheckName(context, name, AffectedEntity.LocalConstant);
                    }

                    var initializer = new VariableInitializer(name, pexpr.Clone());
                    var decl = new VariableDeclarationStatement()
                    {
                        Type = context.CreateShortType(resolveResult.Type),
                        Modifiers = Modifiers.Const,
                        Variables = { initializer }
                    };

                    script.InsertBefore(statement, decl);
                    var variableUsage = new IdentifierExpression(name);
                    script.Replace(pexpr, variableUsage);
                    script.Link(initializer.NameToken, variableUsage);
                }, pexpr));
            }

            yield return(new CodeAction(context.TranslateString("Create constant field"), script => {
                string name = CreateMethodDeclarationAction.CreateBaseName(pexpr, resolveResult.Type);
                var service = (NamingConventionService)context.GetService(typeof(NamingConventionService));
                if (service != null)
                {
                    name = service.CheckName(context, name, AffectedEntity.ConstantField);
                }

                var initializer = new VariableInitializer(name, pexpr.Clone());

                var decl = new FieldDeclaration()
                {
                    ReturnType = context.CreateShortType(resolveResult.Type),
                    Modifiers = Modifiers.Const,
                    Variables = { initializer }
                };

                var variableUsage = new IdentifierExpression(name);
                script.Replace(pexpr, variableUsage);
                //				script.Link(initializer.NameToken, variableUsage);
                script.InsertWithCursor(context.TranslateString("Create constant"), Script.InsertPosition.Before, decl);
            }, pexpr));

            if (visitor.Matches.Count > 1)
            {
                yield return(new CodeAction(string.Format(context.TranslateString("Create local constant (replace '{0}' occurrences)"), visitor.Matches.Count), script => {
                    string name = CreateMethodDeclarationAction.CreateBaseName(pexpr, resolveResult.Type);
                    var service = (NamingConventionService)context.GetService(typeof(NamingConventionService));
                    if (service != null)
                    {
                        name = service.CheckName(context, name, AffectedEntity.LocalConstant);
                    }

                    var initializer = new VariableInitializer(name, pexpr.Clone());
                    var decl = new VariableDeclarationStatement()
                    {
                        Type = context.CreateShortType(resolveResult.Type),
                        Modifiers = Modifiers.Const,
                        Variables = { initializer }
                    };

                    script.InsertBefore(statement, decl);

                    var linkedNodes = new List <AstNode>();
                    linkedNodes.Add(initializer.NameToken);
                    for (int i = 0; i < visitor.Matches.Count; i++)
                    {
                        var identifierExpression = new IdentifierExpression(name);
                        linkedNodes.Add(identifierExpression);
                        script.Replace(visitor.Matches [i], identifierExpression);
                    }
                    script.Link(linkedNodes.ToArray());
                }, pexpr));

                yield return(new CodeAction(string.Format(context.TranslateString("Create constant field (replace '{0}' occurrences)"), visitor.Matches.Count), script => {
                    string name = CreateMethodDeclarationAction.CreateBaseName(pexpr, resolveResult.Type);
                    var service = (NamingConventionService)context.GetService(typeof(NamingConventionService));
                    if (service != null)
                    {
                        name = service.CheckName(context, name, AffectedEntity.ConstantField);
                    }

                    var initializer = new VariableInitializer(name, pexpr.Clone());

                    var decl = new FieldDeclaration()
                    {
                        ReturnType = context.CreateShortType(resolveResult.Type),
                        Modifiers = Modifiers.Const,
                        Variables = { initializer }
                    };

                    var linkedNodes = new List <AstNode>();
                    linkedNodes.Add(initializer.NameToken);
                    for (int i = 0; i < visitor.Matches.Count; i++)
                    {
                        var identifierExpression = new IdentifierExpression(name);
                        linkedNodes.Add(identifierExpression);
                        script.Replace(visitor.Matches [i], identifierExpression);
                    }
                    script.InsertWithCursor(context.TranslateString("Create constant"), Script.InsertPosition.Before, decl);
                }, pexpr));
            }
        }
        static void AddImplementation(RefactoringContext context, TypeDeclaration result, IType guessedType)
        {
            foreach (var property in guessedType.GetProperties())
            {
                if (!property.IsAbstract)
                {
                    continue;
                }
                if (property.IsIndexer)
                {
                    var indexerDecl = new IndexerDeclaration {
                        ReturnType = context.CreateShortType(property.ReturnType),
                        Modifiers  = GetModifiers(property),
                        Name       = property.Name
                    };
                    indexerDecl.Parameters.AddRange(ConvertParameters(context, property.Parameters));
                    if (property.CanGet)
                    {
                        indexerDecl.Getter = new Accessor();
                    }
                    if (property.CanSet)
                    {
                        indexerDecl.Setter = new Accessor();
                    }
                    result.AddChild(indexerDecl, Roles.TypeMemberRole);
                    continue;
                }
                var propDecl = new PropertyDeclaration {
                    ReturnType = context.CreateShortType(property.ReturnType),
                    Modifiers  = GetModifiers(property),
                    Name       = property.Name
                };
                if (property.CanGet)
                {
                    propDecl.Getter = new Accessor();
                }
                if (property.CanSet)
                {
                    propDecl.Setter = new Accessor();
                }
                result.AddChild(propDecl, Roles.TypeMemberRole);
            }

            foreach (var method in guessedType.GetMethods())
            {
                if (!method.IsAbstract)
                {
                    continue;
                }
                var decl = new MethodDeclaration {
                    ReturnType = context.CreateShortType(method.ReturnType),
                    Modifiers  = GetModifiers(method),
                    Name       = method.Name,
                    Body       = new BlockStatement {
                        new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
                    }
                };
                decl.Parameters.AddRange(ConvertParameters(context, method.Parameters));
                result.AddChild(decl, Roles.TypeMemberRole);
            }

            foreach (var evt in guessedType.GetEvents())
            {
                if (!evt.IsAbstract)
                {
                    continue;
                }
                var decl = new EventDeclaration {
                    ReturnType = context.CreateShortType(evt.ReturnType),
                    Modifiers  = GetModifiers(evt),
                    Variables  =
                    {
                        new VariableInitializer {
                            Name = evt.Name
                        }
                    }
                };
                decl.Variables.Add(new VariableInitializer(evt.Name));
                result.AddChild(decl, Roles.TypeMemberRole);
            }
        }
        public override IEnumerable <CodeAction> GetActions(RefactoringContext context)
        {
            //TODO: implement variable assignment & ctor param
            var varInit = context.GetNode <VariableInitializer>();

            if (varInit != null)
            {
                var selectedNode = varInit.GetNodeAt(context.Location);
                if (selectedNode != varInit.NameToken)
                {
                    yield break;
                }

                AstType type = varInit.GetPrevNode() as AstType;
                if (type == null)
                {
                    yield break;
                }
                if (varInit.Parent is FieldDeclaration)
                {
                    yield break;
                }
                if (CannotExtractField(context, varInit))
                {
                    yield break;
                }

                yield return(new CodeAction(context.TranslateString("Assign to new field"), s => {
                    var name = varInit.Name;

                    AstType extractedType;
                    if (type.IsVar())
                    {
                        IType resolvedType = context.Resolve(varInit.Initializer).Type;
                        extractedType = context.CreateShortType(resolvedType);
                    }
                    else
                    {
                        extractedType = (AstType)type.Clone();
                    }

                    AstNode entityDeclarationNode = varInit.Parent;
                    while (!(entityDeclarationNode is EntityDeclaration) || (entityDeclarationNode is Accessor))
                    {
                        entityDeclarationNode = entityDeclarationNode.Parent;
                    }
                    var entity = (EntityDeclaration)entityDeclarationNode;
                    bool isStatic = entity.HasModifier(Modifiers.Static);

                    FieldDeclaration field = new FieldDeclaration()
                    {
                        Modifiers = isStatic ? Modifiers.Static : Modifiers.None,
                        ReturnType = extractedType,
                        Variables = { new VariableInitializer(name) }
                    };
                    AstNode nodeToRemove = RemoveDeclaration(varInit) ? varInit.Parent : type;
                    s.Remove(nodeToRemove, true);
                    s.InsertWithCursor(context.TranslateString("Insert new field"), Script.InsertPosition.Before, field);
                    s.FormatText(varInit.Parent);
                }, selectedNode));
            }

            var idntf = context.GetNode <Identifier>();

            if (idntf == null)
            {
                yield break;
            }
            var paramDec = idntf.Parent as ParameterDeclaration;

            if (paramDec != null)
            {
                var ctor = paramDec.Parent as ConstructorDeclaration;
                if (ctor == null)
                {
                    yield break;
                }
                MemberReferenceExpression thisField = new MemberReferenceExpression(new ThisReferenceExpression(), idntf.Name, new AstType[] {});
                var assign             = new AssignmentExpression(thisField, AssignmentOperatorType.Assign, new IdentifierExpression(idntf.Name));
                var statement          = new ExpressionStatement(assign);
                var type               = (idntf.GetPrevNode() as AstType).Clone();
                FieldDeclaration field = new FieldDeclaration()
                {
                    ReturnType = type.Clone(),
                    Variables  = { new VariableInitializer(idntf.Name) }
                };
                yield return(new CodeAction(context.TranslateString("Assign to new field"), s => {
                    s.InsertWithCursor(context.TranslateString("Insert new field"), Script.InsertPosition.Before, field);
                    s.AddTo(ctor.Body, statement);
                }, paramDec.NameToken));
            }
        }
        public static IEnumerable <ParameterDeclaration> GenerateParameters(RefactoringContext context, IEnumerable <Expression> arguments)
        {
            var nameCounter = new Dictionary <string, int>();

            foreach (var argument in arguments)
            {
                var     direction = ParameterModifier.None;
                AstNode node;
                if (argument is DirectionExpression)
                {
                    var de = (DirectionExpression)argument;
                    direction = de.FieldDirection == FieldDirection.Out ? ParameterModifier.Out : ParameterModifier.Ref;
                    node      = de.Expression;
                }
                else
                {
                    node = argument;
                }

                var    resolveResult = context.Resolve(node);
                string name          = CreateBaseName(argument, resolveResult.Type);
                if (!nameCounter.ContainsKey(name))
                {
                    nameCounter [name] = 1;
                }
                else
                {
                    nameCounter [name]++;
                    name += nameCounter [name].ToString();
                }
                var type = resolveResult.Type.Kind == TypeKind.Unknown || resolveResult.Type.Kind == TypeKind.Null ? new PrimitiveType("object") : context.CreateShortType(resolveResult.Type);

                yield return(new ParameterDeclaration(type, name)
                {
                    ParameterModifier = direction
                });
            }
        }
        IEnumerable <CodeAction> GetActionsFromMemberReferenceExpression(RefactoringContext context, MemberReferenceExpression invocation)
        {
            if (!(context.Resolve(invocation).IsError))
            {
                yield break;
            }

            var methodName  = invocation.MemberName;
            var guessedType = TypeGuessing.GuessType(context, invocation);

            if (guessedType.Kind != TypeKind.Delegate)
            {
                yield break;
            }
            var invocationMethod = guessedType.GetDelegateInvokeMethod();
            var state            = context.GetResolverStateBefore(invocation);

            if (state.CurrentTypeDefinition == null)
            {
                yield break;
            }
            ResolveResult targetResolveResult = context.Resolve(invocation.Target);
            bool          createInOtherType   = !state.CurrentTypeDefinition.Equals(targetResolveResult.Type.GetDefinition());

            bool isStatic;

            if (createInOtherType)
            {
                if (targetResolveResult.Type.GetDefinition() == null || targetResolveResult.Type.GetDefinition().Region.IsEmpty)
                {
                    yield break;
                }
                isStatic = targetResolveResult is TypeResolveResult;
                if (isStatic && targetResolveResult.Type.Kind == TypeKind.Interface || targetResolveResult.Type.Kind == TypeKind.Enum)
                {
                    yield break;
                }
            }
            else
            {
                if (state.CurrentMember == null)
                {
                    yield break;
                }
                isStatic = state.CurrentMember.IsStatic || state.CurrentTypeDefinition.IsStatic;
            }

//			var service = (NamingConventionService)context.GetService(typeof(NamingConventionService));
//			if (service != null && !service.IsValidName(methodName, AffectedEntity.Method, Modifiers.Private, isStatic)) {
//				yield break;
//			}

            yield return(CreateAction(
                             context,
                             invocation,
                             methodName,
                             context.CreateShortType(invocationMethod.ReturnType),
                             invocationMethod.Parameters.Select(parameter => new ParameterDeclaration(context.CreateShortType(parameter.Type), parameter.Name)
            {
                ParameterModifier = GetModifiers(parameter)
            }),
                             createInOtherType,
                             isStatic,
                             targetResolveResult));
        }
示例#43
0
        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 usedVariables = VariableLookupVisitor.Analyze(context, expression);

                var inExtractedRegion = new VariableUsageAnalyzation(context, usedVariables);

                usedVariables.Sort((l, r) => l.Region.Begin.CompareTo(r.Region.Begin));
                var target = new IdentifierExpression(methodName);
                var invocation = new InvocationExpression(target);
                foreach (var variable in usedVariables)
                {
                    Expression argumentExpression = new IdentifierExpression(variable.Name);

                    var mod = ParameterModifier.None;
                    if (inExtractedRegion.GetStatus(variable) == VariableState.Changed)
                    {
                        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);
                }

                var task = script.InsertWithCursor(context.TranslateString("Extract method"), Script.InsertPosition.Before, method);

                Action <Task> replaceStatements = delegate {
                    script.Replace(expression, invocation);
                    script.Link(target, method.NameToken);
                };

                if (task.IsCompleted)
                {
                    replaceStatements(null);
                }
                else
                {
                    task.ContinueWith(replaceStatements, TaskScheduler.FromCurrentSynchronizationContext());
                }
            }, expression));
        }
示例#44
0
        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("void"),
                    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 == "void" &&
                                                  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 indexer = context.GetNode <IndexerExpression>();

            if (indexer == null)
            {
                yield break;
            }
            if (!(context.Resolve(indexer).IsError))
            {
                yield break;
            }

            var state = context.GetResolverStateBefore(indexer);

            if (state.CurrentTypeDefinition == null)
            {
                yield break;
            }
            var guessedType = TypeGuessing.GuessAstType(context, indexer);

            bool          createInOtherType   = false;
            ResolveResult targetResolveResult = null;

            targetResolveResult = context.Resolve(indexer.Target);
            createInOtherType   = !state.CurrentTypeDefinition.Equals(targetResolveResult.Type.GetDefinition());

            bool isStatic;

            if (createInOtherType)
            {
                if (targetResolveResult.Type.GetDefinition() == null || targetResolveResult.Type.GetDefinition().Region.IsEmpty)
                {
                    yield break;
                }
                isStatic = targetResolveResult is TypeResolveResult;
                if (isStatic && targetResolveResult.Type.Kind == TypeKind.Interface || targetResolveResult.Type.Kind == TypeKind.Enum)
                {
                    yield break;
                }
            }
            else
            {
                isStatic = indexer.Target is IdentifierExpression && state.CurrentMember.IsStatic;
            }

            yield return(new CodeAction(context.TranslateString("Create indexer"), script => {
                var decl = new IndexerDeclaration()
                {
                    ReturnType = guessedType,
                    Getter = new Accessor()
                    {
                        Body = new BlockStatement()
                        {
                            new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
                        }
                    },
                    Setter = new Accessor()
                    {
                        Body = new BlockStatement()
                        {
                            new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
                        }
                    },
                };
                decl.Parameters.AddRange(CreateMethodDeclarationAction.GenerateParameters(context, indexer.Arguments));
                if (isStatic)
                {
                    decl.Modifiers |= Modifiers.Static;
                }

                if (createInOtherType)
                {
                    if (targetResolveResult.Type.Kind == TypeKind.Interface)
                    {
                        decl.Getter.Body = null;
                        decl.Setter.Body = null;
                        decl.Modifiers = Modifiers.None;
                    }
                    else
                    {
                        decl.Modifiers |= Modifiers.Public;
                    }

                    script.InsertWithCursor(context.TranslateString("Create indexer"), targetResolveResult.Type.GetDefinition(), (s, c) => decl);
                    return;
                }

                script.InsertWithCursor(context.TranslateString("Create indexer"), Script.InsertPosition.Before, decl);
            }, indexer)
            {
                Severity = ICSharpCode.NRefactory.Refactoring.Severity.Error
            });
        }
        CodeAction CreateFromStatements(RefactoringContext context, List <Statement> 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("void"),
                    Name = methodName,
                    Body = new BlockStatement()
                };
                bool usesNonStaticMember = false;
                foreach (Statement node in statements)
                {
                    usesNonStaticMember |= StaticVisitor.UsesNotStaticMember(context, node);
                    method.Body.Add(node.Clone());
                }
                if (!usesNonStaticMember)
                {
                    method.Modifiers |= Modifiers.Static;
                }

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

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

                var extractedCodeAnalysis = new DefiniteAssignmentAnalysis((Statement)statements [0].Parent, context.Resolver, context.CancellationToken);
                var lastStatement = statements [statements.Count - 1];
                extractedCodeAnalysis.SetAnalyzedRange(statements [0], lastStatement);
                var statusAfterMethod = new List <Tuple <IVariable, DefiniteAssignmentStatus> >();

                foreach (var variable in usedVariables)
                {
                    extractedCodeAnalysis.Analyze(variable.Name, DefiniteAssignmentStatus.PotentiallyAssigned, context.CancellationToken);
                    statusAfterMethod.Add(Tuple.Create(variable, extractedCodeAnalysis.GetStatusAfter(lastStatement)));
                }
                var stmt = statements [0].GetParent <BlockStatement>();
                while (stmt.GetParent <BlockStatement> () != null)
                {
                    stmt = stmt.GetParent <BlockStatement>();
                }

                var wholeCodeAnalysis = new DefiniteAssignmentAnalysis(stmt, context.Resolver, context.CancellationToken);
                var statusBeforeMethod = new Dictionary <IVariable, DefiniteAssignmentStatus>();
                foreach (var variable in usedVariables)
                {
                    wholeCodeAnalysis.Analyze(variable.Name, DefiniteAssignmentStatus.PotentiallyAssigned, context.CancellationToken);
                    statusBeforeMethod [variable] = extractedCodeAnalysis.GetStatusBefore(statements [0]);
                }

                var afterCodeAnalysis = new DefiniteAssignmentAnalysis(stmt, context.Resolver, context.CancellationToken);
                var statusAtEnd = new Dictionary <IVariable, DefiniteAssignmentStatus>();
                afterCodeAnalysis.SetAnalyzedRange(lastStatement, stmt.Statements.Last(), false, true);

                foreach (var variable in usedVariables)
                {
                    afterCodeAnalysis.Analyze(variable.Name, DefiniteAssignmentStatus.PotentiallyAssigned, context.CancellationToken);
                    statusBeforeMethod [variable] = extractedCodeAnalysis.GetStatusBefore(statements [0]);
                }
                var beforeVisitor = new VariableLookupVisitor(context);
                beforeVisitor.SetAnalyzedRange(stmt, statements [0], true, false);
                stmt.AcceptVisitor(beforeVisitor);
                var afterVisitor = new VariableLookupVisitor(context);
                afterVisitor.SetAnalyzedRange(lastStatement, stmt, false, true);
                stmt.AcceptVisitor(afterVisitor);

                foreach (var status in statusAfterMethod)
                {
                    if (!beforeVisitor.UsedVariables.Contains(status.Item1) && !afterVisitor.UsedVariables.Contains(status.Item1))
                    {
                        continue;
                    }
                    Expression argumentExpression = new IdentifierExpression(status.Item1.Name);

                    ParameterModifier mod;
                    switch (status.Item2)
                    {
                    case DefiniteAssignmentStatus.AssignedAfterTrueExpression:
                    case DefiniteAssignmentStatus.AssignedAfterFalseExpression:
                    case DefiniteAssignmentStatus.PotentiallyAssigned:
                        mod = ParameterModifier.Ref;
                        argumentExpression = new DirectionExpression(FieldDirection.Ref, argumentExpression);
                        break;

                    case DefiniteAssignmentStatus.DefinitelyAssigned:
                        if (statusBeforeMethod [status.Item1] != DefiniteAssignmentStatus.PotentiallyAssigned)
                        {
                            goto case DefiniteAssignmentStatus.PotentiallyAssigned;
                        }
                        mod = ParameterModifier.Out;
                        argumentExpression = new DirectionExpression(FieldDirection.Out, argumentExpression);
                        break;

//						case DefiniteAssignmentStatus.Unassigned:
                    default:
                        mod = ParameterModifier.None;
                        break;
                    }
                    method.Parameters.Add(new ParameterDeclaration(context.CreateShortType(status.Item1.Type), status.Item1.Name, mod));
                    invocation.Arguments.Add(argumentExpression);
                }

                foreach (var node in statements.Skip(1))
                {
                    script.Remove(node);
                }
                script.Replace(statements [0], new ExpressionStatement(invocation));
                script.InsertWithCursor(context.TranslateString("Extract method"), method, Script.InsertPosition.Before);
                //script.Link(target, method.NameToken);
            }));
        }
示例#47
0
		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("void"),
					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 == "void" &&
				                                  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);
		}
        CodeAction CreateFromStatements(RefactoringContext context, List <Statement> 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("void"),
                    Name = methodName,
                    Body = new BlockStatement()
                };
                bool usesNonStaticMember = false;
                foreach (Statement node in statements)
                {
                    usesNonStaticMember |= StaticVisitor.UsesNotStaticMember(context, node);
                    method.Body.Add(node.Clone());
                }
                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;
                }

                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);
                        }
                        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);
                }
                var task = script.InsertWithCursor(context.TranslateString("Extract method"), Script.InsertPosition.Before, method);
                Action <Task> replaceStatements = delegate {
                    foreach (var node in statements.Skip(1))
                    {
                        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));
                    }
                    AstNode invocationStatement;

                    if (generatedReturnVariable != null)
                    {
                        invocationStatement = new VariableDeclarationStatement(new SimpleType("var"), generatedReturnVariable.Name, invocation);
                    }
                    else
                    {
                        invocationStatement = new ExpressionStatement(invocation);
                    }
                    script.Replace(statements [0], invocationStatement);


                    script.Link(target, method.NameToken);
                };

                if (task.IsCompleted)
                {
                    replaceStatements(null);
                }
                else
                {
                    task.ContinueWith(replaceStatements, TaskScheduler.FromCurrentSynchronizationContext());
                }
            }));
        }
		public static IEnumerable<ParameterDeclaration> GenerateParameters(RefactoringContext context, IEnumerable<Expression> arguments)
		{
			var nameCounter = new Dictionary<string, int>();
			foreach (var argument in arguments) {
				var direction = ParameterModifier.None;
				AstNode node;
				if (argument is DirectionExpression) {
					var de = (DirectionExpression)argument;
					direction = de.FieldDirection == FieldDirection.Out ? ParameterModifier.Out : ParameterModifier.Ref;
					node = de.Expression;
				} else {
					node = argument;
				}

				var resolveResult = context.Resolve(node);
				string name = CreateBaseName(argument, resolveResult.Type);
				if (!nameCounter.ContainsKey(name)) {
					nameCounter [name] = 1;
				} else {
					nameCounter [name]++;
					name += nameCounter [name].ToString();
				}
				var type = resolveResult.Type.Kind == TypeKind.Unknown || resolveResult.Type.Kind == TypeKind.Null ? new PrimitiveType("object") : context.CreateShortType(resolveResult.Type);

				yield return new ParameterDeclaration(type, name) { ParameterModifier = direction};
			}
		}
示例#50
0
        public static MethodDeclaration CreateEventInvocator(RefactoringContext context, TypeDeclaration declaringType, EventDeclaration eventDeclaration, VariableInitializer initializer, IMethod invokeMethod, bool useExplictType)
        {
            bool hasSenderParam           = false;
            IEnumerable <IParameter> pars = invokeMethod.Parameters;

            if (invokeMethod.Parameters.Any())
            {
                var first = invokeMethod.Parameters [0];
                if (first.Name == "sender" /*&& first.Type == "System.Object"*/)
                {
                    hasSenderParam = true;
                    pars           = invokeMethod.Parameters.Skip(1);
                }
            }
            const string handlerName = "handler";

            var arguments = new List <Expression>();

            if (hasSenderParam)
            {
                arguments.Add(eventDeclaration.HasModifier(Modifiers.Static) ? (Expression) new PrimitiveExpression(null) : new ThisReferenceExpression());
            }
            bool useThisMemberReference = false;

            foreach (var par in pars)
            {
                arguments.Add(new IdentifierExpression(par.Name));
                useThisMemberReference |= par.Name == initializer.Name;
            }
            var proposedHandlerName = GetNameProposal(initializer);
            var modifiers           = eventDeclaration.HasModifier(Modifiers.Static) ? Modifiers.Static : Modifiers.Protected | Modifiers.Virt;

            if (declaringType.HasModifier(Modifiers.Final))
            {
                modifiers = Modifiers.None;
            }
            var methodDeclaration = new MethodDeclaration {
                Name       = proposedHandlerName,
                ReturnType = new PrimitiveType("sub"),
                Modifiers  = modifiers,
                Body       = new BlockStatement {
                    new VariableDeclarationStatement(
                        useExplictType ? eventDeclaration.ReturnType.Clone() : new PrimitiveType("var"), handlerName,
                        useThisMemberReference ?
                        (Expression) new MemberReferenceExpression(new ThisReferenceExpression(), initializer.Name)
                                                : new IdentifierExpression(initializer.Name)
                        ),
                    new IfElseStatement {
                        Condition     = new BinaryOperatorExpression(new IdentifierExpression(handlerName), BinaryOperatorType.InEquality, new PrimitiveExpression(null)),
                        TrueStatement = new InvocationExpression(new IdentifierExpression(handlerName), arguments)
                    }
                }
            };

            foreach (var par in pars)
            {
                var typeName = context.CreateShortType(par.Type);
                var decl     = new ParameterDeclaration(typeName, par.Name);
                methodDeclaration.Parameters.Add(decl);
            }
            return(methodDeclaration);
        }
		static AstNode GenerateMethod(RefactoringContext context, IMethod method, bool explicitImplementation)
		{
			var result = new MethodDeclaration() {
				Name = method.Name,
				ReturnType = context.CreateShortType (method.ReturnType),
				Body = new BlockStatement() {
					new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
				}
			};

			if (!explicitImplementation) {
				result.Modifiers = Modifiers.Public;
			} else {
				result.PrivateImplementationType = context.CreateShortType(method.DeclaringType);
			}

			foreach (var typeParam in method.TypeParameters) {
				result.TypeParameters.Add(new TypeParameterDeclaration(typeParam.Name));
			}

			foreach (var p in method.Parameters) {
				ParameterModifier modifier;
				if (p.IsOut) {
					modifier = ParameterModifier.Out;
				} else if (p.IsRef) {
					modifier = ParameterModifier.Ref;
				} else if (p.IsParams) {
					modifier = ParameterModifier.Params;
				} else {
					modifier = ParameterModifier.None;
				}
				result.Parameters.Add(new ParameterDeclaration(context.CreateShortType(p.Type), p.Name, modifier));
			}

			return result;
		}
        public override IEnumerable <CodeAction> GetActions(RefactoringContext context)
        {
            var switchStatement = context.GetNode <SwitchStatement> ();

            if (switchStatement == null || !switchStatement.SwitchToken.Contains(context.Location))
            {
                yield break;
            }
            var result = context.Resolve(switchStatement.Expression);

            if (result.Type.Kind != TypeKind.Enum)
            {
                yield break;
            }

            if (switchStatement.SwitchSections.Count == 0)
            {
                yield return(new CodeAction(context.TranslateString("Create switch labels"), script => {
                    var type = result.Type;
                    var newSwitch = (SwitchStatement)switchStatement.Clone();

                    var target = context.CreateShortType(result.Type);
                    foreach (var field in type.GetFields())
                    {
                        if (field.IsSynthetic || !field.IsConst)
                        {
                            continue;
                        }
                        newSwitch.SwitchSections.Add(new SwitchSection()
                        {
                            CaseLabels =
                            {
                                new CaseLabel(target.Clone().Member(field.Name))
                            },
                            Statements =
                            {
                                new BreakStatement()
                            }
                        });
                    }

                    newSwitch.SwitchSections.Add(new SwitchSection()
                    {
                        CaseLabels =
                        {
                            new CaseLabel()
                        },
                        Statements =
                        {
                            new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "ArgumentOutOfRangeException")))
                        }
                    });

                    script.Replace(switchStatement, newSwitch);
                }, switchStatement));
            }
            else
            {
                var missingFields = new List <IField>();
                foreach (var field in result.Type.GetFields())
                {
                    if (field.IsSynthetic || !field.IsConst)
                    {
                        continue;
                    }
                    if (!IsHandled(context, switchStatement, field))
                    {
                        missingFields.Add(field);
                    }
                }
                if (missingFields.Count == 0)
                {
                    yield break;
                }
                yield return(new CodeAction(context.TranslateString("Create missing switch labels"), script => {
                    var type = result.Type;
                    //var newSwitch = (SwitchStatement)switchStatement.Clone();
                    var insertNode = (AstNode)switchStatement.SwitchSections.LastOrDefault(s => !s.CaseLabels.Any(label => label.Expression.IsNull)) ?? switchStatement.LBraceToken;

                    var target = context.CreateShortType(result.Type);
                    foreach (var field in missingFields)
                    {
                        script.InsertAfter(insertNode, new SwitchSection()
                        {
                            CaseLabels =
                            {
                                new CaseLabel(target.Clone().Member(field.Name))
                            },
                            Statements =
                            {
                                new BreakStatement()
                            }
                        });
                    }
                }, switchStatement));
            }
        }