public void ExtensionReference() { using (var app = new PythonVisualStudioApp()) { var project = app.OpenProject(@"TestData\ExtensionReference.sln"); app.OpenSolutionExplorer(); var solutionTree = app.SolutionExplorerTreeView; var dbPath = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Python Tools", "ReferencesDB", #if DEBUG "Debug", #endif AssemblyVersionInfo.VSVersion ); var existingFiles = Directory.GetFiles(dbPath, "spam*"); // open the solution, add a reference to our spam.pyd Python extension module var folderNode = solutionTree.FindItem( "Solution 'ExtensionReference' (1 project)", "ExtensionReference", SR.GetString(SR.ReferencesNodeName) ); folderNode.Select(); var dialog = new AddReferenceDialog(AutomationElement.FromHandle(app.OpenDialogWithDteExecuteCommand("Project.AddReference"))); dialog.ActivateBrowseTab(); dialog.BrowseFilename = TestData.GetPath(@"TestData\spam.pyd"); dialog.ClickOK(); app.WaitForDialogDismissed(); // make sure the reference got added var spamItem = solutionTree.WaitForItem( "Solution 'ExtensionReference' (1 project)", "ExtensionReference", SR.GetString(SR.ReferencesNodeName), "spam.pyd" ); Assert.IsNotNull(spamItem); // wait for scraping to complete for (int retries = 10; Directory.GetFiles(dbPath, "spam*").Length == existingFiles.Length && retries > 0; --retries) { System.Threading.Thread.Sleep(1000); } Assert.AreNotEqual(existingFiles.Length, Directory.GetFiles(dbPath, "spam*").Length, "File was not scraped"); // now open a file and make sure we get completions against the spam module var item = project.ProjectItems.Item("Program.py"); var window = item.Open(); window.Activate(); var doc = app.GetDocument(item.Document.FullName); doc.MoveCaret(doc.TextView.TextBuffer.CurrentSnapshot.GetLineFromLineNumber(1).Start); Keyboard.Type("spam."); using (var sh = doc.WaitForSession <ICompletionSession>()) { var completion = sh.Session.CompletionSets.First().Completions.Select(x => x.InsertionText).FirstOrDefault(x => x == "system"); Assert.IsNotNull(completion); } // now clear the text we just typed for (int i = 0; i < 5; i++) { Keyboard.Type(Key.Back); } // remove the extension app.Dte.Solution.Projects.Item(1).ProjectItems.Item("References").ProjectItems.Item(@"spam.pyd").Remove(); // make sure it got removed solutionTree.WaitForItemRemoved( "Solution 'ExtensionReference' (1 project)", "ExtensionReference", SR.GetString(SR.ReferencesNodeName), "spam.pyd" ); window.Activate(); // and make sure we no longer offer completions on the spam module. Keyboard.Type("spam."); using (var sh = doc.WaitForSession <ICompletionSession>()) { var completion = sh.Session.CompletionSets.First().Completions.Select(x => x.DisplayText).Single(); Assert.AreEqual(SR.GetString(SR.NoCompletionsCompletion), completion); } } }
protected override void Run() { DotNetProject project = IdeApp.ProjectOperations.CurrentSelectedProject as DotNetProject; var dotNetProjectProxy = new DotNetProjectProxy(project); if (project == null) { return; } INativeTypesHandler nativeTypesHandler = null; //SupportedLanguage names currently returns an empty item and the 'languageName' the DotNetProject //is initialized with. This might be an array to enable extension for other projects? DotNetProject //only returns an empty and languageName. See source link. // https://github.com/mono/monodevelop/blob/dcafac668cbe8f63b4e42ea7f8f032f13aba8221/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs#L198 if (project.SupportedLanguages.Contains("C#")) { nativeTypesHandler = NativeTypeHandlers.CSharpNativeTypesHandler; } if (project.SupportedLanguages.Contains("F#")) { nativeTypesHandler = NativeTypeHandlers.FSharpNativeTypesHandler; } if (project.SupportedLanguages.Contains("VBNet")) { nativeTypesHandler = NativeTypeHandlers.VbNetNativeTypesHandler; } if (nativeTypesHandler == null) { throw new ArgumentNullException("No supported languages found"); } string fileName = "ServiceReference"; int count = 0; bool exists = true; while (exists) { count++; var existingFile = project.Files.FirstOrDefault(x => x.FilePath.FileName == fileName + count.ToString() + nativeTypesHandler.CodeFileExtension); exists = existingFile != null; } var dialog = new AddReferenceDialog(fileName + count.ToString(), nativeTypesHandler); dialog.Run(); string finalFileName = dialog.ReferenceName + nativeTypesHandler.CodeFileExtension; string code = dialog.CodeTemplate; dialog.Destroy(); if (!dialog.AddReferenceSucceeded) { return; } IdeApp.Workbench.StatusBar.ShowReady(); IdeApp.Workbench.StatusBar.ShowMessage("Adding ServiceStack Reference..."); IdeApp.Workbench.StatusBar.Pulse(); string fullPath = Path.Combine(project.BaseDirectory.FullPath.ToString(), finalFileName); using (var streamWriter = File.CreateText(fullPath)) { streamWriter.Write(code); streamWriter.Flush(); } project.AddFile(fullPath, BuildAction.Compile); try { Task.Run(() => { AddNuGetPackageReference(dotNetProjectProxy, "ServiceStack.Client"); AddNuGetPackageReference(dotNetProjectProxy, "ServiceStack.Interfaces"); AddNuGetPackageReference(dotNetProjectProxy, "ServiceStack.Text"); }).ContinueWith(task => { IdeApp.Workbench.StatusBar.ShowReady(); IdeApp.Workbench.StatusBar.Pulse(); }, TaskScheduler.FromCurrentSynchronizationContext()); } catch (Exception ex) { //TODO Error message for user var messageDialog = new MessageDialog( (Gtk.Window)IdeApp.Workbench.RootWindow.Toplevel, DialogFlags.Modal, MessageType.Warning, ButtonsType.Close, "An error occurred trying to add required NuGet packages. Error : " + ex.Message + "\r\n\r\nGenerated service reference will require ServiceStack.Interfaces as a minimum."); messageDialog.Run(); messageDialog.Destroy(); IdeApp.Workbench.StatusBar.ShowReady(); IdeApp.Workbench.StatusBar.Pulse(); } }
protected override void Run() { DotNetProject project = IdeApp.ProjectOperations.CurrentSelectedProject as DotNetProject; var dotNetProjectProxy = new DotNetProjectProxy (project); if (project == null) { return; } INativeTypesHandler nativeTypesHandler = null; //SupportedLanguage names currently returns an empty item and the 'languageName' the DotNetProject //is initialized with. This might be an array to enable extension for other projects? DotNetProject //only returns an empty and languageName. See source link. // https://github.com/mono/monodevelop/blob/dcafac668cbe8f63b4e42ea7f8f032f13aba8221/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs#L198 if (project.SupportedLanguages.Contains ("C#")) { nativeTypesHandler = NativeTypeHandlers.CSharpNativeTypesHandler; } if (project.SupportedLanguages.Contains ("F#")) { nativeTypesHandler = NativeTypeHandlers.FSharpNativeTypesHandler; } if (project.SupportedLanguages.Contains ("VBNet")) { nativeTypesHandler = NativeTypeHandlers.VbNetNativeTypesHandler; } if (nativeTypesHandler == null) { throw new ArgumentNullException ("No supported languages found"); } string fileName = "ServiceReference"; int count = 0; bool exists = true; while (exists) { count++; var existingFile = project.Files.FirstOrDefault (x => x.FilePath.FileName == fileName + count.ToString () + nativeTypesHandler.CodeFileExtension); exists = existingFile != null; } var dialog = new AddReferenceDialog (fileName + count.ToString (), nativeTypesHandler); dialog.Run (); string finalFileName = dialog.ReferenceName + nativeTypesHandler.CodeFileExtension; string code = dialog.CodeTemplate; dialog.Destroy (); if (!dialog.AddReferenceSucceeded) { return; } IdeApp.Workbench.StatusBar.ShowReady (); IdeApp.Workbench.StatusBar.ShowMessage ("Adding ServiceStack Reference..."); IdeApp.Workbench.StatusBar.Pulse (); string fullPath = Path.Combine (project.BaseDirectory.FullPath.ToString (), finalFileName); using (var streamWriter = File.CreateText (fullPath)) { streamWriter.Write (code); streamWriter.Flush (); } project.AddFile (fullPath, BuildAction.Compile); try { Task.Run (() => { AddNuGetPackageReference (dotNetProjectProxy, "ServiceStack.Client"); AddNuGetPackageReference (dotNetProjectProxy, "ServiceStack.Interfaces"); AddNuGetPackageReference (dotNetProjectProxy, "ServiceStack.Text"); }).ContinueWith (task => { IdeApp.Workbench.StatusBar.Pulse (); IdeApp.Workbench.StatusBar.ShowReady (); },TaskScheduler.FromCurrentSynchronizationContext ()); } catch (Exception ex) { //TODO Error message for user var messageDialog = new MessageDialog ( (Gtk.Window)IdeApp.Workbench.RootWindow.Toplevel, DialogFlags.Modal, MessageType.Warning, ButtonsType.Close, "An error occurred trying to add required NuGet packages. Error : " + ex.Message + "\r\n\r\nGenerated service reference will require ServiceStack.Interfaces as a minimum."); messageDialog.Run (); messageDialog.Destroy (); } }