public static void MoveToMethodWithFieldIntroduction([NotNull] IClassDeclaration classDeclaration, [NotNull] IMethodDeclaration methodDeclaration, [NotNull] ICSharpExpression expression, string fieldName = null) { classDeclaration.GetPsiServices().Locks.AssertReadAccessAllowed(); var result = GetDeclaredElementFromParentDeclaration(expression); var factory = CSharpElementFactory.GetInstance(classDeclaration); var type = expression.Type(new ResolveContext(classDeclaration.GetPsiModule())); if (type.IsUnknown) { type = TypeFactory.CreateTypeByCLRName("System.Object", classDeclaration.GetPsiModule()); } var isVoid = type.IsVoid(); if (!isVoid) { var baseName = fieldName ?? CreateBaseName(expression, result); var name = NamingUtil.GetUniqueName(expression, baseName, NamedElementKinds.PrivateInstanceFields, baseName == null ? collection => { collection.Add(expression.Type(), new EntryOptions()); } : (Action <INamesCollection>)null, de => !de.Equals(result)); var field = factory.CreateFieldDeclaration(type, name); field.SetAccessRights(AccessRights.PRIVATE); classDeclaration.AddClassMemberDeclaration(field); var initialization = factory.CreateStatement("$0 = $1;", name, expression.CopyWithResolve()); var body = methodDeclaration.EnsureStatementMemberBody(); body.AddStatementAfter(initialization, null); RenameOldUsages(expression, result, name, factory); } else { var initialization = factory.CreateStatement("$0;", expression.CopyWithResolve()); var body = methodDeclaration.EnsureStatementMemberBody(); body.AddStatementAfter(initialization, null); ExpressionStatementNavigator.GetByExpression(expression).NotNull("statement != null").RemoveOrReplaceByEmptyStatement(); } }
protected override Action <ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress) { var factory = CSharpElementFactory.GetInstance(myInvocationExpression); // try find declaration where string to id conversation is done. If we don't find it, create in top-level class var idDeclaration = TryFindDeclaration(myInvocationExpression, myGraphicsPropertyName, myTypeName, myMapFunction, out var name); if (idDeclaration == null) { var psiModule = myInvocationExpression.PsiModule; var fieldInitializerValue = factory.CreateExpression("$0.$1($2)", TypeFactory.CreateTypeByCLRName(myTypeName, myInvocationExpression.PsiModule), myMapFunction, myArgumentExpression.Copy()); name = NamingUtil.GetUniqueName(myInvocationExpression, myFieldName, NamedElementKinds.PrivateStaticReadonly).NotNull(); var newDeclaration = factory.CreateFieldDeclaration(psiModule.GetPredefinedType().Int, name); idDeclaration = newDeclaration.DeclaredElement; if (idDeclaration == null) { return(null); } newDeclaration.SetReadonly(true); newDeclaration.SetStatic(true); newDeclaration.SetAccessRights(AccessRights.PRIVATE); newDeclaration.SetInitial(factory.CreateExpressionInitializer(fieldInitializerValue)); // TODO: [C#8] default interface implementations // interface is not good place to add field declaration var classDeclaration = GetTopLevelClassLikeDeclaration(myInvocationExpression); classDeclaration.AddClassMemberDeclaration(newDeclaration); } // replace argument var referenceExpression = factory.CreateReferenceExpression("$0", idDeclaration); var argument = factory.CreateArgument(ParameterKind.VALUE, myArgument.NameIdentifier?.Name, referenceExpression); myArgument.ReplaceBy(argument); return(null); }
protected override Action <ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress) { var anchor = myLoopStatement as ICSharpStatement; var declaredElement = MonoBehaviourMoveUtil.GetDeclaredElementFromParentDeclaration(myToMove); var baseName = myVariableName ?? MonoBehaviourMoveUtil.CreateBaseName(myToMove, declaredElement); var name = NamingUtil.GetUniqueName(myToMove, baseName, NamedElementKinds.Locals, collection => collection.Add(myToMove.Type(), new EntryOptions()), de => !de.Equals(declaredElement)); var factory = CSharpElementFactory.GetInstance(myToMove); var originMyToMove = myToMove.CopyWithResolve(); MonoBehaviourMoveUtil.RenameOldUsages(myToMove, declaredElement, name, factory); ICSharpStatement declaration = factory.CreateStatement("var $0 = $1;", name, originMyToMove); StatementUtil.InsertStatement(declaration, ref anchor, true); return(null); }