private void HandleItemCompleted(object sender,
                                  ILookupItem lookupitem,
                                  Suffix suffix,
                                  LookupItemInsertType lookupiteminserttype)
 {
     _delayedCancelAction.Cancel();
     OnApplied(_terminationTrigger.GetValueOrDefault(EventTrigger.Typing), lookupitem);
 }
예제 #2
0
        public override void Accept(ITextControl textControl, DocumentRange nameRange,
                                    LookupItemInsertType lookupItemInsertType, Suffix suffix,
                                    ISolution solution, bool keepCaretStill)
        {
            var rangeMarker = nameRange.CreateRangeMarkerWithMappingToDocument();

            Accept(textControl, rangeMarker, solution);
        }
예제 #3
0
 public void Accept(ITextControl textControl,
                    TextRange nameRange,
                    LookupItemInsertType lookupItemInsertType,
                    Suffix suffix,
                    ISolution solution,
                    bool keepCaretStill)
 {
     Item.Accept(textControl, nameRange, lookupItemInsertType, suffix, solution, keepCaretStill);
 }
            public void Accept(ITextControl textControl, TextRange nameRange, LookupItemInsertType insertType,
                               Suffix suffix, ISolution solution, bool keepCaretStill)
            {
                const string template  = "Plugin.ControlFlow.PostfixTemplates.<{0}>";
                var          featureId = string.Format(template, myFakeText.ToLowerInvariant());

                TipsManager.Instance.FeatureIsUsed(featureId, textControl.Document, solution);

                myRealItem.Accept(textControl, nameRange, insertType, suffix, solution, keepCaretStill);
            }
예제 #5
0
            public void Accept(
                ITextControl textControl, TextRange nameRange, LookupItemInsertType lookupItemInsertType,
                Suffix suffix, ISolution solution, bool keepCaretStill)
            {
                textControl.Document.ReplaceText(nameRange, CASE_COMPLETION_NAME + "()");

                var psiServices = solution.GetPsiServices();

                psiServices.Files.CommitAllDocuments();

                var enumMember = Info.PreferredDeclaredElement;

                if (enumMember == null)
                {
                    return;
                }

                var invocationExpression = FindFakeInvocation(textControl, solution, nameRange.EndOffset);

                if (invocationExpression == null)
                {
                    return;
                }

                var factory  = CSharpElementFactory.GetInstance(invocationExpression);
                var template = (Info.IsFlagsEnum && !Info.IsZeroCase)
          ? (Info.IsMultiBitFlagCase ? "($0 & $1) != $1" : "($0 & $1) != 0")
          : "$0 == $1";

                var referenceExpression = (IReferenceExpression)invocationExpression.InvokedExpression;
                var qualifierExpression = referenceExpression.QualifierExpression;

                var enumMemberCheck = factory.CreateExpression(template, qualifierExpression, enumMember);

                var caretPointer = psiServices.DoTransaction(
                    commandName: typeof(EnumCaseCheckBehavior).FullName,
                    func: () =>
                {
                    using (WriteLockCookie.Create())
                    {
                        var memberCheck = invocationExpression.ReplaceBy(enumMemberCheck);
                        return(memberCheck.CreateTreeElementPointer());
                    }
                });

                if (caretPointer != null)
                {
                    var checkExpression = caretPointer.GetTreeNode();
                    if (checkExpression != null)
                    {
                        var offset = checkExpression.GetDocumentRange().TextRange.EndOffset;
                        textControl.Caret.MoveTo(offset, CaretVisualPlacement.DontScrollIfVisible);
                    }
                }
            }
        private string GetCompleteItemText(LookupItemInsertType insertType)
        {
            switch (insertType)
            {
            case LookupItemInsertType.Insert:
                return("Insert Item");

            case LookupItemInsertType.Replace:
                return("Replace with Item");

            default:
                throw new ArgumentOutOfRangeException(nameof(insertType), insertType, null);
            }
        }
            public void Accept(ITextControl textControl, TextRange nameRange, LookupItemInsertType insertType,
                               Suffix suffix, ISolution solution, bool keepCaretStill)
            {
                textControl.Document.ReplaceText(nameRange, "E()");

                var psiServices = solution.GetPsiServices();

                psiServices.CommitAllDocuments();

                var enumMember = myPointer.Resolve();

                if (enumMember == null)
                {
                    return;
                }

                var referenceExpression = FindReferenceExpression(textControl, solution);
                var invocation          = InvocationExpressionNavigator.GetByInvokedExpression(referenceExpression);

                if (invocation == null)
                {
                    return;
                }

                TipsManager.Instance.FeatureIsUsed(
                    "Plugin.ControlFlow.PostfixTemplates.<enum>", textControl.Document, solution);

                var factory         = CSharpElementFactory.GetInstance(referenceExpression);
                var template        = myIsFlags ? "($0 & $1) != 0" : "$0 == $1";
                var enumMemberCheck = factory.CreateExpression(
                    template, referenceExpression.QualifierExpression, enumMember);

                var commandName  = typeof(CSharpEnumCaseItemProvider).FullName;
                var caretPointer = psiServices.DoTransaction(commandName, () =>
                {
                    using (WriteLockCookie.Create())
                    {
                        var memberCheck = invocation.ReplaceBy(enumMemberCheck);
                        return(memberCheck.CreatePointer());
                    }
                });

                var checkExpression = caretPointer.GetTreeNode();

                if (checkExpression != null)
                {
                    var offset = checkExpression.GetDocumentRange().TextRange.EndOffset;
                    textControl.Caret.MoveTo(offset, CaretVisualPlacement.DontScrollIfVisible);
                }
            }
        public void Accept(
      ITextControl textControl, TextRange nameRange, LookupItemInsertType lookupItemInsertType,
      Suffix suffix, ISolution solution, bool keepCaretStill)
        {
            if (!myReplaceRange.IsValid || !myExpressionRange.IsValid) return;

              var replaceRange = myReplaceRange.Intersects(nameRange)
            ? new TextRange(myReplaceRange.StartOffset, nameRange.EndOffset)
            : myReplaceRange;

              var expressionText = textControl.Document.GetText(myExpressionRange);
              var targetText = myReplaceTemplate.Replace("$EXPR$", expressionText);

              var caretOffset = targetText.IndexOf("$CARET$", StringComparison.Ordinal);
              if (caretOffset == -1) caretOffset = targetText.Length;
              else targetText = targetText.Replace("$CARET$", string.Empty);

              textControl.Document.ReplaceText(replaceRange, targetText);

              var range = TextRange.FromLength(replaceRange.StartOffset, targetText.Length);
              AfterCompletion(textControl, solution, suffix, range, targetText, caretOffset);
        }
        public override void Accept(
            ITextControl textControl, DocumentRange nameRange,
            LookupItemInsertType insertType, Suffix suffix, ISolution solution, bool keepCaretStill)
        {
            var psiServices             = solution.GetPsiServices();
            var updateMethodDeclaration = TextControlToPsi.GetElement <IMethodDeclaration>(solution, textControl);

            if (!Info.ShouldGenerateMethod)
            {
                UpdateExistingMethod(updateMethodDeclaration, psiServices);
                return;
            }

            var isCoroutine = updateMethodDeclaration?.TypeUsage is IUserTypeUsage userTypeUsage &&
                              userTypeUsage.ScalarTypeName?.ShortName == "IEnumerator";

            var fixedNameRange = nameRange.SetStartTo(Info.MemberReplaceRanges.InsertRange.StartOffset);
            var memberRange    = Info.MemberReplaceRanges.GetAcceptRange(fixedNameRange, insertType);

            // Insert a dummy method declaration, as text, which means the PSI is reparsed. This will remove empty type
            // usages and merge leading attributes into a method declaration, such that we can copy them and replace
            // them once the declared element has expanded. This also fixes up the case where the type usage picks up
            // the attribute of the next code construct as an array specifier. E.g. `OnAni{caret} [SerializeField]`
            using (WriteLockCookie.Create())
            {
                textControl.Document.ReplaceText(memberRange, "void Foo(){}");
            }

            psiServices.Files.CommitAllDocuments();

            var methodDeclaration = TextControlToPsi.GetElement <IMethodDeclaration>(solution, textControl);

            if (methodDeclaration == null)
            {
                return;
            }

            var methodDeclarationCopy = methodDeclaration.Copy();
            var nodesBeforeCopyRange  = NodesBeforeMethodHeader(methodDeclarationCopy);

            using (new PsiTransactionCookie(psiServices, DefaultAction.Commit, "RemoveInsertedDeclaration"))
                using (WriteLockCookie.Create())
                {
                    LowLevelModificationUtil.DeleteChild(methodDeclaration);
                }

            var classDeclaration = TextControlToPsi.GetElement <IClassLikeDeclaration>(solution, textControl);

            Assertion.AssertNotNull(classDeclaration, "classDeclaration != null");

            var factory = CSharpElementFactory.GetInstance(classDeclaration);

            GenerateCodeWorkflowBase.ExecuteNonInteractive(
                GeneratorUnityKinds.UnityEventFunctions, solution, textControl, methodDeclaration.Language,
                configureContext: context =>
            {
                // Note that the generated code will use the access rights, if specified. However, if they haven't
                // been specified (NONE) or they are the default for methods (PRIVATE), the generated code will be
                // whatever the current code style setting is - implicit or explicit
                var knownTypesCache = solution.GetComponent <KnownTypesCache>();
                var declaredElement = myEventFunction.CreateDeclaration(factory, knownTypesCache, classDeclaration,
                                                                        myAccessRights, makeCoroutine: isCoroutine)
                                      .DeclaredElement.NotNull("declaredElement != null");
                context.InputElements.Clear();
                context.InputElements.Add(new GeneratorDeclaredElement(declaredElement));
            },
                onCompleted: context =>
            {
                if (nodesBeforeCopyRange.IsEmpty)
                {
                    return;
                }

                foreach (var outputElement in context.OutputElements)
                {
                    if (outputElement is GeneratorDeclarationElement declarationElement)
                    {
                        using (new PsiTransactionCookie(psiServices, DefaultAction.Commit, "BringBackAttributes"))
                            using (WriteLockCookie.Create())
                            {
                                var newDeclaration = declarationElement.Declaration;
                                ModificationUtil.AddChildRangeAfter(newDeclaration, anchor: null, nodesBeforeCopyRange);
                            }

                        return;
                    }
                }
            });

            ITreeRange NodesBeforeMethodHeader(IMethodDeclaration declaration)
            {
                var firstNode = declaration.ModifiersList ?? declaration.TypeUsage as ITreeNode;

                var smthBeforeTypeUsage = firstNode?.PrevSibling;

                if (smthBeforeTypeUsage == null)
                {
                    return(TreeRange.Empty);
                }

                return(new TreeRange(declaration.FirstChild, smthBeforeTypeUsage));
            }
        }
        public override void Accept(ITextControl textControl, TextRange nameRange, LookupItemInsertType lookupItemInsertType, Suffix suffix,
                                    ISolution solution, bool keepCaretStill)
        {
            var rangeMarker = nameRange.CreateRangeMarkerWithMappingToDocument(textControl.Document);

            var identifierNode = TextControlToPsi.GetElement <ITreeNode>(solution, textControl);
            var psiServices    = solution.GetPsiServices();

            if (identifierNode != null)
            {
                IErrorElement errorElement = null;

                ITreeNode usage = identifierNode.GetContainingNode <IUserTypeUsage>();
                if (usage != null)
                {
                    errorElement = usage.NextSibling as IErrorElement;
                }
                else
                {
                    usage = identifierNode.PrevSibling;
                    while (usage != null && !(usage is ITypeUsage))
                    {
                        usage = usage.PrevSibling;
                    }
                    errorElement = identifierNode.NextSibling as IErrorElement;
                }

                using (var cookie = new PsiTransactionCookie(psiServices, DefaultAction.Rollback, "RemoveIdentifier"))
                    using (new DisableCodeFormatter())
                    {
                        using (WriteLockCookie.Create())
                        {
                            ModificationUtil.DeleteChild(identifierNode);
                            if (usage != null)
                            {
                                ModificationUtil.DeleteChild(usage);
                            }
                            if (errorElement != null)
                            {
                                ModificationUtil.DeleteChild(errorElement);
                            }
                        }

                        cookie.Commit();
                    }
            }

            using (WriteLockCookie.Create())
            {
                textControl.Document.InsertText(rangeMarker.Range.StartOffset, "void Foo(){}");
            }

            psiServices.Files.CommitAllDocuments();

            var methodDeclaration = TextControlToPsi.GetElement <IMethodDeclaration>(solution, textControl);

            if (methodDeclaration == null)
            {
                return;
            }

            var insertionIndex = methodDeclaration.GetTreeStartOffset().Offset;

            string attributeText = null;

            var attributeList = methodDeclaration.FirstChild as IAttributeSectionList;

            if (attributeList != null)
            {
                attributeText = attributeList.GetText();
                var treeNode = attributeList.NextSibling;
                while (treeNode is IWhitespaceNode)
                {
                    attributeText += treeNode.GetText();
                    treeNode       = treeNode.NextSibling;
                }
            }

            using (var cookie = new PsiTransactionCookie(psiServices, DefaultAction.Rollback, "RemoveInsertedDeclaration"))
                using (new DisableCodeFormatter())
                {
                    using (WriteLockCookie.Create())
                        ModificationUtil.DeleteChild(methodDeclaration);

                    cookie.Commit();
                }

            // Get the UniteMessages generator to actually insert the methods
            GenerateCodeWorkflowBase.ExecuteNonInteractive(
                GeneratorUnityKinds.UnityMessages, solution, textControl, methodDeclaration.Language,
                configureContext: context =>
            {
                var inputElements = from e in context.ProvidedElements.Cast <GeneratorDeclaredElement <IMethod> >()
                                    where myMessage.Match(e.DeclaredElement)
                                    select e;

                context.InputElements.Clear();
                context.InputElements.AddRange(inputElements);
            });

            if (!string.IsNullOrEmpty(attributeText))
            {
                using (WriteLockCookie.Create())
                    textControl.Document.InsertText(insertionIndex, attributeText);
            }
        }
        public void Accept(
      ITextControl textControl, TextRange nameRange,
      LookupItemInsertType insertType, Suffix suffix,
      ISolution solution, bool keepCaretStill)
        {
            // find target expression after code completion
              var expressionRange = myExpressionRange.Range;

              if (myWasReparsed)
              {
            textControl.Document.ReplaceText(nameRange, "__");
            solution.GetPsiServices().CommitAllDocuments();
            nameRange = TextRange.FromLength(nameRange.StartOffset, 2);
              }

              var expression = (ICSharpExpression) FindMarkedNode(
            solution, textControl, expressionRange, nameRange, typeof(ICSharpExpression));

              if (expression == null)
              {
            // still can be parsed as IReferenceName
            var referenceName = (IReferenceName) FindMarkedNode(
              solution, textControl, expressionRange, nameRange, typeof(IReferenceName));

            if (referenceName == null) return;

            // reparse IReferenceName as ICSharpExpression
            var factory = CSharpElementFactory.GetInstance(referenceName.GetPsiModule(), false);
            expression = factory.CreateExpression(referenceName.GetText());
              }

              // take required component while tree is valid
              var psiModule = expression.GetPsiModule();

              var reference = FindMarkedNode(
            solution, textControl, myReferenceRange.Range, nameRange, myReferenceType);

              // Razor.{caret} case
              if (reference == expression && myWasReparsed)
              {
            var parentReference = reference.Parent as IReferenceExpression;
            if (parentReference != null && parentReference.NameIdentifier.Name == "__")
              reference = parentReference;
              }

              // calculate textual range to remove
              var replaceRange = CalculateRangeToRemove(nameRange, expression, reference);

              // fix "x > 0.if" to "x > 0"
              ICSharpExpression expressionCopy;
              if (reference != null && expression.Contains(reference))
              {
            expressionCopy = FixExpression(expression, reference);
              }
              else
              {
            expressionCopy = expression.IsPhysical() ? expression.Copy(expression) : expression;
              }

              Assertion.Assert(!expressionCopy.IsPhysical(), "expressionCopy is physical");

              ExpandPostfix(
            textControl, suffix, solution,
            replaceRange, psiModule, expressionCopy);
        }
        public override void Accept(JetBrains.TextControl.ITextControl textControl, JetBrains.Util.TextRange nameRange, LookupItemInsertType lookupItemInsertType, Suffix suffix, JetBrains.ProjectModel.ISolution solution, bool keepCaretStill)
        {
            Solution.GetPsiServices().Files.CommitAllDocuments();

            IDisposable changeUnit = Shell.Instance.GetComponent <TextControlChangeUnitFactory>().CreateChangeUnit(textControl, "Expand live template");

            try
            {
                var method = (IMethod)_instance.Element;
                var invocationExpression = ((IInvocationExpression)Context.NodeInFile.Parent); //target.GetMethod()


                string target = ((IReferenceExpression)invocationExpression.InvokedExpression).QualifierExpression.GetText();
                if (!method.IsStatic)
                {
                    target = string.Format("Expression.Default({0})", target);
                }


                textControl.Document.DeleteText(invocationExpression.GetDocumentRange().TextRange);

                string[] parameters;
                string[] arguments;
                BuildArguments(method, out parameters, out arguments);

                var template = new Template("GetMethodTemplate", string.Empty,
                                            string.Format("Expression.Call({0}, \"{1}\", new Type[] {{ {2} }}, {3}).Method", target, method.ShortName,
                                                          string.Join(", ", parameters.Select(p => string.Format("typeof({0})", p))),
                                                          string.Join(", ", arguments)),
                                            false, true, false, TemplateApplicability.Live);

                for (int i = 0; i < parameters.Length; i++)
                {
                    template.Fields.Add(new TemplateField(parameters[i].Replace("$", string.Empty), parameters[i], 0));
                }

                HotspotSession sessionFromTemplate = LiveTemplatesManager.Instance.CreateHotspotSessionFromTemplate(
                    template,
                    solution,
                    textControl, (Action <IHotspotSession>)null);
                if (sessionFromTemplate == null)
                {
                    return;
                }
                sessionFromTemplate.Execute(changeUnit);
            }
            catch
            {
                changeUnit.Dispose();
                throw;
            }
        }
예제 #13
0
 public override void Accept(ITextControl textControl, DocumentRange nameRange,
                             LookupItemInsertType lookupItemInsertType, Suffix suffix,
                             ISolution solution, bool keepCaretStill)
 {
     Accept(textControl, nameRange, solution);
 }
예제 #14
0
        public void Accept(ITextControl textControl, TextRange nameRange, LookupItemInsertType insertType,
                           Suffix suffix, ISolution solution, bool keepCaretStill)
        {
            // todo: carefully review and document all of this :\
            var reparseString = Info.ReparseString;

            // so we inserted '.__' and get '2 + 2.__' just like in code completion reparse
            textControl.Document.InsertText(nameRange.EndOffset, reparseString, TextModificationSide.RightSide);

            solution.GetPsiServices().Files.CommitAllDocuments();

            var executionContext = new PostfixTemplateExecutionContext(
                solution, textControl, Info.ExecutionContext.SettingsStore, Info.ReparseString, Info.ExecutionContext.IsPreciseMode);

            PostfixTemplateContext postfixContext = null;

            foreach (var element in TextControlToPsi.GetElements <ITreeNode>(solution, textControl.Document, nameRange.EndOffset))
            {
                var contextFactory = LanguageManager.Instance.TryGetService <IPostfixTemplateContextFactory>(element.Language);
                if (contextFactory == null)
                {
                    continue;
                }

                postfixContext = contextFactory.TryCreate(element, executionContext);
                if (postfixContext != null)
                {
                    break;
                }
            }

            // todo: [R#] good feature id, looks at source templates 'Accept()'
            TipsManager.Instance.FeatureIsUsed(
                "Plugin.ControlFlow.PostfixTemplates." + Info.Text, textControl.Document, solution);

            Assertion.AssertNotNull(postfixContext, "postfixContext != null");

            var expressions = FindOriginalContexts(postfixContext);

            Assertion.Assert(expressions.Count > 0, "expressions.Count > 0");

            if (expressions.Count > 1 && myExpressionIndex == -1)
            {
                // rollback document changes to hide reparse string from user
                var chooser = solution.GetComponent <ExpressionChooser>();

                var postfixRange = GetPostfixRange(textControl, nameRange);
                var postfixText  = textControl.Document.GetText(postfixRange);
                textControl.Document.ReplaceText(postfixRange, string.Empty);

                chooser.Execute(
                    EternalLifetime.Instance, textControl, expressions, postfixText,
                    ExpressionSelectTitle, continuation: index =>
                {
                    myExpressionIndex = index;

                    // yep, run accept recursively, now with selected item index
                    var locks = solution.GetComponent <IShellLocks>();
                    const string commandName = "PostfixTemplates.Accept";

                    locks.ReentrancyGuard.ExecuteOrQueue(commandName, () =>
                    {
                        locks.ExecuteWithReadLock(() =>
                        {
                            var processor = solution.GetComponent <ICommandProcessor>();
                            using (processor.UsingCommand(commandName))
                            {
                                var text = postfixText.Substring(0, postfixText.Length - reparseString.Length);

                                // todo: don't like it very much, is there a better way to solve this?
                                textControl.Document.InsertText( // bring back ".name__"
                                    postfixRange.StartOffset, text, TextModificationSide.RightSide);

                                // argh!
                                Accept(textControl, nameRange, insertType, suffix, solution, keepCaretStill);
                            }
                        });
                    });
                });

                return;
            }

            Assertion.Assert(myExpressionIndex >= 0, "myExpressionIndex >= 0");
            Assertion.Assert(myExpressionIndex < expressions.Count, "myExpressionIndex < expressions.Count");

            var expressionContext = expressions[myExpressionIndex];

            ITreeNode newNode;

            using (WriteLockCookie.Create())
            {
                var fixedContext = postfixContext.FixExpression(expressionContext);

                var expression = fixedContext.Expression;
                Assertion.Assert(expression.IsPhysical(), "expression.IsPhysical()");

                newNode = ExpandPostfix(fixedContext);
                Assertion.AssertNotNull(newNode, "newNode != null");
                Assertion.Assert(newNode.IsPhysical(), "newNode.IsPhysical()");
            }

            AfterComplete(textControl, newNode);
        }
            public override void Accept(
                ITextControl textControl, TextRange nameRange, LookupItemInsertType lookupItemInsertType,
                Suffix suffix, ISolution solution, bool keepCaretStill)
            {
                base.Accept(textControl, nameRange, lookupItemInsertType, suffix, solution, keepCaretStill);

                var psiServices = solution.GetPsiServices();
                var startOffset = nameRange.StartOffset;
                var suffix1     = suffix;

                psiServices.Files.CommitAllDocuments();

                var hotspotInfo = psiServices.DoTransaction(
                    commandName: typeof(CSharpTypeParameterFromUsageItemProvider).FullName,
                    func: () =>
                {
                    using (WriteLockCookie.Create(true))
                    {
                        var typeParameterName = Info.Text;
                        var referenceName     = TextControlToPsi
                                                .GetElements <IReferenceName>(solution, textControl.Document, startOffset)
                                                .FirstOrDefault(x => x.NameIdentifier != null && x.NameIdentifier.Name == typeParameterName);

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

                        var methodDeclaration = referenceName.GetContainingNode <IMethodDeclaration>();
                        if (methodDeclaration == null)
                        {
                            return(null);
                        }

                        var factory = CSharpElementFactory.GetInstance(methodDeclaration);

                        var lastTypeParameter = methodDeclaration.TypeParameterDeclarations.LastOrDefault();
                        var newTypeParameter  = methodDeclaration.AddTypeParameterAfter(
                            factory.CreateTypeParameterOfMethodDeclaration(typeParameterName), anchor: lastTypeParameter);

                        return(new HotspotInfo(
                                   templateField: new TemplateField(typeParameterName, initialRange: 0),
                                   documentRanges: new[] { newTypeParameter.GetDocumentRange(), referenceName.GetDocumentRange() }));
                    }
                });

                if (hotspotInfo == null)
                {
                    return;
                }

                // do not provide hotspots when item is completed with spacebar
                if (suffix1.HasPresentation && suffix1.Presentation == ' ')
                {
                    return;
                }

                var endRange = hotspotInfo.Ranges[1].EndOffsetRange().TextRange;

                var session = LiveTemplatesManager.Instance.CreateHotspotSessionAtopExistingText(
                    solution, endRange, textControl, LiveTemplatesManager.EscapeAction.RestoreToOriginalText, hotspotInfo);

                session.Execute();
            }
            private void PlaceCaretAfterCompletion(
                [NotNull] ITextControl textControl, [NotNull] IReferenceExpression referenceExpression, int existingArgumentsCount, LookupItemInsertType insertType)
            {
                var referenceRange = referenceExpression.GetDocumentRange();

                textControl.Caret.MoveTo(referenceRange.TextRange.EndOffset, CaretVisualPlacement.DontScrollIfVisible);

                var invocationExpression = InvocationExpressionNavigator.GetByInvokedExpression(referenceExpression);

                if (invocationExpression == null)
                {
                    return;
                }

                var invocationRange = invocationExpression.GetDocumentRange();

                textControl.Caret.MoveTo(invocationRange.TextRange.EndOffset, CaretVisualPlacement.DontScrollIfVisible);

                var settingsStore           = referenceExpression.GetSettingsStore();
                var parenthesesInsertType   = settingsStore.GetValue(CodeCompletionSettingsAccessor.ParenthesesInsertType);
                var hasMoreParametersToPass = HasMoreParametersToPass(existingArgumentsCount);

                switch (parenthesesInsertType)
                {
                case ParenthesesInsertType.Both:
                {
                    if (hasMoreParametersToPass)
                    {
                        var rightPar = invocationExpression.RPar;
                        if (rightPar != null)
                        {
                            var rightParRange = rightPar.GetDocumentRange().TextRange;
                            textControl.Caret.MoveTo(rightParRange.StartOffset, CaretVisualPlacement.DontScrollIfVisible);
                        }
                    }

                    break;
                }

                case ParenthesesInsertType.Left:
                case ParenthesesInsertType.None:
                {
                    // if in insert mode - drop right par and set caret to it's start offest
                    if (insertType == LookupItemInsertType.Insert)
                    {
                        var rightPar = invocationExpression.RPar;
                        if (rightPar != null)
                        {
                            var rightParRange = rightPar.GetDocumentRange().TextRange;

                            invocationExpression.GetPsiServices().Transactions.Execute(
                                commandName: typeof(StaticMethodBehavior).FullName,
                                handler: () =>
                                {
                                    using (WriteLockCookie.Create())
                                        LowLevelModificationUtil.DeleteChild(rightPar);
                                });

                            textControl.Caret.MoveTo(rightParRange.StartOffset, CaretVisualPlacement.DontScrollIfVisible);
                        }
                    }

                    break;
                }
                }
            }
            public void Accept(ITextControl textControl, TextRange nameRange, LookupItemInsertType lookupItemInsertType, Suffix suffix, ISolution solution, bool keepCaretStill)
            {
                /* PLEASE DO NOT OBSERVE THIS */
                string text;

                if (lookupItemInsertType == LookupItemInsertType.Insert)
                {
                    if (Info.InsertText.IndexOf(')') == -1)
                    {
                        Info.InsertText += ")";
                    }

                    text = Info.Text + Info.InsertText;
                    textControl.Document.ReplaceText(Info.Ranges.InsertRange.JoinRight(nameRange), text);
                }
                else
                {
                    if (Info.ReplaceText.IndexOf(')') == -1)
                    {
                        Info.ReplaceText += ")";
                    }

                    text = Info.Text + Info.ReplaceText;
                    textControl.Document.ReplaceText(Info.Ranges.ReplaceRange.JoinRight(nameRange), text);
                }

                var tailType = Info.TailType;

                if (tailType != null)
                {
                    LookupUtil.InsertTailType(textControl, nameRange.StartOffset + text.Length, tailType, solution, emulateTypingOfSpace: false);
                }

                /* PLEASE DO NOT OBSERVE THIS */

                var psiServices = solution.GetPsiServices();

                psiServices.Files.CommitAllDocuments();

                var referenceExpression = TextControlToPsi.GetElement <IReferenceExpression>(solution, textControl.Document, nameRange.StartOffset);

                if (referenceExpression == null || myMethods.Count == 0)
                {
                    return;
                }

                var existingArgumentsCount = GetExistingArgumentsCount(referenceExpression);
                var referencePointer       = referenceExpression.CreateTreeElementPointer();

                InsertQualifierAsArgument(referenceExpression, existingArgumentsCount, textControl);

                psiServices.Files.CommitAllDocuments();

                var reference1 = referencePointer.GetTreeNode();

                if (reference1 != null)
                {
                    var textRange = reference1.NameIdentifier.GetDocumentRange().TextRange;
                    var pointers  = Info.DeclaredElementPointers.ToList();

#if RESHARPER92
                    var caretPositionMarker = RangeMarker.InvalidMarker;
                    LookupUtil.BindRange(solution, textControl, textRange, pointers, reference1.Language, ref caretPositionMarker);
#else
                    LookupUtil.BindRange(solution, textControl, textRange, pointers, reference1.Language);
#endif

                    psiServices.Files.CommitAllDocuments();

                    var reference3 = referencePointer.GetTreeNode();
                    if (reference3 != null)
                    {
                        ApplyQualifierCodeStyle(reference3);

                        psiServices.Files.CommitAllDocuments();

                        var reference2 = referencePointer.GetTreeNode();
                        if (reference2 != null)
                        {
                            PlaceCaretAfterCompletion(textControl, reference2, existingArgumentsCount, lookupItemInsertType);
                        }
                    }
                }
            }
 public void Accept(ITextControl textControl, TextRange nameRange, LookupItemInsertType lookupItemInsertType, Suffix suffix,
     ISolution solution, bool keepCaretStill)
 {
     Item.Accept(textControl, nameRange, lookupItemInsertType, suffix, solution, keepCaretStill);
 }
예제 #19
0
        public void Accept(ITextControl textControl, TextRange nameRange, LookupItemInsertType insertType,
                           Suffix suffix, ISolution solution, bool keepCaretStill)
        {
            textControl.Document.InsertText(
                nameRange.EndOffset, myReparseString, TextModificationSide.RightSide);

            solution.GetPsiServices().CommitAllDocuments();

            var itemsOwnerFactory = solution.GetComponent <LookupItemsOwnerFactory>();
            var templatesManager  = solution.GetComponent <PostfixTemplatesManager>();
            var lookupItemsOwner  = itemsOwnerFactory.CreateLookupItemsOwner(textControl);

            PostfixTemplateContext postfixContext = null;
            var identifierOffset = (textControl.Caret.Offset() - myReparseString.Length);

            foreach (var position in TextControlToPsi
                     .GetElements <ITokenNode>(solution, textControl.Document, identifierOffset))
            {
                var executionContext = new PostfixExecutionContext(
                    myLifetime, solution, textControl, lookupItemsOwner, myReparseString, false);

                postfixContext = templatesManager.IsAvailable(position, executionContext);
                if (postfixContext != null)
                {
                    break;
                }
            }

            TipsManager.Instance.FeatureIsUsed(
                "Plugin.ControlFlow.PostfixTemplates." + myShortcut, textControl.Document, solution);

            Assertion.AssertNotNull(postfixContext, "postfixContext != null");

            var expressions = FindOriginalContexts(postfixContext);

            Assertion.Assert(expressions.Count > 0, "expressions.Count > 0");

            if (expressions.Count > 1 && myExpressionIndex == -1)
            {
                // rollback document changes to hide reparse string from user
                var chooser = solution.GetComponent <ExpressionChooser>();

                var postfixRange = GetPostfixRange(textControl, nameRange);
                var postfixText  = textControl.Document.GetText(postfixRange);
                textControl.Document.ReplaceText(postfixRange, string.Empty);

                chooser.Execute(myLifetime, textControl, expressions,
                                postfixText, ExpressionSelectTitle, index =>
                {
                    myExpressionIndex = index;

                    // yep, run accept recursively, now with selected item index
                    var locks = solution.GetComponent <IShellLocks>();
                    const string commandName = "PostfixTemplates.Accept";

                    locks.ReentrancyGuard.ExecuteOrQueue(commandName, () =>
                    {
                        locks.ExecuteWithReadLock(() =>
                        {
                            var processor = solution.GetComponent <ICommandProcessor>();
                            using (processor.UsingCommand(commandName))
                            {
                                var text = postfixText.Substring(0, postfixText.Length - myReparseString.Length);
                                textControl.Document.InsertText( // bring back ".name__"
                                    postfixRange.StartOffset, text, TextModificationSide.RightSide);

                                Accept(textControl, nameRange, insertType, suffix, solution, keepCaretStill);
                            }
                        });
                    });
                });
                return;
            }

            Assertion.Assert(myExpressionIndex >= 0, "myExpressionIndex >= 0");
            Assertion.Assert(myExpressionIndex < expressions.Count, "myExpressionIndex < expressions.Count");

            var expressionContext = expressions[myExpressionIndex];

            TNode newNode;

            using (WriteLockCookie.Create())
            {
                var fixedContext = postfixContext.FixExpression(expressionContext);

                var expression = fixedContext.Expression;
                Assertion.Assert(expression.IsPhysical(), "expression.IsPhysical()");

                newNode = ExpandPostfix(fixedContext);
                Assertion.AssertNotNull(newNode, "newNode != null");
                Assertion.Assert(newNode.IsPhysical(), "newNode.IsPhysical()");
            }

            AfterComplete(textControl, newNode);
        }