public override Task Link(params AstNode[] nodes) { var segs = nodes.Select(node => GetSegment(node)).ToArray(); InsertionContext c = new InsertionContext(editor.GetRequiredService <TextArea>(), segs.Min(seg => seg.Offset)); c.InsertionPosition = segs.Max(seg => seg.EndOffset); var tcs = new TaskCompletionSource <bool>(); c.Deactivated += (sender, e) => tcs.SetResult(true); if (segs.Length > 0) { // try to use node in identifier context to avoid the code completion popup. var identifier = nodes.OfType <Identifier>().FirstOrDefault(); ISegment first; if (identifier == null) { first = segs[0]; } else { first = GetSegment(identifier); } c.Link(first, segs.Except(new[] { first }).ToArray()); c.RaiseInsertionCompleted(EventArgs.Empty); } else { c.RaiseInsertionCompleted(EventArgs.Empty); c.Deactivate(new SnippetEventArgs(DeactivateReason.NoActiveElements)); } return(tcs.Task); }
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.Virt | 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 = AlFormattingPolicies.Instance.GetProjectOptions(contextAtCaret.Compilation.GetProject()); var segmentDict = SegmentTrackingOutputFormatter.WriteNode( w, entityDeclaration, formattingOptions.OptionsContainer.GetEffectiveOptions(), 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); } AlFormatterHelper.Format(context.Editor, declarationBegin, newText.Length, formattingOptions.OptionsContainer); var refactoringContext = SDRefactoringContext.Create(context.Editor, CancellationToken.None); var typeResolveContext = refactoringContext.GetTypeResolveContext(); if (typeResolveContext == null) { return; } var resolvedCurrent = typeResolveContext.CurrentTypeDefinition; 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; var current = typeResolveContext.CurrentTypeDefinition; AbstractInlineRefactorDialog dialog = new OverrideEqualsGetHashCodeMethodsDialog(insertionContext, context.Editor, endAnchor, insertionPos, current, Entity as IMethod, baseCallStatement); dialog.Element = uiService.CreateInlineUIElement(insertionPos, dialog); insertionContext.RegisterActiveElement(new InlineRefactorSnippetElement(cxt => null, ""), dialog); insertionContext.RaiseInsertionCompleted(EventArgs.Empty); } }
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; } using (textEditor.Document.OpenUndoGroup()) { ITextAnchor startAnchor = textEditor.Document.CreateAnchor(textEditor.Caret.Offset); startAnchor.MovementType = AnchorMovementType.BeforeInsertion; ITextAnchor endAnchor = textEditor.Document.CreateAnchor(textEditor.Caret.Offset); endAnchor.MovementType = AnchorMovementType.AfterInsertion; 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); AbstractInlineRefactorDialog dialog = new OverrideEqualsGetHashCodeMethodsDialog(insertionContext, textEditor, startAnchor, endAnchor, insertionPos, current, completionItem.Member as IMethod, 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); insertionContext.RaiseInsertionCompleted(EventArgs.Empty); } }