public override void Complete(CompletionContext context)
        {
            if (declarationBegin > context.StartOffset)
            {
                base.Complete(context);
                return;
            }

            TypeSystemAstBuilder b = new TypeSystemAstBuilder(contextAtCaret);

            b.ShowTypeParameterConstraints = false;
            b.GenerateBody = true;

            var entityDeclaration = b.ConvertEntity(this.Entity);

            entityDeclaration.Modifiers &= ~(Modifiers.Virtual | Modifiers.Abstract);
            entityDeclaration.Modifiers |= Modifiers.Override;

            var       body = entityDeclaration.GetChildByRole(Roles.Body);
            Statement baseCallStatement = body.Children.OfType <Statement>().FirstOrDefault();

            if (!this.Entity.IsAbstract)
            {
                // modify body to call the base method
                if (this.Entity.SymbolKind == SymbolKind.Method)
                {
                    var baseCall = new BaseReferenceExpression().Invoke(this.Entity.Name, new Expression[] { });
                    if (((IMethod)this.Entity).ReturnType.IsKnownType(KnownTypeCode.Void))
                    {
                        baseCallStatement = new ExpressionStatement(baseCall);
                    }
                    else
                    {
                        baseCallStatement = new ReturnStatement(baseCall);
                    }

                    // Clear body of inserted method
                    entityDeclaration.GetChildByRole(Roles.Body).Statements.Clear();
                }
            }

            var          document          = context.Editor.Document;
            StringWriter w                 = new StringWriter();
            var          formattingOptions = FormattingOptionsFactory.CreateSharpDevelop();
            var          segmentDict       = SegmentTrackingOutputFormatter.WriteNode(w, entityDeclaration, formattingOptions, context.Editor.Options);

            using (document.OpenUndoGroup()) {
                InsertionContext insertionContext = new InsertionContext(context.Editor.GetService(typeof(TextArea)) as TextArea, declarationBegin);
                insertionContext.InsertionPosition = context.Editor.Caret.Offset;

                string newText = w.ToString().TrimEnd();
                document.Replace(declarationBegin, context.EndOffset - declarationBegin, newText);
                var throwStatement = entityDeclaration.Descendants.FirstOrDefault(n => n is ThrowStatement);
                if (throwStatement != null)
                {
                    var segment = segmentDict[throwStatement];
                    context.Editor.Select(declarationBegin + segment.Offset, segment.Length);
                }
                CSharpFormatterHelper.Format(context.Editor, declarationBegin, newText.Length, formattingOptions);

                var refactoringContext = SDRefactoringContext.Create(context.Editor, CancellationToken.None);
                var typeResolveContext = refactoringContext.GetTypeResolveContext();
                if (typeResolveContext == null)
                {
                    return;
                }
                var resolvedCurrent = typeResolveContext.CurrentTypeDefinition;
                var entities        = FindFieldsAndProperties(resolvedCurrent).ToList();
                if (entities.Any())
                {
                    IEditorUIService uiService = context.Editor.GetService(typeof(IEditorUIService)) as IEditorUIService;

                    ITextAnchor endAnchor = context.Editor.Document.CreateAnchor(context.Editor.Caret.Offset);
                    endAnchor.MovementType = AnchorMovementType.AfterInsertion;

                    ITextAnchor startAnchor = context.Editor.Document.CreateAnchor(context.Editor.Caret.Offset);
                    startAnchor.MovementType = AnchorMovementType.BeforeInsertion;

                    ITextAnchor insertionPos = context.Editor.Document.CreateAnchor(endAnchor.Offset);
                    insertionPos.MovementType = AnchorMovementType.BeforeInsertion;

                    AbstractInlineRefactorDialog dialog = new OverrideToStringMethodDialog(insertionContext, context.Editor, insertionPos, entities, baseCallStatement);
                    dialog.Element = uiService.CreateInlineUIElement(insertionPos, dialog);

                    insertionContext.RegisterActiveElement(new InlineRefactorSnippetElement(cxt => null, ""), dialog);
                }
                else
                {
                    if (baseCallStatement != null)
                    {
                        // Add default base call
                        MethodDeclaration insertedOverrideMethod = refactoringContext.GetNode().PrevSibling as MethodDeclaration;
                        if (insertedOverrideMethod == null)
                        {
                            // We are not inside of a method declaration
                            return;
                        }
                        using (Script script = refactoringContext.StartScript()) {
                            script.AddTo(insertedOverrideMethod.Body, baseCallStatement);
                        }
                    }
                }

                insertionContext.RaiseInsertionCompleted(EventArgs.Empty);
            }
        }
예제 #2
0
        public void Insert(CompletionContext context, ICompletionItem item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            if (!(item is OverrideCompletionItem))
            {
                throw new ArgumentException("item is not an OverrideCompletionItem");
            }

            OverrideCompletionItem completionItem = item as OverrideCompletionItem;

            ITextEditor textEditor = context.Editor;

            IEditorUIService uiService = textEditor.GetService(typeof(IEditorUIService)) as IEditorUIService;

            if (uiService == null)
            {
                return;
            }

            ParseInformation parseInfo = ParserService.GetParseInformation(textEditor.FileName);

            if (parseInfo == null)
            {
                return;
            }

            CodeGenerator generator = parseInfo.CompilationUnit.Language.CodeGenerator;
            IClass        current   = parseInfo.CompilationUnit.GetInnermostClass(textEditor.Caret.Line, textEditor.Caret.Column);
            ClassFinder   finder    = new ClassFinder(current, textEditor.Caret.Line, textEditor.Caret.Column);

            if (current == null)
            {
                return;
            }

            List <PropertyOrFieldWrapper> entities = FindFieldsAndProperties(current).ToList();

            using (textEditor.Document.OpenUndoGroup()) {
                ITextAnchor endAnchor = textEditor.Document.CreateAnchor(textEditor.Caret.Offset);
                endAnchor.MovementType = AnchorMovementType.AfterInsertion;

                ITextAnchor startAnchor = textEditor.Document.CreateAnchor(textEditor.Caret.Offset);
                startAnchor.MovementType = AnchorMovementType.BeforeInsertion;

                MethodDeclaration member = (MethodDeclaration)generator.GetOverridingMethod(completionItem.Member, finder);

                string indent          = DocumentUtilitites.GetWhitespaceBefore(textEditor.Document, textEditor.Caret.Offset);
                string codeForBaseCall = generator.GenerateCode(member.Body.Children.OfType <AbstractNode>().First(), "");
                string code            = generator.GenerateCode(member, indent);
                int    marker          = code.IndexOf(codeForBaseCall);

                textEditor.Document.Insert(startAnchor.Offset, code.Substring(0, marker).TrimStart());

                ITextAnchor insertionPos = textEditor.Document.CreateAnchor(endAnchor.Offset);
                insertionPos.MovementType = AnchorMovementType.BeforeInsertion;

                InsertionContext insertionContext = new InsertionContext(textEditor.GetService(typeof(TextArea)) as TextArea, startAnchor.Offset);

                if (entities.Any())
                {
                    AbstractInlineRefactorDialog dialog = new OverrideToStringMethodDialog(insertionContext, textEditor, startAnchor, insertionPos, entities, codeForBaseCall.Trim());
                    dialog.Element = uiService.CreateInlineUIElement(insertionPos, dialog);

                    textEditor.Document.InsertNormalized(endAnchor.Offset, Environment.NewLine + code.Substring(marker + codeForBaseCall.Length));

                    insertionContext.RegisterActiveElement(new InlineRefactorSnippetElement(cxt => null, ""), dialog);
                }
                else
                {
                    int startIndex = endAnchor.Offset;
                    textEditor.Document.InsertNormalized(startIndex, code.Substring(marker));
                    textEditor.Select(startIndex, codeForBaseCall.TrimEnd().Length);
                }
                insertionContext.RaiseInsertionCompleted(EventArgs.Empty);
            }
        }