// Check that invocation immediately under declaration statement as initializer (Parenthesized Expression is allowed) private bool IsInvocationInitializer() { var expression = myInvocationExpression.GetContainingParenthesizedExpression(); var currentInitializer = ExpressionInitializerNavigator.GetByValue(expression); var selectedDeclarator = LocalVariableDeclarationNavigator.GetByInitial(currentInitializer); var multiplyVariableDeclaration = MultipleLocalVariableDeclarationNavigator.GetByDeclarator(selectedDeclarator); return(DeclarationStatementNavigator.GetByDeclaration(multiplyVariableDeclaration) != null); }
/// <summary> /// If current expression is used as initializer for local variable, declared element for this variable will be returned /// </summary> public static IDeclaredElement GetDeclaredElementFromParentDeclaration([NotNull] ICSharpExpression expression) { expression.GetPsiServices().Locks.AssertReadAccessAllowed(); var localVariableDeclaration = LocalVariableDeclarationNavigator.GetByInitial( ExpressionInitializerNavigator.GetByValue(expression.GetContainingParenthesizedExpression())); return(localVariableDeclaration?.DeclaredElement); }
public static void RenameOldUsages([NotNull] ICSharpExpression originExpression, [CanBeNull] IDeclaredElement localVariableDeclaredElement, [NotNull] string newName, [NotNull] CSharpElementFactory factory) { originExpression.GetPsiServices().Locks.AssertReadAccessAllowed(); var statement = ExpressionStatementNavigator.GetByExpression(originExpression); if (statement != null) { statement.RemoveOrReplaceByEmptyStatement(); } else { if (localVariableDeclaredElement == null) { originExpression.ReplaceBy(factory.CreateReferenceExpression(newName)); } else if (!newName.Equals(localVariableDeclaredElement.ShortName)) { var provider = DefaultUsagesProvider.Instance; var usages = provider.GetUsages(localVariableDeclaredElement, originExpression.GetContainingNode <IMethodDeclaration>().NotNull("scope != null")); originExpression.GetContainingStatement().NotNull("expression.GetContainingStatement() != null") .RemoveOrReplaceByEmptyStatement(); foreach (var usage in usages) { if (usage.IsValid() && usage is IReferenceExpression node) { node.ReplaceBy(factory.CreateReferenceExpression(newName)); } } } else { DeclarationStatementNavigator.GetByVariableDeclaration( LocalVariableDeclarationNavigator.GetByInitial( ExpressionInitializerNavigator.GetByValue( originExpression.GetContainingParenthesizedExpression()))) ?.RemoveOrReplaceByEmptyStatement(); } } }
protected override IExpressionInitializer Navigate(ICSharpExpression expression) { return(ExpressionInitializerNavigator.GetByValue(expression)); }
protected override Action <ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress) { var oldMethod = myExpression.Reference.Resolve().DeclaredElement as IMethod; if (oldMethod == null) { return(null); } var factory = CSharpElementFactory.GetInstance(myInvocationExpression); var builder = FactoryArgumentsBuilder.Create(); if (myExpression.QualifierExpression != null) { builder.Argument(myExpression.QualifierExpression); builder.Append("."); } builder.Append(myNewMethod.ShortName); builder.Append("("); var returnType = oldMethod.ReturnType; var oldArguments = myInvocationExpression.Arguments; var firstPositionalArgIdx = GetPositionalArgumentIndex(oldArguments); var curArgIdx = 0; var newParameters = myNewMethod.Parameters; var argumentIndex = 0; // insert new argument to correct position. If we should use positional argument, we will check it and use. for (int i = 0; i < newParameters.Count; i++) { var parameter = newParameters[i]; if (parameter.Type.Equals(returnType)) { var referenceExpression = factory.CreateReferenceExpression(GetUniqueName(myInvocationExpression, ResultParamName)); IArgument argument = curArgIdx > firstPositionalArgIdx ? factory.CreateArgument(ParameterKind.VALUE, ResultParamName, referenceExpression) : factory.CreateArgument(ParameterKind.VALUE, referenceExpression); builder.Argument(argument); argumentIndex = i; } else { builder.Argument(oldArguments[curArgIdx]); curArgIdx++; } if (i + 1 != newParameters.Count) { builder.Append(","); } } builder.Append(")"); var newInvocation = factory.CreateExpression(builder.ToString(), builder.ToArguments()); var newDeclaration = (IDeclarationStatement)factory.CreateStatement("var $0 = $1;", GetUniqueName(myInvocationExpression, "size"), newInvocation); var oldStatement = myInvocationExpression.GetContainingStatement().NotNull("oldStatement != null"); IDeclarationStatement result; if (oldStatement is IExpressionStatement) { result = oldStatement.ReplaceBy(newDeclaration); } else { var declaration = (oldStatement as IDeclarationStatement).NotNull(nameof(oldStatement) + " is not IDeclarationStatement"); // if only one declaration just replace it if (declaration.Declaration.Declarators.Count == 1) { result = oldStatement.ReplaceBy(newDeclaration); } else { // There are several declaration, exclude our and transform it. var expression = myInvocationExpression.GetContainingParenthesizedExpression(); var currentInitializer = ExpressionInitializerNavigator.GetByValue(expression); var selectedDeclarator = LocalVariableDeclarationNavigator.GetByInitial(currentInitializer).NotNull("selectedDeclarator != null"); MultipleDeclarationUtil.SplitDeclarationBefore(selectedDeclarator); MultipleDeclarationUtil.SplitDeclarationAfter(selectedDeclarator); result = declaration.ReplaceBy(newDeclaration); } } var actualArgument = result.Descendants <IArgumentList>().First().Arguments[argumentIndex]; if (!actualArgument.IsValid()) { return(null); } // allow user to decide which array he will use var hotspotsRegistry = new HotspotsRegistry(newInvocation.GetPsiServices()); hotspotsRegistry.Register(new ITreeNode[] { actualArgument }); return(BulbActionUtils.ExecuteHotspotSession(hotspotsRegistry, actualArgument.GetDocumentRange())); }
protected override void Analyze(IInvocationExpression expression, ElementProblemAnalyzerData data, IHighlightingConsumer consumer) { var reference = (expression.InvokedExpression as IReferenceExpression)?.Reference; if (reference == null) { return; } var info = reference.Resolve(); if (info.ResolveErrorType != ResolveErrorType.OK) { return; } var method = info.DeclaredElement as IMethod; if (method == null) { return; } if (!method.ShortName.Equals(ourKnownMethod)) { return; } if (method.GetContainingType()?.GetClrName().Equals(KnownTypes.Object) != true) { return; } var parameters = method.Parameters; if (parameters.Count != 1) { return; } var scope = expression.GetContainingFunctionLikeDeclarationOrClosure().GetCodeBody().GetAnyTreeNode(); if (scope == null) { return; } IEnumerable <ITreeNode> usages = null; ITreeNode storage = null; var containingParenthesizedExpression = expression.GetContainingParenthesizedExpression(); var castExpression = CastExpressionNavigator.GetByOp(containingParenthesizedExpression); var asExpression = AsExpressionNavigator.GetByOperand(containingParenthesizedExpression); var initializer = ExpressionInitializerNavigator.GetByValue(castExpression ?? asExpression ?? containingParenthesizedExpression); var declaration = LocalVariableDeclarationNavigator.GetByInitial(initializer); var usageProvider = data.GetUsagesProvider(); if (declaration != null) { usages = usageProvider.GetUsages(declaration.DeclaredElement, scope).Where(t => t is IReferenceExpression); storage = declaration; } else { var assignment = AssignmentExpressionNavigator.GetBySource(castExpression ?? asExpression ?? containingParenthesizedExpression); var dest = assignment?.Dest as IReferenceExpression; var destInfo = dest?.Reference.Resolve(); if (destInfo != null && destInfo.ResolveErrorType == ResolveErrorType.OK) { usages = usageProvider.GetUsages(destInfo.DeclaredElement.NotNull(), scope).Where(t => IsSameReferenceUsed(t, dest)); storage = dest; } else { return; } } foreach (var usage in usages) { if (usage is IReferenceExpression referenceExpression) { var fullReferenceExpression = ReferenceExpressionNavigator.GetTopByQualifierExpression(referenceExpression); if (IsUsageSetTransformParent(fullReferenceExpression, out var stayInWorldCoords, out var transform)) { if (!InSameBlock(fullReferenceExpression, storage)) { return; } var finder = new TransformParentRelatedReferenceFinder(referenceExpression); var relatedExpressions = finder.GetRelatedExpressions(scope, expression).FirstOrDefault(); if (relatedExpressions == null || relatedExpressions.GetTreeStartOffset() >= fullReferenceExpression.GetTreeStartOffset()) { consumer.AddHighlighting(new InstantiateWithoutParentWarning(fullReferenceExpression, expression, transform, stayInWorldCoords)); } return; } } } }