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); }
static async Task TestInsertionPoints(string text) { var tww = new TestWorkbenchWindow(); var content = new TestViewContent(); tww.ViewContent = content; content.ContentName = "/a.cs"; content.Data.MimeType = "text/x-csharp"; MonoDevelop.AnalysisCore.AnalysisOptions.EnableUnitTestEditorIntegration.Set(true); var doc = new MonoDevelop.Ide.Gui.Document(tww); var data = doc.Editor; List <InsertionPoint> loc = new List <InsertionPoint> (); for (int i = 0; i < text.Length; i++) { char ch = text [i]; if (ch == '@') { i++; ch = text [i]; NewLineInsertion insertBefore = NewLineInsertion.None; NewLineInsertion insertAfter = NewLineInsertion.None; switch (ch) { case 'n': break; case 'd': insertAfter = NewLineInsertion.Eol; break; case 'D': insertAfter = NewLineInsertion.BlankLine; break; case 'u': insertBefore = NewLineInsertion.Eol; break; case 'U': insertBefore = NewLineInsertion.BlankLine; break; case 's': insertBefore = insertAfter = NewLineInsertion.Eol; break; case 'S': insertBefore = insertAfter = NewLineInsertion.BlankLine; break; case 't': insertBefore = NewLineInsertion.Eol; insertAfter = NewLineInsertion.BlankLine; break; case 'T': insertBefore = NewLineInsertion.None; insertAfter = NewLineInsertion.BlankLine; break; case 'v': insertBefore = NewLineInsertion.BlankLine; insertAfter = NewLineInsertion.Eol; break; case 'V': insertBefore = NewLineInsertion.None; insertAfter = NewLineInsertion.Eol; break; default: Assert.Fail("unknown insertion point:" + ch); break; } var vv = data.OffsetToLocation(data.Length); loc.Add(new InsertionPoint(new DocumentLocation(vv.Line, vv.Column), insertBefore, insertAfter)); } else { data.InsertText(data.Length, ch.ToString()); } } var project = Services.ProjectService.CreateProject("C#"); project.Name = "test"; project.FileName = "test.csproj"; project.Files.Add(new ProjectFile("/a.cs", BuildAction.Compile)); var solution = new MonoDevelop.Projects.Solution(); solution.AddConfiguration("", true); solution.DefaultSolutionFolder.AddItem(project); using (var monitor = new ProgressMonitor()) await TypeSystemService.Load(solution, monitor); content.Project = project; doc.SetProject(project); var parsedFile = await doc.UpdateParseDocument(); var model = parsedFile.GetAst <SemanticModel> (); var sym = model?.GetEnclosingSymbol(data.Text.IndexOf('{')); var type = sym as INamedTypeSymbol ?? sym?.ContainingType; if (type != null) { var foundPoints = InsertionPointService.GetInsertionPoints(doc.Editor, parsedFile, type, type.Locations.First()); Assert.AreEqual(loc.Count, foundPoints.Count, "point count doesn't match"); for (int i = 0; i < loc.Count; i++) { Assert.AreEqual(loc [i].Location, foundPoints [i].Location, "point " + i + " doesn't match"); Assert.AreEqual(loc [i].LineAfter, foundPoints [i].LineAfter, "point " + i + " ShouldInsertNewLineAfter doesn't match"); Assert.AreEqual(loc [i].LineBefore, foundPoints [i].LineBefore, "point " + i + " ShouldInsertNewLineBefore doesn't match"); } } TypeSystemService.Unload(solution); }
async Task TestInsertionPoints(string text) { MonoDevelop.AnalysisCore.AnalysisOptions.EnableUnitTestEditorIntegration.Set(true); using (var testCase = await SetupTestCase("")) { var doc = testCase.Document; var data = doc.Editor; List <InsertionPoint> loc = new List <InsertionPoint> (); for (int i = 0; i < text.Length; i++) { char ch = text [i]; if (ch == '@') { i++; ch = text [i]; NewLineInsertion insertBefore = NewLineInsertion.None; NewLineInsertion insertAfter = NewLineInsertion.None; switch (ch) { case 'n': break; case 'd': insertAfter = NewLineInsertion.Eol; break; case 'D': insertAfter = NewLineInsertion.BlankLine; break; case 'u': insertBefore = NewLineInsertion.Eol; break; case 'U': insertBefore = NewLineInsertion.BlankLine; break; case 's': insertBefore = insertAfter = NewLineInsertion.Eol; break; case 'S': insertBefore = insertAfter = NewLineInsertion.BlankLine; break; case 't': insertBefore = NewLineInsertion.Eol; insertAfter = NewLineInsertion.BlankLine; break; case 'T': insertBefore = NewLineInsertion.None; insertAfter = NewLineInsertion.BlankLine; break; case 'v': insertBefore = NewLineInsertion.BlankLine; insertAfter = NewLineInsertion.Eol; break; case 'V': insertBefore = NewLineInsertion.None; insertAfter = NewLineInsertion.Eol; break; default: Assert.Fail("unknown insertion point:" + ch); break; } var vv = data.OffsetToLocation(data.Length); loc.Add(new InsertionPoint(new DocumentLocation(vv.Line, vv.Column), insertBefore, insertAfter)); } else { data.InsertText(data.Length, ch.ToString()); } } var model = await doc.AnalysisDocument.GetSemanticModelAsync(); var sym = model?.GetEnclosingSymbol(data.Text.IndexOf('{')); var type = sym as INamedTypeSymbol ?? sym?.ContainingType; if (type != null) { var foundPoints = InsertionPointService.GetInsertionPoints(doc.Editor, model, type, type.Locations.First()); Assert.AreEqual(loc.Count, foundPoints.Count, "point count doesn't match"); for (int i = 0; i < loc.Count; i++) { Assert.AreEqual(loc [i].Location, foundPoints [i].Location, "point " + i + " doesn't match"); Assert.AreEqual(loc [i].LineAfter, foundPoints [i].LineAfter, "point " + i + " ShouldInsertNewLineAfter doesn't match"); Assert.AreEqual(loc [i].LineBefore, foundPoints [i].LineBefore, "point " + i + " ShouldInsertNewLineBefore doesn't match"); } } } }
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))); }