// 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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
        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;
                    }
                }
            }
        }