public async Task Run() { var token = default(CancellationToken); var insertionAction = act as InsertionAction; if (insertionAction != null) { var insertion = await insertionAction.CreateInsertion(token).ConfigureAwait(false); var document = await IdeApp.Workbench.OpenDocument(insertion.Location.SourceTree.FilePath, documentContext.Project); var parsedDocument = await document.UpdateParseDocument(); if (parsedDocument != null) { var insertionPoints = InsertionPointService.GetInsertionPoints( document.Editor, parsedDocument, insertion.Type, insertion.Location.SourceSpan.Start ); var options = new InsertionModeOptions( insertionAction.Title, insertionPoints, point => { if (!point.Success) { return; } var node = Formatter.Format(insertion.Node, document.RoslynWorkspace, document.GetOptionSet(), token); point.InsertionPoint.Insert(document.Editor, document, node.ToString()); // document = await Simplifier.ReduceAsync(document.AnalysisDocument, Simplifier.Annotation, cancellationToken: token).ConfigureAwait(false); } ); document.Editor.StartInsertionMode(options); return; } } var oldSolution = documentContext.AnalysisDocument.Project.Solution; var updatedSolution = oldSolution; using (var undo = editor.OpenUndoGroup()) { // TODO: Fix workaround for https://devdiv.visualstudio.com/DevDiv/_workitems?id=518783&fullScreen=true&_a=edit // Roslyn issue: https://github.com/dotnet/roslyn/issues/23239 updatedSolution = await act.GetChangedSolutionInternalAsync(true, token); documentContext.RoslynWorkspace.TryApplyChanges(updatedSolution, new RoslynProgressTracker()); } await TryStartRenameSession(documentContext.RoslynWorkspace, oldSolution, updatedSolution, token); }
public async Task Run() { var token = default(CancellationToken); var insertionAction = act as InsertionAction; if (insertionAction != null) { var insertion = await insertionAction.CreateInsertion(token).ConfigureAwait(false); var document = await IdeApp.Workbench.OpenDocument(insertion.Location.SourceTree.FilePath, documentContext.Project); var parsedDocument = await document.UpdateParseDocument(); if (parsedDocument != null) { var insertionPoints = InsertionPointService.GetInsertionPoints( document.Editor, parsedDocument, insertion.Type, insertion.Location.SourceSpan.Start ); var options = new InsertionModeOptions( insertionAction.Title, insertionPoints, point => { if (!point.Success) { return; } var node = Formatter.Format(insertion.Node, document.RoslynWorkspace, document.GetOptionSet(), token); point.InsertionPoint.Insert(document.Editor, document, node.ToString()); // document = await Simplifier.ReduceAsync(document.AnalysisDocument, Simplifier.Annotation, cancellationToken: token).ConfigureAwait(false); } ); document.Editor.StartInsertionMode(options); return; } } var oldSolution = documentContext.AnalysisDocument.Project.Solution; var updatedSolution = oldSolution; using (var undo = editor.OpenUndoGroup()) { updatedSolution = await act.GetChangedSolutionAsync(new RoslynProgressTracker(), token); documentContext.RoslynWorkspace.TryApplyChanges(updatedSolution, new RoslynProgressTracker()); } await TryStartRenameSession(documentContext.RoslynWorkspace, oldSolution, updatedSolution, token); }
public override async Task <CompletionChange> GetChangeAsync(Document doc, CompletionItem item, char?commitKey = default(char?), CancellationToken cancellationToken = default(CancellationToken)) { (string beforeText, string afterText, string newMethod) = await GetInsertText(item.Properties); TextChange change; if (newMethod != null) { change = new TextChange(new TextSpan(item.Span.Start, item.Span.Length), item.Properties [MethodNameKey] + ";"); var semanticModel = await doc.GetSemanticModelAsync(cancellationToken); if (!doc.IsOpen() || await doc.IsForkedDocumentWithSyntaxChangesAsync(cancellationToken)) { return(CompletionChange.Create(change)); } await Runtime.RunInMainThread(delegate { var document = IdeApp.Workbench.ActiveDocument; var editor = document.Editor; if (editor.EditMode != EditMode.Edit) { return; } var parsedDocument = document.ParsedDocument; var declaringType = semanticModel.GetEnclosingSymbolMD <INamedTypeSymbol> (item.Span.Start, default(CancellationToken)); var insertionPoints = InsertionPointService.GetInsertionPoints( document.Editor, semanticModel, declaringType, editor.CaretOffset ); var options = new InsertionModeOptions( GettextCatalog.GetString("Create new method"), insertionPoints, point => { if (!point.Success) { return; } point.InsertionPoint.Insert(document.Editor, document, newMethod); } ); editor.StartInsertionMode(options); }); return(CompletionChange.Create(change)); } change = new TextChange(new TextSpan(item.Span.Start, item.Span.Length), beforeText + afterText); return(CompletionChange.Create(change, item.Span.Start + beforeText.Length)); }
public override async Task <CompletionChange> GetChangeAsync(Document doc, CompletionItem item, char?commitKey = default(char?), CancellationToken cancellationToken = default(CancellationToken)) { TextChange change; if (item.Properties.ContainsKey("NewMethod")) { change = new TextChange(new TextSpan(item.Span.Start, item.Span.Length), item.Properties ["MethodName"] + ";"); var document = IdeApp.Workbench.ActiveDocument; var editor = document.Editor; var parsedDocument = document.ParsedDocument; var semanticModel = await doc.GetSemanticModelAsync(cancellationToken); var declaringType = semanticModel.GetEnclosingSymbolMD <INamedTypeSymbol> (item.Span.Start, default(CancellationToken)); var insertionPoints = InsertionPointService.GetInsertionPoints( document.Editor, parsedDocument, declaringType, editor.CaretOffset ); var options = new InsertionModeOptions( GettextCatalog.GetString("Create new method"), insertionPoints, point => { if (!point.Success) { return; } point.InsertionPoint.Insert(document.Editor, document, item.Properties ["NewMethod"]); } ); editor.StartInsertionMode(options); return(CompletionChange.Create(change)); } var beforeText = item.Properties ["InsertBefore"]; var afterText = item.Properties ["InsertAfter"]; change = new TextChange(new TextSpan(item.Span.Start, item.Span.Length), beforeText + afterText); return(CompletionChange.Create(change, item.Span.Start + beforeText.Length)); }
public override void InsertCompletionText(CompletionListWindow window, ref KeyActions ka, KeyDescriptor descriptor) { // insert add/remove event handler code after +=/-= var editor = factory.Ext.Editor; bool AddSemicolon = true; var position = window.CodeCompletionContext.TriggerOffset; editor.ReplaceText(position, editor.CaretOffset - position, this.DisplayText + (AddSemicolon ? ";" : "")); var document = IdeApp.Workbench.ActiveDocument; var parsedDocument = document.UpdateParseDocument().Result; var semanticModel = parsedDocument.GetAst <SemanticModel> (); var declaringType = semanticModel.GetEnclosingSymbol <INamedTypeSymbol> (position, default(CancellationToken)); var enclosingSymbol = semanticModel.GetEnclosingSymbol <ISymbol> (position, default(CancellationToken)); var insertionPoints = InsertionPointService.GetInsertionPoints( document.Editor, parsedDocument, declaringType, editor.CaretOffset ); var options = new InsertionModeOptions( GettextCatalog.GetString("Create new method"), insertionPoints, point => { if (!point.Success) { return; } var indent = "\t"; var sb = new StringBuilder(); if (enclosingSymbol != null && enclosingSymbol.IsStatic) { sb.Append("static "); } sb.Append("void "); int pos2 = sb.Length; sb.Append(this.DisplayText); sb.Append(' '); sb.Append("("); var delegateMethod = delegateType.GetDelegateInvokeMethod(); for (int k = 0; k < delegateMethod.Parameters.Length; k++) { if (k > 0) { sb.Append(", "); } sb.Append(RoslynCompletionData.SafeMinimalDisplayString(delegateMethod.Parameters [k], semanticModel, position, MonoDevelop.Ide.TypeSystem.Ambience.LabelFormat)); } sb.Append(")"); sb.Append(editor.EolMarker); sb.Append(indent); sb.Append("{"); sb.Append(editor.EolMarker); sb.Append(indent); sb.Append(editor.Options.GetIndentationString()); //int cursorPos = pos + sb.Length; sb.Append(editor.EolMarker); sb.Append(indent); sb.Append("}"); point.InsertionPoint.Insert(document.Editor, document, sb.ToString()); // // start text link mode after insert // var links = new List<TextLink> (); // var link = new TextLink ("name"); // // link.AddLink (new TextSegment (initialOffset, this.DisplayText.Length)); // link.AddLink (new TextSegment (initialOffset + pos + pos2, this.DisplayText.Length)); // links.Add (link); // editor.StartTextLinkMode (new TextLinkModeOptions (links)); } ); editor.StartInsertionMode(options); }
public static async Task InsertMemberWithCursor(string operation, Projects.Project project, ITypeSymbol type, Location part, SyntaxNode newMember, CancellationToken cancellationToken = default(CancellationToken)) { if (operation == null) { throw new ArgumentNullException(nameof(operation)); } if (project == null) { throw new ArgumentNullException(nameof(project)); } if (type == null) { throw new ArgumentNullException(nameof(type)); } if (newMember == null) { throw new ArgumentNullException(nameof(newMember)); } var doc = await IdeApp.Workbench.OpenDocument(part.SourceTree.FilePath, project, true); var textView = await doc.GetContentWhenAvailable <ITextView> (cancellationToken); await doc.DocumentContext.UpdateParseDocument(); var document = doc.DocumentContext.AnalysisDocument; if (document == null) { LoggingService.LogError("Can't find document to insert member (fileName:" + part.SourceTree.FilePath + ")"); return; } var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var typeDecl = (ClassDeclarationSyntax)root.FindNode(part.SourceSpan); // for some reason the reducer doesn't reduce this var systemVoid = newMember.DescendantNodesAndSelf().OfType <QualifiedNameSyntax> ().FirstOrDefault(ma => ma.ToString() == "System.Void"); if (systemVoid != null) { newMember = newMember.ReplaceNode(systemVoid, SyntaxFactory.ParseTypeName("void")); } var newRoot = root.ReplaceNode(typeDecl, typeDecl.AddMembers((MemberDeclarationSyntax)newMember.WithAdditionalAnnotations(Simplifier.Annotation, Formatter.Annotation, insertedMemberAnnotation))); var projectOptions = await document.GetOptionsAsync(cancellationToken); document = document.WithSyntaxRoot(newRoot); document = await Formatter.FormatAsync(document, Formatter.Annotation, projectOptions, cancellationToken).ConfigureAwait(false); document = await Simplifier.ReduceAsync(document, Simplifier.Annotation, projectOptions, cancellationToken).ConfigureAwait(false); root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var node = root.GetAnnotatedNodes(insertedMemberAnnotation).Single(); var model = await doc.DocumentContext.AnalysisDocument.GetSemanticModelAsync(cancellationToken); Application.Invoke((o, args) => { var editor = doc.Editor; if (editor == null) { // bypass the insertion point selection UI for the new editor document.Project.Solution.Workspace.TryApplyChanges(document.Project.Solution); var editorOperationsFactoryService = CompositionManager.Instance.GetExportedValue <IEditorOperationsFactoryService> (); var editorOperations = editorOperationsFactoryService.GetEditorOperations(textView); var point = new Microsoft.VisualStudio.Text.VirtualSnapshotPoint(textView.TextSnapshot, node.SpanStart); editorOperations.SelectAndMoveCaret(point, point, TextSelectionMode.Stream, EnsureSpanVisibleOptions.AlwaysCenter); return; } var insertionPoints = InsertionPointService.GetInsertionPoints( editor, model, type, part.SourceSpan.Start ); var options = new InsertionModeOptions( operation, insertionPoints, point => { if (!point.Success) { return; } var text = node.ToString(); point.InsertionPoint.Insert(editor, doc.DocumentContext, text); } ); editor.StartInsertionMode(options); }); }
public static async Task InsertMemberWithCursor(string operation, Projects.Project project, ITypeSymbol type, Location part, SyntaxNode newMember, CancellationToken cancellationToken = default(CancellationToken)) { if (operation == null) { throw new ArgumentNullException(nameof(operation)); } if (project == null) { throw new ArgumentNullException(nameof(project)); } if (type == null) { throw new ArgumentNullException(nameof(type)); } if (newMember == null) { throw new ArgumentNullException(nameof(newMember)); } var doc = await IdeApp.Workbench.OpenDocument(part.SourceTree.FilePath, project, true); await doc.UpdateParseDocument(); var document = doc.AnalysisDocument; if (document == null) { LoggingService.LogError("Can't find document to insert member (fileName:" + part.SourceTree.FilePath + ")"); return; } var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var typeDecl = (ClassDeclarationSyntax)root.FindNode(part.SourceSpan); // for some reason the reducer doesn't reduce this var systemVoid = newMember.DescendantNodesAndSelf().OfType <QualifiedNameSyntax> ().FirstOrDefault(ma => ma.ToString() == "System.Void"); if (systemVoid != null) { newMember = newMember.ReplaceNode(systemVoid, SyntaxFactory.ParseTypeName("void")); } var newRoot = root.ReplaceNode(typeDecl, typeDecl.AddMembers((MemberDeclarationSyntax)newMember.WithAdditionalAnnotations(Simplifier.Annotation, Formatter.Annotation, insertedMemberAnnotation))); var policy = project.Policies.Get <CSharpFormattingPolicy> ("text/x-csharp"); var textPolicy = project.Policies.Get <TextStylePolicy> ("text/x-csharp"); var projectOptions = policy.CreateOptions(textPolicy); document = document.WithSyntaxRoot(newRoot); document = await Formatter.FormatAsync(document, Formatter.Annotation, projectOptions, cancellationToken).ConfigureAwait(false); document = await Simplifier.ReduceAsync(document, Simplifier.Annotation, projectOptions, cancellationToken).ConfigureAwait(false); root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var node = root.GetAnnotatedNodes(insertedMemberAnnotation).Single(); Application.Invoke(async(o, args) => { var insertionPoints = InsertionPointService.GetInsertionPoints( doc.Editor, await doc.UpdateParseDocument(), type, part.SourceSpan.Start ); var options = new InsertionModeOptions( operation, insertionPoints, point => { if (!point.Success) { return; } var text = node.ToString(); point.InsertionPoint.Insert(doc.Editor, doc, text); } ); doc.Editor.StartInsertionMode(options); }); }
internal async void Run() { var token = default(CancellationToken); var insertionAction = act as InsertionAction; if (insertionAction != null) { var insertion = await insertionAction.CreateInsertion(token).ConfigureAwait(false); var document = IdeApp.Workbench.OpenDocument(insertion.Location.SourceTree.FilePath, documentContext.Project); var parsedDocument = await document.UpdateParseDocument(); if (parsedDocument != null) { var insertionPoints = InsertionPointService.GetInsertionPoints( document.Editor, parsedDocument, insertion.Type, insertion.Location.SourceSpan.Start ); var options = new InsertionModeOptions( insertionAction.Title, insertionPoints, point => { if (!point.Success) { return; } var node = Formatter.Format(insertion.Node, TypeSystemService.Workspace, document.GetOptionSet(), token); point.InsertionPoint.Insert(document.Editor, document, node.ToString()); // document = await Simplifier.ReduceAsync(document.AnalysisDocument, Simplifier.Annotation, cancellationToken: token).ConfigureAwait(false); } ); document.Editor.StartInsertionMode(options); return; } } var oldSolution = documentContext.AnalysisDocument.Project.Solution; var updatedSolution = oldSolution; if (RefactoringService.OptionSetCreation != null) { documentContext.RoslynWorkspace.Options = RefactoringService.OptionSetCreation(editor, documentContext); } using (var undo = editor.OpenUndoGroup()) { foreach (var operation in act.GetOperationsAsync(token).Result) { var applyChanges = operation as ApplyChangesOperation; if (applyChanges == null) { operation.Apply(documentContext.RoslynWorkspace, token); continue; } if (updatedSolution == oldSolution) { updatedSolution = applyChanges.ChangedSolution; } operation.Apply(documentContext.RoslynWorkspace, token); } } TryStartRenameSession(documentContext.RoslynWorkspace, oldSolution, updatedSolution, token); }
public override async Task <CompletionChange> GetChangeAsync(Document doc, CompletionItem item, char?commitKey = default(char?), CancellationToken cancellationToken = default(CancellationToken)) { (string beforeText, string afterText, string newMethod) = await GetInsertText(item.Properties); TextChange change; if (newMethod != null && RoslynCompletionData.RequestInsertText) // check for completion window manager to prevent the insertion cursor popup when the changes are queried by code diagnostics. { change = new TextChange(new TextSpan(item.Span.Start, item.Span.Length), item.Properties [MethodNameKey] + ";"); var semanticModel = await doc.GetSemanticModelAsync(cancellationToken); if (!doc.IsOpen() || await doc.IsForkedDocumentWithSyntaxChangesAsync(cancellationToken)) { return(CompletionChange.Create(change)); } var document = IdeApp.Workbench.ActiveDocument; var editor = document.Editor; void StartInsertionMode() { if (editor.EditMode != EditMode.Edit) { return; } var parsedDocument = document.DocumentContext.ParsedDocument; var declaringType = semanticModel.GetEnclosingSymbolMD <INamedTypeSymbol> (item.Span.Start, default(CancellationToken)); var insertionPoints = InsertionPointService.GetInsertionPoints( document.Editor, semanticModel, declaringType, editor.CaretOffset ); var options = new InsertionModeOptions( GettextCatalog.GetString("Create new method"), insertionPoints, point => { if (!point.Success) { return; } point.InsertionPoint.Insert(document.Editor, document.DocumentContext, newMethod); } ); editor.StartInsertionMode(options); } if (editor.TextView is Microsoft.VisualStudio.Text.Editor.IMdTextView) { await Runtime.RunInMainThread(StartInsertionMode); } else { StartInsertionMode(); } return(CompletionChange.Create(change)); } change = new TextChange(new TextSpan(item.Span.Start, item.Span.Length), beforeText + afterText); return(CompletionChange.Create(change, item.Span.Start + (beforeText != null ? beforeText.Length : 0))); }