diff options
author | David Karlaš <david.karlas@xamarin.com> | 2017-03-07 17:28:34 +0300 |
---|---|---|
committer | David Karlaš <david.karlas@xamarin.com> | 2017-03-07 17:28:34 +0300 |
commit | 41e227d8187ee05a3496375d514bcb08b9b8de6b (patch) | |
tree | de01a949df06bba86b783bb7ca46550d3bc88cd6 /main/src | |
parent | a11ede7183f77eaca433a9bffabafb940f9594ff (diff) | |
parent | aa201bd070d1e1aa9f09dfe5b7a46f5573870a13 (diff) |
Merge vNext into roslyn-ivt
# Conflicts:
# main/external/debugger-libs
# main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.csproj
# main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionEditorExtension.cs
# main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj
# main/src/core/MonoDevelop.Ide/packages.config
# version-checks
Diffstat (limited to 'main/src')
148 files changed, 3397 insertions, 1241 deletions
diff --git a/main/src/addins/CSharpBinding/CSharpBinding.addin.xml b/main/src/addins/CSharpBinding/CSharpBinding.addin.xml index ba66641c3a..12e2e3c658 100644 --- a/main/src/addins/CSharpBinding/CSharpBinding.addin.xml +++ b/main/src/addins/CSharpBinding/CSharpBinding.addin.xml @@ -304,7 +304,6 @@ <CommandItem id = "MonoDevelop.Refactoring.RefactoryCommands.CurrentRefactoryOperations" insertafter="MonoDevelop.SourceEditor.SourceEditorCommands.MarkerOperations" insertbefore="MonoDevelop.Debugger.DebugCommands.ExpressionEvaluator"/> <ItemSet id = "Navigate" _label = "Navigate"> - <CommandItem id = "MonoDevelop.Refactoring.RefactoryCommands.FindReferences"/> <CommandItem id = "MonoDevelop.Refactoring.RefactoryCommands.FindAllReferences"/> <CommandItem id = "MonoDevelop.Refactoring.Navigation.FindBaseSymbols"/> <CommandItem id = "MonoDevelop.Refactoring.Navigation.FindDerivedSymbols"/> diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/ParameterHinting/ParameterHintingEngine.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/ParameterHinting/ParameterHintingEngine.cs index eac4717c9a..eaf91272a6 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/ParameterHinting/ParameterHintingEngine.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/ParameterHinting/ParameterHintingEngine.cs @@ -283,11 +283,18 @@ namespace ICSharpCode.NRefactory6.CSharp.Completion { var info = semanticModel.GetSymbolInfo(node, cancellationToken); var result = new ParameterHintingResult(node.SpanStart); - var resolvedMethod = info.Symbol as IMethodSymbol; - if (resolvedMethod != null) - result.AddData(factory.CreateConstructorProvider(resolvedMethod)); - result.AddRange(info.CandidateSymbols.OfType<IMethodSymbol>().Select (factory.CreateConstructorProvider)); + if (resolvedMethod != null) { + var type = resolvedMethod.ContainingType; + var within = semanticModel.GetEnclosingNamedTypeOrAssembly (node.SpanStart, cancellationToken); + + result.AddRange (type.GetMembers () + .OfType<IMethodSymbol> () + .Where (m => m.MethodKind == MethodKind.Constructor && m.IsAccessibleWithin (within)) + .Select (factory.CreateConstructorProvider)); + } else { + result.AddRange (info.CandidateSymbols.OfType<IMethodSymbol> ().Select (factory.CreateConstructorProvider)); + } return result; } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/CSharpTextPasteHandler.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/CSharpTextPasteHandler.cs index 8f74d3ce58..7417da5707 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/CSharpTextPasteHandler.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/CSharpTextPasteHandler.cs @@ -29,6 +29,8 @@ using MonoDevelop.Ide.Editor; using MonoDevelop.Ide.CodeCompletion; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Text; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Formatting; namespace MonoDevelop.CSharp.Formatting { @@ -53,22 +55,22 @@ namespace MonoDevelop.CSharp.Formatting return engine.GetCopyData (indent.Editor, new TextSpan (offset, length)); } - public override void PostFomatPastedText (int insertionOffset, int insertedChars) + public override async Task PostFomatPastedText (int insertionOffset, int insertedChars) { if (indent.Editor.Options.IndentStyle == IndentStyle.None || indent.Editor.Options.IndentStyle == IndentStyle.Auto) return; if (DefaultSourceEditorOptions.Instance.OnTheFlyFormatting) { + var tree = await indent.DocumentContext.AnalysisDocument.GetSyntaxTreeAsync (); int lineStartOffset = indent.Editor.GetLineByOffset (insertionOffset).Offset; - int formatCharsCount = insertedChars + (lineStartOffset - insertionOffset); - var newText = CSharpFormatter.FormatText ( - indent.DocumentContext.GetFormattingPolicy (), - indent.DocumentContext.Project.Policies.Get<Ide.Gui.Content.TextStylePolicy> (), - indent.Editor.GetTextBetween (lineStartOffset, insertionOffset + insertedChars), - 0, - formatCharsCount - ); - indent.Editor.ReplaceText (lineStartOffset, formatCharsCount, newText); + int formatCharsCount = insertedChars + (insertionOffset - lineStartOffset); + var policy = indent.DocumentContext.GetFormattingPolicy (); + var textPolicy = indent.DocumentContext.Project.Policies.Get<Ide.Gui.Content.TextStylePolicy> (); + var optionSet = policy.CreateOptions (textPolicy); + var span = new TextSpan (lineStartOffset, formatCharsCount); + var doc = await Formatter.FormatAsync (indent.DocumentContext.AnalysisDocument, span, optionSet); + + OnTheFlyFormatter.ApplyNewTree (indent.Editor, lineStartOffset, true, span, tree, await doc.GetSyntaxTreeAsync ()); return; } // Just correct the start line of the paste operation - the text is already indented. @@ -79,7 +81,6 @@ namespace MonoDevelop.CSharp.Formatting int pos = curLineOffset; string curIndent = curLine.GetIndentation (indent.Editor); int nlwsp = curIndent.Length; - if (!indent.stateTracker.LineBeganInsideMultiLineComment || (nlwsp < curLine.LengthIncludingDelimiter && indent.Editor.GetCharAt (curLineOffset + nlwsp) == '*')) { // Possibly replace the indent indent.SafeUpdateIndentEngine (curLineOffset + curLine.Length); diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/OnTheFlyFormatter.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/OnTheFlyFormatter.cs index ce7ebe7a22..0484a14ac2 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/OnTheFlyFormatter.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/OnTheFlyFormatter.cs @@ -101,44 +101,52 @@ namespace MonoDevelop.CSharp.Formatting } var doc = Formatter.FormatAsync (analysisDocument, span, optionSet).Result; var newTree = doc.GetSyntaxTreeAsync ().Result; - var caretOffset = editor.CaretOffset; - var caretEndOffset = caretOffset; + ApplyNewTree (editor, startOffset, exact, span, syntaxTree, newTree); + } catch (Exception e) { + LoggingService.LogError ("Error in on the fly formatter", e); + } + } + } - int delta = 0; - foreach (var change in newTree.GetChanges (syntaxTree)) { - if (!exact && change.Span.Start >= caretOffset) - continue; - if (exact && !span.Contains (change.Span.Start)) - continue; - var newText = change.NewText; - var length = change.Span.Length; - var changeEnd = delta + change.Span.End - 1; - if (changeEnd < editor.Length && changeEnd >= 0 && editor.GetCharAt (changeEnd) == '\r') - length--; - var replaceOffset = delta + change.Span.Start; - editor.ReplaceText (replaceOffset, length, newText); - delta = delta - length + newText.Length; - if (change.Span.Start < caretOffset) { - if (change.Span.End < caretOffset) { - caretEndOffset += newText.Length - length; - } else { - caretEndOffset = replaceOffset; - } - } - } - if (startOffset < caretOffset) { - if (0 <= caretEndOffset && caretEndOffset < editor.Length) - editor.CaretOffset = caretEndOffset; - if (editor.CaretColumn == 1) { - if (editor.CaretLine > 1 && editor.GetLine (editor.CaretLine - 1).Length == 0) - editor.CaretLine--; - editor.CaretColumn = editor.GetVirtualIndentationColumn (editor.CaretLine); + internal static void ApplyNewTree (TextEditor editor, int startOffset, bool exact, TextSpan span, Microsoft.CodeAnalysis.SyntaxTree syntaxTree, Microsoft.CodeAnalysis.SyntaxTree newTree) + { + var caretOffset = editor.CaretOffset; + var caretEndOffset = caretOffset; + using (var undo = editor.OpenUndoGroup ()) { + + int delta = 0; + foreach (var change in newTree.GetChanges (syntaxTree)) { + if (!exact && change.Span.Start >= caretOffset) + continue; + if (exact && !span.Contains (change.Span.Start)) + continue; + var newText = change.NewText; + var length = change.Span.Length; + var changeEnd = delta + change.Span.End - 1; + if (changeEnd < editor.Length && changeEnd >= 0 && editor.GetCharAt (changeEnd) == '\r') + length--; + var replaceOffset = delta + change.Span.Start; + editor.ReplaceText (replaceOffset, length, newText); + delta = delta - length + newText.Length; + if (change.Span.Start < caretOffset) { + if (change.Span.End < caretOffset) { + caretEndOffset += newText.Length - length; + } else { + caretEndOffset = replaceOffset; } } - } catch (Exception e) { - LoggingService.LogError ("Error in on the fly formatter", e); + } + } + + if (startOffset < caretOffset) { + if (0 <= caretEndOffset && caretEndOffset < editor.Length) + editor.CaretOffset = caretEndOffset; + if (editor.CaretColumn == 1) { + if (editor.CaretLine > 1 && editor.GetLine (editor.CaretLine - 1).Length == 0) + editor.CaretLine--; + editor.CaretColumn = editor.GetVirtualIndentationColumn (editor.CaretLine); } } } - } +} } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/CSharpFindReferencesProvider.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/CSharpFindReferencesProvider.cs index 1046132837..d230e2edef 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/CSharpFindReferencesProvider.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/CSharpFindReferencesProvider.cs @@ -205,64 +205,55 @@ namespace MonoDevelop.CSharp.Refactoring return Task.Run (async delegate { var result = new List<SearchResult> (); var antiDuplicatesSet = new HashSet<SearchResult> (new SearchResultComparer ()); - foreach (var workspace in TypeSystemService.AllWorkspaces.OfType<MonoDevelopWorkspace> ()) { - LookupResult lookup = null; - - foreach (var project in workspace.CurrentSolution.Projects) { - if (token.IsCancellationRequested) - return result; - - lookup = await TryLookupSymbolInProject (project, documentationCommentId, token); - if (lookup.Success) - break; - } + var lookup = await TryLookupSymbol (documentationCommentId, hintProject, token); + if (lookup == null || !lookup.Success) + return Enumerable.Empty<SearchResult> (); + + var workspace = TypeSystemService.AllWorkspaces.FirstOrDefault (w => w.CurrentSolution == lookup.Solution) as MonoDevelopWorkspace; + if (workspace == null) + return Enumerable.Empty<SearchResult> (); - if (lookup == null || !lookup.Success) { + foreach (var loc in lookup.Symbol.Locations) { + if (token.IsCancellationRequested) + break; + + if (!loc.IsInSource) continue; + var fileName = loc.SourceTree.FilePath; + var offset = loc.SourceSpan.Start; + string projectedName; + int projectedOffset; + if (workspace.TryGetOriginalFileFromProjection (fileName, offset, out projectedName, out projectedOffset)) { + fileName = projectedName; + offset = projectedOffset; } + var sr = new MemberReference (lookup.Symbol, fileName, offset, loc.SourceSpan.Length); + sr.ReferenceUsageType = ReferenceUsageType.Declariton; + antiDuplicatesSet.Add (sr); + result.Add (sr); + } - foreach (var loc in lookup.Symbol.Locations) { + foreach (var mref in await SymbolFinder.FindReferencesAsync (lookup.Symbol, lookup.Solution, token).ConfigureAwait (false)) { + foreach (var loc in mref.Locations) { if (token.IsCancellationRequested) break; - - if (!loc.IsInSource) - continue; - var fileName = loc.SourceTree.FilePath; - var offset = loc.SourceSpan.Start; + var fileName = loc.Document.FilePath; + var offset = loc.Location.SourceSpan.Start; string projectedName; int projectedOffset; if (workspace.TryGetOriginalFileFromProjection (fileName, offset, out projectedName, out projectedOffset)) { fileName = projectedName; offset = projectedOffset; } - var sr = new MemberReference (lookup.Symbol, fileName, offset, loc.SourceSpan.Length); - sr.ReferenceUsageType = ReferenceUsageType.Declariton; - antiDuplicatesSet.Add (sr); - result.Add (sr); - } + var sr = new MemberReference (lookup.Symbol, fileName, offset, loc.Location.SourceSpan.Length); - foreach (var mref in await SymbolFinder.FindReferencesAsync (lookup.Symbol, lookup.Solution, token).ConfigureAwait (false)) { - foreach (var loc in mref.Locations) { - if (token.IsCancellationRequested) - break; - var fileName = loc.Document.FilePath; - var offset = loc.Location.SourceSpan.Start; - string projectedName; - int projectedOffset; - if (workspace.TryGetOriginalFileFromProjection (fileName, offset, out projectedName, out projectedOffset)) { - fileName = projectedName; - offset = projectedOffset; - } - var sr = new MemberReference (lookup.Symbol, fileName, offset, loc.Location.SourceSpan.Length); - - if (antiDuplicatesSet.Add (sr)) { - var root = loc.Location.SourceTree.GetRoot (); - var node = root.FindNode (loc.Location.SourceSpan); - var trivia = root.FindTrivia (loc.Location.SourceSpan.Start); - sr.ReferenceUsageType = HighlightUsagesExtension.GetUsage (node); - result.Add (sr); - } + if (antiDuplicatesSet.Add (sr)) { + var root = loc.Location.SourceTree.GetRoot (); + var node = root.FindNode (loc.Location.SourceSpan); + var trivia = root.FindTrivia (loc.Location.SourceSpan.Start); + sr.ReferenceUsageType = HighlightUsagesExtension.GetUsage (node); + result.Add (sr); } } } @@ -272,40 +263,41 @@ namespace MonoDevelop.CSharp.Refactoring public override Task<IEnumerable<SearchResult>> FindAllReferences (string documentationCommentId, MonoDevelop.Projects.Project hintProject, CancellationToken token) { - var workspace = TypeSystemService.Workspace as MonoDevelopWorkspace; - if (workspace == null) - return Task.FromResult (Enumerable.Empty<SearchResult> ()); return Task.Run (async delegate { var antiDuplicatesSet = new HashSet<SearchResult> (new SearchResultComparer ()); var result = new List<SearchResult> (); var lookup = await TryLookupSymbol (documentationCommentId, hintProject, token); if (!lookup.Success) return result; - - foreach (var simSym in SymbolFinder.FindSimilarSymbols (lookup.Symbol, lookup.Compilation)) { - foreach (var loc in simSym.Locations) { - if (!loc.IsInSource) - continue; - var sr = new SearchResult (new FileProvider (loc.SourceTree.FilePath), loc.SourceSpan.Start, loc.SourceSpan.Length); - if (antiDuplicatesSet.Add (sr)) { - result.Add (sr); + var workspace = TypeSystemService.AllWorkspaces.FirstOrDefault (w => w.CurrentSolution == lookup.Solution) as MonoDevelopWorkspace; + if (workspace == null) + return Enumerable.Empty<SearchResult> (); + foreach (var curSymbol in lookup.Symbol.ContainingType.GetMembers ().Where (m => m.Kind == lookup.Symbol.Kind && m.Name == lookup.Symbol.Name)) { + foreach (var simSym in SymbolFinder.FindSimilarSymbols (curSymbol, lookup.Compilation)) { + foreach (var loc in simSym.Locations) { + if (!loc.IsInSource) + continue; + var sr = new SearchResult (new FileProvider (loc.SourceTree.FilePath), loc.SourceSpan.Start, loc.SourceSpan.Length); + if (antiDuplicatesSet.Add (sr)) { + result.Add (sr); + } } - } - foreach (var mref in await SymbolFinder.FindReferencesAsync (simSym, lookup.Solution).ConfigureAwait (false)) { - foreach (var loc in mref.Locations) { - var fileName = loc.Document.FilePath; - var offset = loc.Location.SourceSpan.Start; - string projectedName; - int projectedOffset; - if (workspace.TryGetOriginalFileFromProjection (fileName, offset, out projectedName, out projectedOffset)) { - fileName = projectedName; - offset = projectedOffset; - } + foreach (var mref in await SymbolFinder.FindReferencesAsync (simSym, lookup.Solution).ConfigureAwait (false)) { + foreach (var loc in mref.Locations) { + var fileName = loc.Document.FilePath; + var offset = loc.Location.SourceSpan.Start; + string projectedName; + int projectedOffset; + if (workspace.TryGetOriginalFileFromProjection (fileName, offset, out projectedName, out projectedOffset)) { + fileName = projectedName; + offset = projectedOffset; + } - var sr = new SearchResult (new FileProvider (fileName), offset, loc.Location.SourceSpan.Length); - if (antiDuplicatesSet.Add (sr)) { - result.Add (sr); + var sr = new SearchResult (new FileProvider (fileName), offset, loc.Location.SourceSpan.Length); + if (antiDuplicatesSet.Add (sr)) { + result.Add (sr); + } } } } diff --git a/main/src/addins/MacPlatform/MainToolbar/SelectorView.cs b/main/src/addins/MacPlatform/MainToolbar/SelectorView.cs index 518f247cad..8ae54fe72d 100644 --- a/main/src/addins/MacPlatform/MainToolbar/SelectorView.cs +++ b/main/src/addins/MacPlatform/MainToolbar/SelectorView.cs @@ -262,6 +262,12 @@ namespace MonoDevelop.MacIntegration.MainToolbar Enabled = mutableModel.Enabled, Hidden = !mutableModel.Visible, }; + if (!string.IsNullOrEmpty (runtime.Image)) { + menuItem.Image = ImageService.GetIcon (runtime.Image).ToNSImage (); + } + if (!string.IsNullOrEmpty (runtime.Tooltip)) { + menuItem.ToolTip = runtime.Tooltip; + } if (ActiveRuntime == runtime || (ActiveRuntime?.Children.Contains (runtime) ?? false)) { menuItem.State = NSCellStateValue.On; } @@ -297,6 +303,10 @@ namespace MonoDevelop.MacIntegration.MainToolbar NSImage projectImageDisabled = MultiResImage.CreateMultiResImage ("project", "disabled"); NSImage deviceImage = MultiResImage.CreateMultiResImage ("device", ""); NSImage deviceImageDisabled = MultiResImage.CreateMultiResImage ("device", "disabled"); + + string lastDeviceIconId; + NSImage lastDeviceImage; + NSImage lastDeviceImageDisabled; public PathSelectorView (CGRect frameRect) : base (frameRect) { Cells = new [] { @@ -501,11 +511,43 @@ namespace MonoDevelop.MacIntegration.MainToolbar UpdateImages (); } + static NSImage FixImageServiceImage (Xwt.Drawing.Image image, double scale, string[] styles) + { + NSImage result = image.WithStyles (styles).ToBitmap (scale).ToNSImage (); + result.Template = true; + return result; + } + + NSImage GetDeviceImage (bool enabled) + { + if (ActiveRuntime == null || string.IsNullOrEmpty (ActiveRuntime.Image)) + return enabled ? deviceImage : deviceImageDisabled; + if (ActiveRuntime.Image == lastDeviceIconId) + return enabled ? lastDeviceImage : lastDeviceImageDisabled; + + lastDeviceIconId = ActiveRuntime.Image; + var scale = GtkWorkarounds.GetScaleFactor (Ide.IdeApp.Workbench.RootWindow); + Xwt.Drawing.Image baseIcon = ImageService.GetIcon (ActiveRuntime.Image, Gtk.IconSize.Menu); + + string [] styles, disabledStyles; + if (NSUserDefaults.StandardUserDefaults.StringForKey ("AppleInterfaceStyle") == "Dark") { + styles = new [] { "dark" }; + disabledStyles = new [] { "dark", "disabled" }; + } else { + styles = null; + disabledStyles = new [] { "disabled" }; + } + + lastDeviceImage = FixImageServiceImage (baseIcon, scale, styles); + lastDeviceImageDisabled = FixImageServiceImage (baseIcon, scale, disabledStyles); + return enabled ? lastDeviceImage : lastDeviceImageDisabled; + } + void UpdateImages () { NSImage runConfigImage = projectImage; NSImage configImage = projectImage; - NSImage runtimeImage = deviceImage; + NSImage runtimeImage = GetDeviceImage (Cells [RuntimeIdx].Enabled); if (!Cells [RunConfigurationIdx].Enabled) runConfigImage = projectImageDisabled; @@ -513,9 +555,6 @@ namespace MonoDevelop.MacIntegration.MainToolbar if (!Cells [ConfigurationIdx].Enabled) configImage = projectImageDisabled; - if (!Cells [ConfigurationIdx].Enabled) - runtimeImage = deviceImageDisabled; - // HACK // For some reason NSPathControl does not like the images that ImageService provides. To use them it requires // ToBitmap() to be called first. But a second problem is that ImageService only seems to provide a single resolution diff --git a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeDebuggerSession.cs b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeDebuggerSession.cs index 68c8843843..f554e15e4f 100644 --- a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeDebuggerSession.cs +++ b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeDebuggerSession.cs @@ -34,6 +34,9 @@ using System.IO; using System.Text; using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages; using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol; +using System.Threading; +using MonoDevelop.Core; +using MonoDevelop.Core.Execution; namespace MonoDevelop.Debugger.VsCodeDebugProtocol { @@ -150,7 +153,17 @@ namespace MonoDevelop.Debugger.VsCodeDebugProtocol protected virtual void OnDebugAdaptorRequestReceived (object sender, RequestReceivedEventArgs e) { - + if (e.Command == "runInTerminal") { + var args = (RunInTerminalArguments)e.Args; + var consoleOptions = OperationConsoleFactory.CreateConsoleOptions.Default.WithTitle (args.Title).WithPauseWhenFinished (pauseWhenFinished); + Runtime.ProcessService.StartConsoleProcess ( + args.Args [0], + string.Join (" ", args.Args.Skip (1).ToArray ()), + args.Cwd, + ExternalConsoleFactory.Instance.CreateConsole (consoleOptions), + args.Env.ToDictionary ((i) => i.Key, (i) => i.Value.ToString ())); + e.Response = new RunInTerminalResponse (); + } } void StartDebugAgent () @@ -196,8 +209,10 @@ namespace MonoDevelop.Debugger.VsCodeDebugProtocol Launch (startInfo); } + bool pauseWhenFinished; protected void Launch (DebuggerStartInfo startInfo) { + pauseWhenFinished = !startInfo.CloseExternalConsoleOnExit; StartDebugAgent (); LaunchRequest launchRequest = CreateLaunchRequest (startInfo); protocolClient.SendRequestSync (launchRequest); @@ -296,19 +311,19 @@ namespace MonoDevelop.Debugger.VsCodeDebugProtocol return null; } - List<Source> existingSourcesWithBreakpoints = new List<Source> (); + List<string> pathsWithBreakpoints = new List<string> (); void UpdateBreakpoints () { - //First clear all old breakpoints - foreach (var source in existingSourcesWithBreakpoints) - protocolClient.SendRequest (new SetBreakpointsRequest (source, new List<SourceBreakpoint> ()), null); - existingSourcesWithBreakpoints.Clear (); + var bks = breakpoints.Select (b => b.Key).OfType<Mono.Debugging.Client.Breakpoint> ().Where (b => b.Enabled).GroupBy (b => b.FileName).ToArray (); + var filesForRemoval = pathsWithBreakpoints.Where (path => !bks.Any (b => b.Key == path)).ToArray (); + pathsWithBreakpoints = bks.Select (b => b.Key).ToList (); + + foreach (var path in filesForRemoval) + protocolClient.SendRequest (new SetBreakpointsRequest (new Source (Path.GetFileName (path), path), new List<SourceBreakpoint> ()), null); - var bks = breakpoints.Select (b => b.Key).OfType<Mono.Debugging.Client.Breakpoint> ().GroupBy (b => b.FileName).ToArray (); foreach (var sourceFile in bks) { var source = new Source (Path.GetFileName (sourceFile.Key), sourceFile.Key); - existingSourcesWithBreakpoints.Add (source); protocolClient.SendRequest (new SetBreakpointsRequest ( source, sourceFile.Select (b => new SourceBreakpoint { @@ -360,8 +375,11 @@ namespace MonoDevelop.Debugger.VsCodeDebugProtocol public override void Dispose () { base.Dispose (); - if (protocolClient != null) + if (protocolClient != null) { protocolClient.RequestReceived += OnDebugAdaptorRequestReceived; + protocolClient.SendRequestSync (new DisconnectRequest ()); + protocolClient.Stop (); + } } } } diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ExceptionCaughtDialog.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ExceptionCaughtDialog.cs index 785349674e..15b7afb3a3 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ExceptionCaughtDialog.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ExceptionCaughtDialog.cs @@ -58,6 +58,8 @@ namespace MonoDevelop.Debugger protected Label ExceptionMessageLabel { get; private set; } + protected Label ExceptionHelpLinkLabel { get; private set; } + protected Label ExceptionTypeLabel { get; private set; } readonly ExceptionCaughtMessage message; @@ -101,15 +103,30 @@ namespace MonoDevelop.Debugger ExceptionTypeLabel = new Label { Xalign = 0.0f, Selectable = true, CanFocus = false }; ExceptionMessageLabel = new Label { Wrap = true, Xalign = 0.0f, Selectable = true, CanFocus = false }; + ExceptionHelpLinkLabel = new Label { Wrap = true, Xalign = 0.0f, Selectable = true, CanFocus = false, UseMarkup = true, LineWrapMode = Pango.WrapMode.Char }; + ExceptionHelpLinkLabel.Name = "exception_help_link_label"; + Gtk.Rc.ParseString (@"style ""exception-help-link-label"" +{ + GtkWidget::link-color = ""#ffffff"" + GtkWidget::visited-link-color = ""#ffffff"" +} +widget ""*.exception_help_link_label"" style ""exception-help-link-label"" +"); + ExceptionHelpLinkLabel.ModifyBase (StateType.Prelight, new Gdk.Color (119, 130, 140)); + + ExceptionHelpLinkLabel.SetLinkHandler ((str) => DesktopService.ShowUrl (str)); ExceptionTypeLabel.ModifyFg (StateType.Normal, new Gdk.Color (255, 255, 255)); ExceptionMessageLabel.ModifyFg (StateType.Normal, new Gdk.Color (255, 255, 255)); + ExceptionHelpLinkLabel.ModifyFg (StateType.Normal, new Gdk.Color (255, 255, 255)); if (Platform.IsWindows) { ExceptionTypeLabel.ModifyFont (Pango.FontDescription.FromString ("bold 19")); ExceptionMessageLabel.ModifyFont (Pango.FontDescription.FromString ("10")); + ExceptionHelpLinkLabel.ModifyFont (Pango.FontDescription.FromString ("10")); } else { ExceptionTypeLabel.ModifyFont (Pango.FontDescription.FromString ("21")); ExceptionMessageLabel.ModifyFont (Pango.FontDescription.FromString ("12")); + ExceptionHelpLinkLabel.ModifyFont (Pango.FontDescription.FromString ("12")); } //Force rendering of background with EventBox @@ -121,6 +138,7 @@ namespace MonoDevelop.Debugger rightVBox.PackStart (ExceptionTypeLabel, false, false, (uint)(Platform.IsWindows ? 0 : 2)); rightVBox.PackStart (ExceptionMessageLabel, true, true, (uint)(Platform.IsWindows ? 6 : 5)); + rightVBox.PackStart (ExceptionHelpLinkLabel, false, false, 2); hBox.PackStart (leftVBox, false, false, (uint)(Platform.IsWindows ? 5 : 0)); // as we change frame.BorderWidth below, we need to compensate hBox.PackStart (rightVBox, true, true, (uint)(Platform.IsWindows ? 5 : 10)); @@ -142,8 +160,11 @@ namespace MonoDevelop.Debugger { base.OnSizeAllocated (allocation); ExceptionMessageLabel.WidthRequest = rightVBox.Allocation.Width; - if (vboxAroundInnerExceptionMessage != null) + ExceptionHelpLinkLabel.WidthRequest = rightVBox.Allocation.Width; + if (vboxAroundInnerExceptionMessage != null) { InnerExceptionMessageLabel.WidthRequest = vboxAroundInnerExceptionMessage.Allocation.Width; + InnerExceptionHelpLinkLabel.WidthRequest = vboxAroundInnerExceptionMessage.Allocation.Width; + } } Widget CreateExceptionValueTreeView () @@ -374,6 +395,7 @@ widget ""*.exception_dialog_expander"" style ""exception-dialog-expander"" Label InnerExceptionTypeLabel; Label InnerExceptionMessageLabel; + Label InnerExceptionHelpLinkLabel; Widget CreateInnerExceptionMessage () { @@ -398,8 +420,20 @@ widget ""*.exception_dialog_expander"" style ""exception-dialog-expander"" InnerExceptionMessageLabel.CanFocus = false; InnerExceptionMessageLabel.Xalign = 0; InnerExceptionMessageLabel.ModifyFont (Pango.FontDescription.FromString (Platform.IsWindows ? "9" : "11")); + + InnerExceptionHelpLinkLabel = new Label (); + InnerExceptionHelpLinkLabel.UseMarkup = true; + InnerExceptionHelpLinkLabel.Wrap = true; + InnerExceptionHelpLinkLabel.LineWrapMode = Pango.WrapMode.Char; + InnerExceptionHelpLinkLabel.Selectable = true; + InnerExceptionHelpLinkLabel.CanFocus = false; + InnerExceptionHelpLinkLabel.Xalign = 0; + InnerExceptionHelpLinkLabel.ModifyFont (Pango.FontDescription.FromString (Platform.IsWindows ? "9" : "11")); + InnerExceptionHelpLinkLabel.SetLinkHandler ((str) => DesktopService.ShowUrl (str)); + vboxAroundInnerExceptionMessage.PackStart (hbox, false, true, 0); vboxAroundInnerExceptionMessage.PackStart (InnerExceptionMessageLabel, true, true, 10); + vboxAroundInnerExceptionMessage.PackStart (InnerExceptionHelpLinkLabel, true, true, 2); hboxMain.PackStart (vboxAroundInnerExceptionMessage, true, true, 10); hboxMain.ShowAll (); return hboxMain; @@ -564,6 +598,12 @@ widget ""*.exception_dialog_expander"" style ""exception-dialog-expander"" if (InnerExceptionTypeLabel != null) { InnerExceptionTypeLabel.Markup = "<b>" + GLib.Markup.EscapeText (ex.Type) + "</b>"; InnerExceptionMessageLabel.Text = ex.Message; + if (!string.IsNullOrEmpty (ex.HelpLink)) { + InnerExceptionHelpLinkLabel.Markup = GetHelpLinkMarkup (ex); + InnerExceptionHelpLinkLabel.Show (); + } else { + InnerExceptionHelpLinkLabel.Hide (); + } } } @@ -574,10 +614,21 @@ widget ""*.exception_dialog_expander"" style ""exception-dialog-expander"" ExceptionTypeLabel.Text = exception.Type; ExceptionMessageLabel.Text = exception.Message ?? string.Empty; + if (!string.IsNullOrEmpty (exception.HelpLink)) { + ExceptionHelpLinkLabel.Show (); + ExceptionHelpLinkLabel.Markup = GetHelpLinkMarkup(exception); + } else { + ExceptionHelpLinkLabel.Hide (); + } UpdateSelectedException (exception); } + internal static string GetHelpLinkMarkup (ExceptionInfo exception) + { + return $"<a href=\"{System.Security.SecurityElement.Escape (exception.HelpLink)}\">{GettextCatalog.GetString ("More information")}</a>"; + } + void ExceptionChanged (object sender, EventArgs e) { Application.Invoke (delegate { diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackageDependenciesNodeCommandHandler.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Commands/PackageDependenciesNodeCommandHandler.cs index 6cfdb494e6..78ee767357 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackageDependenciesNodeCommandHandler.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Commands/PackageDependenciesNodeCommandHandler.cs @@ -25,8 +25,9 @@ // THE SOFTWARE. using MonoDevelop.Ide.Gui.Components; +using MonoDevelop.PackageManagement; -namespace MonoDevelop.PackageManagement.Commands +namespace MonoDevelop.DotNetCore.Commands { class PackageDependenciesNodeCommandHandler : NodeCommandHandler { diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackageDependencyNodeCommandHandler.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Commands/PackageDependencyNodeCommandHandler.cs index 81d19be668..bc64566779 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackageDependencyNodeCommandHandler.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Commands/PackageDependencyNodeCommandHandler.cs @@ -25,13 +25,16 @@ // THE SOFTWARE. using System; +using System.Linq; using MonoDevelop.Components.Commands; using MonoDevelop.Core; +using MonoDevelop.DotNetCore.NodeBuilders; using MonoDevelop.Ide.Commands; using MonoDevelop.Ide.Gui.Components; -using MonoDevelop.PackageManagement.NodeBuilders; +using MonoDevelop.PackageManagement; +using MonoDevelop.PackageManagement.Commands; -namespace MonoDevelop.PackageManagement.Commands +namespace MonoDevelop.DotNetCore.Commands { class PackageDependencyNodeCommandHandler : NodeCommandHandler { @@ -49,36 +52,57 @@ namespace MonoDevelop.PackageManagement.Commands void RemovePackage (PackageDependencyNode node, ProgressMonitorStatusMessage progressMessage) { - IPackageAction action = CreateUninstallPackageAction (node); + IPackageAction action = PackageReferenceNodeCommandHandler.CreateUninstallPackageAction (node.Project, node.Name); PackageManagementServices.BackgroundPackageActionRunner.Run (progressMessage, action); } - IPackageAction CreateUninstallPackageAction (PackageDependencyNode node) - { - var solutionManager = PackageManagementServices.Workspace.GetSolutionManager (node.Project.ParentSolution); - return new UninstallNuGetPackageAction (solutionManager, new DotNetProjectProxy (node.Project)) { - PackageId = node.Name - }; - } - [CommandUpdateHandler (EditCommands.Delete)] public void UpdateRemoveItem (CommandInfo info) { var node = (PackageDependencyNode)CurrentNode.DataItem; - info.Enabled = CanDeleteMultipleItems () && node.CanBeRemoved; - info.Text = GettextCatalog.GetString ("Remove"); + if (!node.CanBeRemoved) { + info.Visible = false; + } else { + info.Enabled = CanDeleteMultipleItems (); + info.Text = GettextCatalog.GetString ("Remove"); + } + } + + public override void DeleteMultipleItems () + { + int nodeCount = CurrentNodes.Count (); + if (nodeCount == 1) { + DeleteItem (); + } else if (nodeCount > 0) { + var nodes = CurrentNodes.Select (node => (PackageDependencyNode)node.DataItem).ToArray (); + RemoveMultiplePackages (nodes); + } + } + + void RemoveMultiplePackages (PackageDependencyNode[] nodes) + { + ProgressMonitorStatusMessage progressMessage = ProgressMonitorStatusMessageFactory.CreateRemovingPackagesFromProjectMessage (nodes.Length); + + try { + RemoveMultiplePackage (nodes, progressMessage); + } catch (Exception ex) { + PackageManagementServices.BackgroundPackageActionRunner.ShowError (progressMessage, ex); + } } - public override bool CanDeleteMultipleItems () + void RemoveMultiplePackage (PackageDependencyNode[] nodes, ProgressMonitorStatusMessage progressMessage) { - return !MultipleSelectedNodes; + var project = nodes[0].Project; + string[] packageIds = nodes.Select (node => node.Name).ToArray (); + IPackageAction action = PackageReferenceNodeCommandHandler.CreateUninstallPackagesAction (project, packageIds); + PackageManagementServices.BackgroundPackageActionRunner.Run (progressMessage, action); } [CommandUpdateHandler (PackageReferenceNodeCommands.UpdatePackage)] void CheckCanUpdatePackage (CommandInfo info) { var node = (PackageDependencyNode)CurrentNode.DataItem; - info.Enabled = node.CanBeRemoved; + info.Visible = node.CanBeRemoved; } [CommandHandler (PackageReferenceNodeCommands.UpdatePackage)] @@ -86,19 +110,11 @@ namespace MonoDevelop.PackageManagement.Commands { var node = (PackageDependencyNode)CurrentNode.DataItem; var project = new DotNetProjectProxy (node.Project); - ProgressMonitorStatusMessage progressMessage = ProgressMonitorStatusMessageFactory.CreateUpdatingSinglePackageMessage (node.Name, project); - try { - var solutionManager = PackageManagementServices.Workspace.GetSolutionManager (node.Project.ParentSolution); - var action = new UpdateNuGetPackageAction (solutionManager, project) { - PackageId = node.Name, - IncludePrerelease = !node.IsReleaseVersion () - }; - - PackageManagementServices.BackgroundPackageActionRunner.Run (progressMessage, action); - } catch (Exception ex) { - PackageManagementServices.BackgroundPackageActionRunner.ShowError (progressMessage, ex); - } + PackageReferenceNodeCommandHandler.UpdatePackage ( + project, + node.Name, + !node.IsReleaseVersion ()); } } } diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Commands/ProjectOrAssemblyDependenciesCommandHandler.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Commands/ProjectOrAssemblyDependenciesCommandHandler.cs new file mode 100644 index 0000000000..18e2dced0e --- /dev/null +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Commands/ProjectOrAssemblyDependenciesCommandHandler.cs @@ -0,0 +1,40 @@ +// +// ProjectOrAssemblyDependenciesCommandHandler.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2017 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using MonoDevelop.Ide.Gui.Components; +using MonoDevelop.Ide; +using MonoDevelop.Ide.Commands; + +namespace MonoDevelop.DotNetCore.Commands +{ + class ProjectOrAssemblyDependenciesCommandHandler : NodeCommandHandler + { + public override void ActivateItem () + { + IdeApp.CommandService.DispatchCommand (ProjectCommands.AddReference); + } + } +} diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/AssemblyDependenciesNode.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/AssemblyDependenciesNode.cs new file mode 100644 index 0000000000..8673e3ca0e --- /dev/null +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/AssemblyDependenciesNode.cs @@ -0,0 +1,74 @@ +// +// AssemblyDependenciesNode.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2017 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System.Collections.Generic; +using System.Linq; +using MonoDevelop.Core; +using MonoDevelop.Ide.Gui; +using MonoDevelop.Projects; + +namespace MonoDevelop.DotNetCore.NodeBuilders +{ + class AssemblyDependenciesNode + { + public static readonly string NodeName = "AssemblyDependencies"; + + public AssemblyDependenciesNode (DotNetProject project) + { + Project = project; + } + + internal DotNetProject Project { get; private set; } + + public bool HasChildNodes () + { + return Project.References.Any (ProjectReferenceExtensions.IsAssemblyReference); + } + + public string GetLabel () + { + return GettextCatalog.GetString ("Assemblies"); + } + + public string GetSecondaryLabel () + { + return string.Empty; + } + + public IconId Icon { + get { return Stock.OpenReferenceFolder; } + } + + public IconId ClosedIcon { + get { return Stock.ClosedReferenceFolder; } + } + + public IEnumerable<ProjectReference> GetChildNodes () + { + return Project.References.Where (ProjectReferenceExtensions.IsAssemblyReference); + } + } +} diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/AssemblyDependenciesNodeBuilder.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/AssemblyDependenciesNodeBuilder.cs new file mode 100644 index 0000000000..2821fa9048 --- /dev/null +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/AssemblyDependenciesNodeBuilder.cs @@ -0,0 +1,68 @@ +// +// AssemblyDependenciesNodeBuilder.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2017 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using MonoDevelop.DotNetCore.Commands; +using MonoDevelop.Ide.Gui.Components; + +namespace MonoDevelop.DotNetCore.NodeBuilders +{ + class AssemblyDependenciesNodeBuilder : TypeNodeBuilder + { + public override Type NodeDataType { + get { return typeof(AssemblyDependenciesNode); } + } + + public override Type CommandHandlerType { + get { return typeof(ProjectOrAssemblyDependenciesCommandHandler); } + } + + public override string GetNodeName (ITreeNavigator thisNode, object dataObject) + { + return AssemblyDependenciesNode.NodeName; + } + + public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, NodeInfo nodeInfo) + { + var node = (AssemblyDependenciesNode)dataObject; + nodeInfo.Label = node.GetLabel (); + nodeInfo.SecondaryLabel = node.GetSecondaryLabel (); + nodeInfo.Icon = Context.GetIcon (node.Icon); + nodeInfo.ClosedIcon = Context.GetIcon (node.ClosedIcon); + } + + public override bool HasChildNodes (ITreeBuilder builder, object dataObject) + { + return true; + } + + public override void BuildChildNodes (ITreeBuilder treeBuilder, object dataObject) + { + var node = (AssemblyDependenciesNode)dataObject; + treeBuilder.AddChildren (node.GetChildNodes ()); + } + } +} diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/DependenciesNode.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DependenciesNode.cs index 802d428101..6b5e75d324 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/DependenciesNode.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DependenciesNode.cs @@ -24,11 +24,12 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +using System.Collections.Generic; using MonoDevelop.Core; using MonoDevelop.Ide.Gui; using MonoDevelop.Projects; -namespace MonoDevelop.PackageManagement.NodeBuilders +namespace MonoDevelop.DotNetCore.NodeBuilders { class DependenciesNode { @@ -37,9 +38,11 @@ namespace MonoDevelop.PackageManagement.NodeBuilders public DependenciesNode (DotNetProject project) { Project = project; + PackageDependencyCache = new PackageDependencyNodeCache (Project); } internal DotNetProject Project { get; private set; } + internal PackageDependencyNodeCache PackageDependencyCache { get; private set; } public string GetLabel () { @@ -58,5 +61,15 @@ namespace MonoDevelop.PackageManagement.NodeBuilders public IconId ClosedIcon { get { return Stock.ClosedReferenceFolder; } } + + public IEnumerable<TargetFrameworkNode> GetTargetFrameworkNodes (bool sdkDependencies) + { + return PackageDependencyCache.GetTargetFrameworkNodes (this, sdkDependencies); + } + + public IEnumerable<PackageDependencyNode> GetProjectPackageReferencesAsDependencyNodes () + { + return PackageDependencyCache.GetProjectPackageReferencesAsDependencyNodes (this); + } } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/DependenciesNodeBuilder.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DependenciesNodeBuilder.cs index a73baa5a09..8c00cd2380 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/DependenciesNodeBuilder.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DependenciesNodeBuilder.cs @@ -26,10 +26,8 @@ using System; using MonoDevelop.Ide.Gui.Components; -using MonoDevelop.Ide.Gui.Pads.ProjectPad; -using MonoDevelop.Projects; -namespace MonoDevelop.PackageManagement.NodeBuilders +namespace MonoDevelop.DotNetCore.NodeBuilders { public class DependenciesNodeBuilder : TypeNodeBuilder { @@ -64,9 +62,22 @@ namespace MonoDevelop.PackageManagement.NodeBuilders public override void BuildChildNodes (ITreeBuilder treeBuilder, object dataObject) { var node = (DependenciesNode)dataObject; - var folderNode = new PackageDependenciesNode (node); - folderNode.Refresh (); - treeBuilder.AddChild (folderNode); + node.PackageDependencyCache.Refresh (); + + var packagesNode = new PackageDependenciesNode (node); + if (packagesNode.HasChildNodes ()) + treeBuilder.AddChild (packagesNode); + + var sdkNode = new SdkDependenciesNode (node); + treeBuilder.AddChild (sdkNode); + + var assembliesNode = new AssemblyDependenciesNode (node.Project); + if (assembliesNode.HasChildNodes ()) + treeBuilder.AddChild (assembliesNode); + + var projectsNode = new ProjectDependenciesNode (node.Project); + if (projectsNode.HasChildNodes ()) + treeBuilder.AddChild (projectsNode); } } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/DependenciesNodeBuilderExtension.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DependenciesNodeBuilderExtension.cs index 6dbd4e0e1d..3d0d807c76 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/DependenciesNodeBuilderExtension.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DependenciesNodeBuilderExtension.cs @@ -25,27 +25,33 @@ // THE SOFTWARE. using System; +using System.Linq; using MonoDevelop.Core; using MonoDevelop.Ide; using MonoDevelop.Ide.Gui.Components; +using MonoDevelop.PackageManagement; using MonoDevelop.Projects; -namespace MonoDevelop.PackageManagement.NodeBuilders +namespace MonoDevelop.DotNetCore.NodeBuilders { class DependenciesNodeBuilderExtension : NodeBuilderExtension { IPackageManagementEvents packageManagementEvents; - public DependenciesNodeBuilderExtension () + protected override void Initialize () { packageManagementEvents = PackageManagementServices.PackageManagementEvents; - packageManagementEvents.PackageOperationsFinished += PackageOperationsFinished; + + IdeApp.Workspace.ReferenceAddedToProject += OnReferencesChanged; + IdeApp.Workspace.ReferenceRemovedFromProject += OnReferencesChanged; } public override void Dispose () { packageManagementEvents.PackageOperationsFinished -= PackageOperationsFinished; + IdeApp.Workspace.ReferenceAddedToProject -= OnReferencesChanged; + IdeApp.Workspace.ReferenceRemovedFromProject -= OnReferencesChanged; } public override bool CanBuildNode (Type dataType) @@ -61,7 +67,7 @@ namespace MonoDevelop.PackageManagement.NodeBuilders void PackageOperationsFinished (object sender, EventArgs e) { - RefreshAllChildNodes (); + RefreshAllChildNodes (packagesOnly: true); } public override void BuildChildNodes (ITreeBuilder treeBuilder, object dataObject) @@ -74,27 +80,55 @@ namespace MonoDevelop.PackageManagement.NodeBuilders treeBuilder.AddChild (folderNode); } - void RefreshAllChildNodes () + void RefreshAllChildNodes (bool packagesOnly = false) { Runtime.RunInMainThread (() => { foreach (DotNetProject project in IdeApp.Workspace.GetAllItems<DotNetProject> ()) { if (project.IsDotNetCoreProject ()) - RefreshChildNodes (project); + RefreshChildNodes (project, packagesOnly); } }); } - void RefreshChildNodes (DotNetProject project) + void RefreshChildNodes (DotNetProject project, bool packagesOnly) { ITreeBuilder builder = Context.GetTreeBuilder (project); if (builder != null) { if (builder.MoveToChild (DependenciesNode.NodeName, typeof (DependenciesNode))) { - if (builder.MoveToChild (PackageDependenciesNode.NodeName, typeof (PackageDependenciesNode))) { - var packagesFolder = (PackageDependenciesNode)builder.DataItem; - packagesFolder.Refresh (); + if (packagesOnly) { + var dependenciesNode = (DependenciesNode)builder.DataItem; + dependenciesNode.PackageDependencyCache.Refresh (); + UpdateNuGetFolderNode (builder, dependenciesNode); + } else { + builder.UpdateAll (); } } } } + + void UpdateNuGetFolderNode (ITreeBuilder builder, DependenciesNode dependenciesNode) + { + bool hasPackages = dependenciesNode.Project.Items.OfType<ProjectPackageReference> ().Any (); + if (hasPackages && !builder.MoveToChild (PackageDependenciesNode.NodeName, typeof (PackageDependenciesNode))) { + var packagesNode = new PackageDependenciesNode (dependenciesNode); + builder.AddChild (packagesNode); + } + } + + void OnReferencesChanged (object sender, ProjectReferenceEventArgs e) + { + RefreshAllChildNodes (e.Project as DotNetProject); + } + + void RefreshAllChildNodes (DotNetProject project) + { + if (project == null) + return; + + Runtime.RunInMainThread (() => { + if (project.IsDotNetCoreProject ()) + RefreshChildNodes (project, packagesOnly: false); + }); + } } } diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreFolderNodeBuilderExtension.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DotNetCoreFolderNodeBuilderExtension.cs index b4c8426b54..f6600d1ece 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreFolderNodeBuilderExtension.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DotNetCoreFolderNodeBuilderExtension.cs @@ -29,7 +29,7 @@ using MonoDevelop.Ide.Gui.Components; using MonoDevelop.Ide.Gui.Pads.ProjectPad; using MonoDevelop.Projects; -namespace MonoDevelop.DotNetCore +namespace MonoDevelop.DotNetCore.NodeBuilders { class DotNetCoreFolderNodeBuilderExtension : NodeBuilderExtension { diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectNodeBuilderExtension.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DotNetCoreProjectNodeBuilderExtension.cs index 2dcb4802f9..ff1e4f2c76 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectNodeBuilderExtension.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DotNetCoreProjectNodeBuilderExtension.cs @@ -30,7 +30,7 @@ using MonoDevelop.Ide.Gui.Components; using MonoDevelop.Ide.Tasks; using MonoDevelop.Projects; -namespace MonoDevelop.DotNetCore +namespace MonoDevelop.DotNetCore.NodeBuilders { class DotNetCoreProjectNodeBuilderExtension : NodeBuilderExtension { diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DotNetCoreProjectReferencesNodeBuilderExtension.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DotNetCoreProjectReferencesNodeBuilderExtension.cs new file mode 100644 index 0000000000..62db831eb0 --- /dev/null +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DotNetCoreProjectReferencesNodeBuilderExtension.cs @@ -0,0 +1,57 @@ +// +// EmptyDirectoryRemover.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2017 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; +using MonoDevelop.Ide.Gui.Components; +using MonoDevelop.Projects; + +namespace MonoDevelop.DotNetCore.NodeBuilders +{ + class DotNetCoreProjectReferencesNodeBuilderExtension : NodeBuilderExtension + { + public override bool CanBuildNode (Type dataType) + { + return typeof (ProjectReferenceCollection).IsAssignableFrom (dataType); + } + + public override void GetNodeAttributes (ITreeNavigator parentNode, object dataObject, ref NodeAttributes attributes) + { + if (IsDotNetCoreProject (parentNode)) { + attributes |= NodeAttributes.Hidden; + } + } + + bool IsDotNetCoreProject (ITreeNavigator parentNode) + { + var project = parentNode.DataItem as DotNetProject; + if (project != null) + return project.HasFlavor<DotNetCoreProjectExtension> (); + + return false; + } + } +} diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/PackageDependenciesNode.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/PackageDependenciesNode.cs new file mode 100644 index 0000000000..e22d152dca --- /dev/null +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/PackageDependenciesNode.cs @@ -0,0 +1,94 @@ +// +// PackageDependenciesNode.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2016 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Linq; +using MonoDevelop.Core; +using MonoDevelop.Ide.Gui; +using MonoDevelop.PackageManagement; +using MonoDevelop.Projects; + +namespace MonoDevelop.DotNetCore.NodeBuilders +{ + class PackageDependenciesNode + { + public static readonly string NodeName = "PackageDependencies"; + + public PackageDependenciesNode (DependenciesNode parentNode) + { + ParentNode = parentNode; + } + + internal DotNetProject Project { + get { return ParentNode.Project; } + } + + internal DependenciesNode ParentNode { get; private set; } + + public string GetLabel () + { + return "NuGet"; + } + + public string GetSecondaryLabel () + { + return string.Empty; + } + + public IconId Icon { + get { return Stock.OpenReferenceFolder; } + } + + public IconId ClosedIcon { + get { return Stock.ClosedReferenceFolder; } + } + + public bool LoadedDependencies { + get { return ParentNode.PackageDependencyCache.LoadedDependencies; } + } + + public IEnumerable<TargetFrameworkNode> GetTargetFrameworkNodes () + { + return ParentNode.GetTargetFrameworkNodes (sdkDependencies: false); + } + + public PackageDependency GetDependency (string dependency) + { + return ParentNode.PackageDependencyCache.GetDependency (dependency); + } + + public IEnumerable<PackageDependencyNode> GetProjectPackageReferencesAsDependencyNodes () + { + return ParentNode.GetProjectPackageReferencesAsDependencyNodes (); + } + + public bool HasChildNodes () + { + return Project.Items.OfType<ProjectPackageReference> ().Any (); + } + } +} diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/PackageDependenciesNodeBuilder.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/PackageDependenciesNodeBuilder.cs index 9af68bda6b..7b093d91cf 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/PackageDependenciesNodeBuilder.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/PackageDependenciesNodeBuilder.cs @@ -27,11 +27,10 @@ using System; using System.Collections.Generic; using System.Linq; -using MonoDevelop.Core; +using MonoDevelop.DotNetCore.Commands; using MonoDevelop.Ide.Gui.Components; -using MonoDevelop.PackageManagement.Commands; -namespace MonoDevelop.PackageManagement.NodeBuilders +namespace MonoDevelop.DotNetCore.NodeBuilders { class PackageDependenciesNodeBuilder : TypeNodeBuilder { @@ -59,7 +58,8 @@ namespace MonoDevelop.PackageManagement.NodeBuilders public override bool HasChildNodes (ITreeBuilder builder, object dataObject) { - return true; + var node = (PackageDependenciesNode)dataObject; + return node.HasChildNodes (); } public override void BuildChildNodes (ITreeBuilder treeBuilder, object dataObject) @@ -99,21 +99,32 @@ namespace MonoDevelop.PackageManagement.NodeBuilders public override void OnNodeAdded (object dataObject) { var dependenciesNode = (PackageDependenciesNode)dataObject; - dependenciesNode.PackageDependenciesChanged += OnPackageDependenciesChanged; + dependenciesNode.ParentNode.PackageDependencyCache.PackageDependenciesChanged += OnPackageDependenciesChanged; } public override void OnNodeRemoved (object dataObject) { var dependenciesNode = (PackageDependenciesNode)dataObject; - dependenciesNode.PackageDependenciesChanged -= OnPackageDependenciesChanged; + dependenciesNode.ParentNode.PackageDependencyCache.PackageDependenciesChanged -= OnPackageDependenciesChanged; } void OnPackageDependenciesChanged (object sender, EventArgs e) { - var dependenciesNode = (PackageDependenciesNode)sender; - ITreeBuilder builder = Context.GetTreeBuilder (dependenciesNode); - if (builder != null) { - builder.UpdateAll (); + var cache = (PackageDependencyNodeCache)sender; + var project = cache.Project; + ITreeBuilder builder = Context.GetTreeBuilder (project); + if (builder == null) + return; + + if (builder.MoveToChild (DependenciesNode.NodeName, typeof(DependenciesNode))) { + if (builder.MoveToChild (PackageDependenciesNode.NodeName, typeof (PackageDependenciesNode))) { + var node = builder.DataItem as PackageDependenciesNode; + if (node != null && !node.HasChildNodes ()) { + builder.Remove (); + return; + } + builder.UpdateAll (); + } } } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/PackageDependencyNode.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/PackageDependencyNode.cs index 6f6cbc5d82..8067bbfed0 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/PackageDependencyNode.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/PackageDependencyNode.cs @@ -28,20 +28,21 @@ using System; using System.Collections.Generic; using System.Linq; using MonoDevelop.Core; +using MonoDevelop.PackageManagement; using MonoDevelop.Projects; using NuGet.Versioning; -namespace MonoDevelop.PackageManagement.NodeBuilders +namespace MonoDevelop.DotNetCore.NodeBuilders { class PackageDependencyNode { - PackageDependenciesNode dependenciesNode; + DependenciesNode dependenciesNode; PackageDependency dependency; string name; string version; PackageDependencyNode ( - PackageDependenciesNode dependenciesNode, + DependenciesNode dependenciesNode, PackageDependency dependency, bool topLevel) { @@ -56,7 +57,7 @@ namespace MonoDevelop.PackageManagement.NodeBuilders IsReadOnly = !PackageReferenceExistsInProject (); } - PackageDependencyNode (PackageDependenciesNode dependenciesNode, ProjectPackageReference packageReference) + PackageDependencyNode (DependenciesNode dependenciesNode, ProjectPackageReference packageReference) { this.dependenciesNode = dependenciesNode; IsTopLevel = true; @@ -66,19 +67,34 @@ namespace MonoDevelop.PackageManagement.NodeBuilders } public static PackageDependencyNode Create ( - PackageDependenciesNode dependenciesNode, + DependenciesNode dependenciesNode, string dependencyName, + bool sdkDependencies, bool topLevel) { - PackageDependency dependency = dependenciesNode.GetDependency (dependencyName); - if (dependency != null) - return new PackageDependencyNode (dependenciesNode, dependency, topLevel); + PackageDependency dependency = dependenciesNode.PackageDependencyCache.GetDependency (dependencyName); + if (dependency != null) { + var node = new PackageDependencyNode (dependenciesNode, dependency, topLevel); + if (node.IsSupported (sdkDependencies)) { + return node; + } + } return null; } + /// <summary> + /// Sdk dependencies have IsReadOnly set to true. + /// </summary> + bool IsSupported (bool sdkDependencies) + { + if (IsReadOnly) + return sdkDependencies; + return !sdkDependencies; + } + public static PackageDependencyNode Create ( - PackageDependenciesNode dependenciesNode, + DependenciesNode dependenciesNode, ProjectPackageReference packageReference) { return new PackageDependencyNode (dependenciesNode, packageReference); @@ -142,12 +158,13 @@ namespace MonoDevelop.PackageManagement.NodeBuilders } public static IEnumerable<PackageDependencyNode> GetDependencyNodes ( - PackageDependenciesNode dependenciesNode, + DependenciesNode dependenciesNode, PackageDependency dependency, + bool sdkDependencies = false, bool topLevel = false) { return dependency.Dependencies - .Select (item => PackageDependencyNode.Create (dependenciesNode, item, topLevel)) + .Select (item => Create (dependenciesNode, item, sdkDependencies, topLevel)) .Where (item => item != null); } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/PackageDependencyNodeBuilder.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/PackageDependencyNodeBuilder.cs index b90fa4ca55..60cb7a5215 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/PackageDependencyNodeBuilder.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/PackageDependencyNodeBuilder.cs @@ -27,9 +27,9 @@ using System; using System.Collections.Generic; using MonoDevelop.Ide.Gui.Components; -using MonoDevelop.PackageManagement.Commands; +using MonoDevelop.DotNetCore.Commands; -namespace MonoDevelop.PackageManagement.NodeBuilders +namespace MonoDevelop.DotNetCore.NodeBuilders { class PackageDependencyNodeBuilder : TypeNodeBuilder { @@ -44,7 +44,7 @@ namespace MonoDevelop.PackageManagement.NodeBuilders } public override string ContextMenuAddinPath { - get { return "/MonoDevelop/PackageManagement/ContextMenu/ProjectPad/PackageDependency"; } + get { return "/MonoDevelop/DotNetCore/ContextMenu/ProjectPad/PackageDependency"; } } public override Type CommandHandlerType { diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/PackageDependenciesNode.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/PackageDependencyNodeCache.cs index b766e5ac82..08e289e9ff 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/PackageDependenciesNode.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/PackageDependencyNodeCache.cs @@ -1,10 +1,10 @@ // -// PackageDependenciesNode.cs +// PackageDependencyNodeCache.cs // // Author: // Matt Ward <matt.ward@xamarin.com> // -// Copyright (c) 2016 Xamarin Inc. (http://xamarin.com) +// Copyright (c) 2017 Xamarin Inc. (http://xamarin.com) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -23,7 +23,6 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - using System; using System.Collections.Generic; using System.Linq; @@ -31,46 +30,23 @@ using System.Threading; using System.Threading.Tasks; using MonoDevelop.Core; using MonoDevelop.Ide; -using MonoDevelop.Ide.Gui; +using MonoDevelop.PackageManagement; using MonoDevelop.Projects; -namespace MonoDevelop.PackageManagement.NodeBuilders +namespace MonoDevelop.DotNetCore.NodeBuilders { - class PackageDependenciesNode + class PackageDependencyNodeCache { - public static readonly string NodeName = "PackageDependencies"; - - DotNetProject project; List<PackageDependency> frameworks = new List<PackageDependency> (); Dictionary<string, PackageDependency> packageDependencies = new Dictionary<string, PackageDependency> (); CancellationTokenSource cancellationTokenSource; - public PackageDependenciesNode (DependenciesNode dependenciesNode) - { - project = dependenciesNode.Project; - } - - internal DotNetProject Project { - get { return project; } - } - - public string GetLabel () + public PackageDependencyNodeCache (DotNetProject project) { - return "NuGet"; + Project = project; } - public string GetSecondaryLabel () - { - return string.Empty; - } - - public IconId Icon { - get { return Stock.OpenReferenceFolder; } - } - - public IconId ClosedIcon { - get { return Stock.ClosedReferenceFolder; } - } + internal DotNetProject Project { get; private set; } public bool LoadedDependencies { get; private set; } @@ -114,7 +90,7 @@ namespace MonoDevelop.PackageManagement.NodeBuilders Task<IEnumerable<PackageDependency>> GetPackageDependenciesAsync (CancellationTokenSource tokenSource) { var configurationSelector = IdeApp.Workspace?.ActiveConfiguration ?? ConfigurationSelector.Default; - return Task.Run (() => project.GetPackageDependencies (configurationSelector, tokenSource.Token)); + return Task.Run (() => Project.GetPackageDependencies (configurationSelector, tokenSource.Token)); } void OnPackageDependenciesRead (Task<IEnumerable<PackageDependency>> task, CancellationTokenSource tokenSource) @@ -152,9 +128,11 @@ namespace MonoDevelop.PackageManagement.NodeBuilders } } - public IEnumerable<TargetFrameworkNode> GetTargetFrameworkNodes () + public IEnumerable<TargetFrameworkNode> GetTargetFrameworkNodes ( + DependenciesNode dependenciesNode, + bool sdkDependencies) { - return frameworks.Select (dependency => new TargetFrameworkNode (this, dependency)); + return frameworks.Select (dependency => new TargetFrameworkNode (dependenciesNode, dependency, sdkDependencies)); } public PackageDependency GetDependency (string dependency) @@ -166,10 +144,10 @@ namespace MonoDevelop.PackageManagement.NodeBuilders return null; } - public IEnumerable<PackageDependencyNode> GetProjectPackageReferencesAsDependencyNodes () + public IEnumerable<PackageDependencyNode> GetProjectPackageReferencesAsDependencyNodes (DependenciesNode dependenciesNode) { - return project.Items.OfType<ProjectPackageReference> () - .Select (reference => PackageDependencyNode.Create (this, reference)); + return Project.Items.OfType<ProjectPackageReference> () + .Select (reference => PackageDependencyNode.Create (dependenciesNode, reference)); } } } diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/ProjectDependenciesNode.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/ProjectDependenciesNode.cs new file mode 100644 index 0000000000..2a8f52ea07 --- /dev/null +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/ProjectDependenciesNode.cs @@ -0,0 +1,74 @@ +// +// ProjectDependenciesNode.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2017 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System.Collections.Generic; +using System.Linq; +using MonoDevelop.Core; +using MonoDevelop.Ide.Gui; +using MonoDevelop.Projects; + +namespace MonoDevelop.DotNetCore.NodeBuilders +{ + class ProjectDependenciesNode + { + public static readonly string NodeName = "ProjectDependencies"; + + public ProjectDependenciesNode (DotNetProject project) + { + Project = project; + } + + internal DotNetProject Project { get; private set; } + + public bool HasChildNodes () + { + return Project.References.Any (ProjectReferenceExtensions.IsProjectReference); + } + + public string GetLabel () + { + return GettextCatalog.GetString ("Projects"); + } + + public string GetSecondaryLabel () + { + return string.Empty; + } + + public IconId Icon { + get { return Stock.OpenReferenceFolder; } + } + + public IconId ClosedIcon { + get { return Stock.ClosedReferenceFolder; } + } + + public IEnumerable<ProjectReference> GetChildNodes () + { + return Project.References.Where (ProjectReferenceExtensions.IsProjectReference); + } + } +} diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/ProjectDependenciesNodeBuilder.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/ProjectDependenciesNodeBuilder.cs new file mode 100644 index 0000000000..56841efc10 --- /dev/null +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/ProjectDependenciesNodeBuilder.cs @@ -0,0 +1,68 @@ +// +// ProjectDependenciesNodeBuilder.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2017 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using MonoDevelop.DotNetCore.Commands; +using MonoDevelop.Ide.Gui.Components; + +namespace MonoDevelop.DotNetCore.NodeBuilders +{ + class ProjectDependenciesNodeBuilder : TypeNodeBuilder + { + public override Type NodeDataType { + get { return typeof(ProjectDependenciesNode); } + } + + public override Type CommandHandlerType { + get { return typeof(ProjectOrAssemblyDependenciesCommandHandler); } + } + + public override string GetNodeName (ITreeNavigator thisNode, object dataObject) + { + return ProjectDependenciesNode.NodeName; + } + + public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, NodeInfo nodeInfo) + { + var node = (ProjectDependenciesNode)dataObject; + nodeInfo.Label = node.GetLabel (); + nodeInfo.SecondaryLabel = node.GetSecondaryLabel (); + nodeInfo.Icon = Context.GetIcon (node.Icon); + nodeInfo.ClosedIcon = Context.GetIcon (node.ClosedIcon); + } + + public override bool HasChildNodes (ITreeBuilder builder, object dataObject) + { + return true; + } + + public override void BuildChildNodes (ITreeBuilder treeBuilder, object dataObject) + { + var node = (ProjectDependenciesNode)dataObject; + treeBuilder.AddChildren (node.GetChildNodes ()); + } + } +} diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/SdkDependenciesNode.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/SdkDependenciesNode.cs new file mode 100644 index 0000000000..57bd391991 --- /dev/null +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/SdkDependenciesNode.cs @@ -0,0 +1,82 @@ +// +// SdkDependenciesNode.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2017 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +using MonoDevelop.Projects; +using MonoDevelop.Core; +using MonoDevelop.Ide.Gui; +using System.Collections.Generic; + +namespace MonoDevelop.DotNetCore.NodeBuilders +{ + class SdkDependenciesNode + { + public static readonly string NodeName = "SdkDependencies"; + + public SdkDependenciesNode (DependenciesNode parentNode) + { + ParentNode = parentNode; + } + + internal DotNetProject Project { + get { return ParentNode.Project; } + } + + internal DependenciesNode ParentNode { get; private set; } + + public string GetLabel () + { + return GettextCatalog.GetString ("SDK"); + } + + public string GetSecondaryLabel () + { + return string.Empty; + } + + public IconId Icon { + get { return Stock.OpenReferenceFolder; } + } + + public IconId ClosedIcon { + get { return Stock.ClosedReferenceFolder; } + } + + public bool LoadedDependencies { + get { return ParentNode.PackageDependencyCache.LoadedDependencies; } + } + + public IEnumerable<TargetFrameworkNode> GetTargetFrameworkNodes () + { + return ParentNode.GetTargetFrameworkNodes (sdkDependencies: true); + } + + public PackageDependency GetDependency (string dependency) + { + return ParentNode.PackageDependencyCache.GetDependency (dependency); + } + } +} diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/SdkDependenciesNodeBuilder.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/SdkDependenciesNodeBuilder.cs new file mode 100644 index 0000000000..2f6878cb38 --- /dev/null +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/SdkDependenciesNodeBuilder.cs @@ -0,0 +1,112 @@ +// +// SdkDependenciesNodeBuilder.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2017 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +using System; +using System.Collections.Generic; +using System.Linq; +using MonoDevelop.Ide.Gui.Components; + +namespace MonoDevelop.DotNetCore.NodeBuilders +{ + class SdkDependenciesNodeBuilder : TypeNodeBuilder + { + public override Type NodeDataType { + get { return typeof(SdkDependenciesNode); } + } + + public override string GetNodeName (ITreeNavigator thisNode, object dataObject) + { + return SdkDependenciesNode.NodeName; + } + + public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, NodeInfo nodeInfo) + { + var node = (SdkDependenciesNode)dataObject; + nodeInfo.Label = node.GetLabel (); + nodeInfo.SecondaryLabel = node.GetSecondaryLabel (); + nodeInfo.Icon = Context.GetIcon (node.Icon); + nodeInfo.ClosedIcon = Context.GetIcon (node.ClosedIcon); + } + + public override bool HasChildNodes (ITreeBuilder builder, object dataObject) + { + return true; + } + + public override void BuildChildNodes (ITreeBuilder treeBuilder, object dataObject) + { + var dependenciesNode = (SdkDependenciesNode)dataObject; + if (dependenciesNode.LoadedDependencies) { + AddLoadedDependencyNodes (treeBuilder, dependenciesNode); + } + } + + void AddLoadedDependencyNodes (ITreeBuilder treeBuilder, SdkDependenciesNode dependenciesNode) + { + var frameworkNodes = GetTargetFrameworkNodes (dependenciesNode).ToList (); + if (frameworkNodes.Count > 1) { + treeBuilder.AddChildren (frameworkNodes); + } else if (frameworkNodes.Any ()) { + var frameworkNode = frameworkNodes.First (); + treeBuilder.AddChildren (frameworkNode.GetDependencyNodes ()); + } + } + + IEnumerable<TargetFrameworkNode> GetTargetFrameworkNodes (object dataObject) + { + var dependenciesNode = (SdkDependenciesNode)dataObject; + return dependenciesNode.GetTargetFrameworkNodes (); + } + + public override void OnNodeAdded (object dataObject) + { + var dependenciesNode = (SdkDependenciesNode)dataObject; + dependenciesNode.ParentNode.PackageDependencyCache.PackageDependenciesChanged += OnPackageDependenciesChanged; + } + + public override void OnNodeRemoved (object dataObject) + { + var dependenciesNode = (SdkDependenciesNode)dataObject; + dependenciesNode.ParentNode.PackageDependencyCache.PackageDependenciesChanged -= OnPackageDependenciesChanged; + } + + void OnPackageDependenciesChanged (object sender, EventArgs e) + { + var cache = (PackageDependencyNodeCache)sender; + var project = cache.Project; + ITreeBuilder builder = Context.GetTreeBuilder (project); + if (builder == null) + return; + + if (builder.MoveToChild (DependenciesNode.NodeName, typeof(DependenciesNode))) { + if (builder.MoveToChild (SdkDependenciesNode.NodeName, typeof(SdkDependenciesNode))) { + builder.UpdateAll (); + } + } + } + } +} diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/TargetFrameworkNode.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/TargetFrameworkNode.cs index 5b49550c00..8f52f283ad 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/TargetFrameworkNode.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/TargetFrameworkNode.cs @@ -29,33 +29,26 @@ using System.Linq; using MonoDevelop.Core; using MonoDevelop.Projects; -namespace MonoDevelop.PackageManagement.NodeBuilders +namespace MonoDevelop.DotNetCore.NodeBuilders { class TargetFrameworkNode { - PackageDependenciesNode dependenciesNode; + DependenciesNode dependenciesNode; PackageDependency dependency; - string name = string.Empty; + bool sdkDependencies; - public TargetFrameworkNode (PackageDependenciesNode dependenciesNode, PackageDependency dependency) + public TargetFrameworkNode ( + DependenciesNode dependenciesNode, + PackageDependency dependency, + bool sdkDependencies) { this.dependenciesNode = dependenciesNode; this.dependency = dependency; - } - - public TargetFrameworkNode (PackageDependenciesNode dependenciesNode, string name) - { - this.dependenciesNode = dependenciesNode; - this.name = name; + this.sdkDependencies = sdkDependencies; } public string Name { - get { - if (dependency != null) - return dependency.Name; - - return name; - } + get { return dependency.Name; } } public string GetLabel () @@ -65,10 +58,7 @@ namespace MonoDevelop.PackageManagement.NodeBuilders public string GetSecondaryLabel () { - if (dependency != null) - return string.Format ("({0})", dependency.Version); - - return string.Empty; + return string.Format ("({0})", dependency.Version); } public IconId GetIconId () @@ -78,21 +68,16 @@ namespace MonoDevelop.PackageManagement.NodeBuilders public bool HasDependencies () { - if (dependency != null) - return dependency.Dependencies.Any (); - - return false; + return dependency.Dependencies.Any (); } public IEnumerable<PackageDependencyNode> GetDependencyNodes () { - if (dependency != null) { - return PackageDependencyNode.GetDependencyNodes ( - dependenciesNode, - dependency, - topLevel: true); - } - return new PackageDependencyNode[0]; + return PackageDependencyNode.GetDependencyNodes ( + dependenciesNode, + dependency, + sdkDependencies, + topLevel: true); } } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/TargetFrameworkNodeBuilder.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/TargetFrameworkNodeBuilder.cs index 7d2c8e994c..6c85ec97c3 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/TargetFrameworkNodeBuilder.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/TargetFrameworkNodeBuilder.cs @@ -26,10 +26,9 @@ using System; using System.Collections.Generic; -using System.Linq; using MonoDevelop.Ide.Gui.Components; -namespace MonoDevelop.PackageManagement.NodeBuilders +namespace MonoDevelop.DotNetCore.NodeBuilders { class TargetFrameworkNodeBuilder : TypeNodeBuilder { diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreMSBuildProjectTests.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreMSBuildProjectTests.cs index 1ff47267da..42a17e4977 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreMSBuildProjectTests.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreMSBuildProjectTests.cs @@ -468,6 +468,48 @@ namespace MonoDevelop.DotNetCore.Tests } [Test] + public void WriteProject_NetStandardTargetFrameworkVersionChanged_TargetFrameworkUpdated () + { + CreateMSBuildProject ( + "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n" + + " <PropertyGroup>\r\n" + + " <OutputType>Exe</OutputType>\r\n" + + " <TargetFramework>netstandard1.0</TargetFramework>\r\n" + + " </PropertyGroup>\r\n" + + "</Project>"); + msbuildProject.Evaluate (); + ReadProject (); + project.Sdk = "Microsoft.NET.Sdk"; + + WriteProject (".NETStandard", "1.6"); + + string savedFramework = msbuildProject.GetGlobalPropertyGroup () + .GetValue ("TargetFramework"); + Assert.AreEqual ("netstandard1.6", savedFramework); + } + + [Test] + public void WriteProject_NetFrameworkVersionChanged_TargetFrameworkUpdated () + { + CreateMSBuildProject ( + "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n" + + " <PropertyGroup>\r\n" + + " <OutputType>Exe</OutputType>\r\n" + + " <TargetFramework>net45</TargetFramework>\r\n" + + " </PropertyGroup>\r\n" + + "</Project>"); + msbuildProject.Evaluate (); + ReadProject (); + project.Sdk = "Microsoft.NET.Sdk"; + + WriteProject (".NETFramework", "4.6"); + + string savedFramework = msbuildProject.GetGlobalPropertyGroup () + .GetValue ("TargetFramework"); + Assert.AreEqual ("net46", savedFramework); + } + + [Test] public void WriteProject_ProjectDefinesMultipleTargetFrameworksAndTargetFrameworkVersionChanged_TargetFrameworksUpdated () { CreateMSBuildProject ( diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.UnitTesting/DotNetCoreTestProvider.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.UnitTesting/DotNetCoreTestProvider.cs index 5de1d91960..a025cd5c10 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.UnitTesting/DotNetCoreTestProvider.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.UnitTesting/DotNetCoreTestProvider.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -using System; +using MonoDevelop.PackageManagement; using MonoDevelop.Projects; using MonoDevelop.UnitTesting; @@ -40,7 +40,8 @@ namespace MonoDevelop.DotNetCore.UnitTesting var dotNetCoreProject = project.GetFlavor<DotNetCoreProjectExtension> (); if (dotNetCoreProject != null) { - return new DotNetCoreProjectTestSuite (dotNetCoreProject); + if (project.HasPackageReference ("Microsoft.NET.Test.Sdk")) + return new DotNetCoreProjectTestSuite (dotNetCoreProject); } return null; diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.UnitTesting/IDotNetCoreTestProvider.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.UnitTesting/IDotNetCoreTestProvider.cs index 2ae0505f0a..46e7092bb4 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.UnitTesting/IDotNetCoreTestProvider.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.UnitTesting/IDotNetCoreTestProvider.cs @@ -29,7 +29,7 @@ using Microsoft.VisualStudio.TestPlatform.ObjectModel; namespace MonoDevelop.DotNetCore.UnitTesting { - public interface IDotNetCoreTestProvider + interface IDotNetCoreTestProvider { IEnumerable<TestCase> GetTests (); } diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.csproj b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.csproj index 96f0f07b94..a8a157d84d 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.csproj +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.csproj @@ -11,6 +11,9 @@ <RootNamespace>MonoDevelop.DotNetCore</RootNamespace> <AssemblyName>MonoDevelop.DotNetCore</AssemblyName> <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> + <MonoLauncher Condition=" '$(VisualStudioVersion)' == '' ">mono </MonoLauncher> + <NuGetUrl>https://dotnet.myget.org/F/templating/api/v2/package/</NuGetUrl> + <TemplatesVersion>1.0.0-beta1-20170216-123</TemplatesVersion> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> @@ -40,27 +43,31 @@ <HintPath>..\..\..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <Private>False</Private> </Reference> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Runtime.Serialization" /> + <Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" /> + <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" /> + <Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" /> + <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" /> + <Reference Include="NuGet.Versioning"> + <HintPath>..\..\..\external\nuget-binary\NuGet.Versioning.dll</HintPath> + <Private>False</Private> + </Reference> <Reference Include="Microsoft.TestPlatform.CommunicationUtilities"> - <HintPath>..\..\..\packages\Microsoft.TestPlatform.TranslationLayer.15.0.0-preview-20170201-02\lib\net46\Microsoft.TestPlatform.CommunicationUtilities.dll</HintPath> + <HintPath>..\..\..\packages\Microsoft.TestPlatform.TranslationLayer.15.0.0\lib\net46\Microsoft.TestPlatform.CommunicationUtilities.dll</HintPath> </Reference> <Reference Include="Microsoft.TestPlatform.CoreUtilities"> - <HintPath>..\..\..\packages\Microsoft.TestPlatform.TranslationLayer.15.0.0-preview-20170201-02\lib\net46\Microsoft.TestPlatform.CoreUtilities.dll</HintPath> + <HintPath>..\..\..\packages\Microsoft.TestPlatform.TranslationLayer.15.0.0\lib\net46\Microsoft.TestPlatform.CoreUtilities.dll</HintPath> </Reference> <Reference Include="Microsoft.TestPlatform.VsTestConsole.TranslationLayer"> - <HintPath>..\..\..\packages\Microsoft.TestPlatform.TranslationLayer.15.0.0-preview-20170201-02\lib\net46\Microsoft.TestPlatform.VsTestConsole.TranslationLayer.dll</HintPath> + <HintPath>..\..\..\packages\Microsoft.TestPlatform.TranslationLayer.15.0.0\lib\net46\Microsoft.TestPlatform.VsTestConsole.TranslationLayer.dll</HintPath> </Reference> <Reference Include="Microsoft.VisualStudio.TestPlatform.Common"> - <HintPath>..\..\..\packages\Microsoft.TestPlatform.TranslationLayer.15.0.0-preview-20170201-02\lib\net46\Microsoft.VisualStudio.TestPlatform.Common.dll</HintPath> + <HintPath>..\..\..\packages\Microsoft.TestPlatform.TranslationLayer.15.0.0\lib\net46\Microsoft.VisualStudio.TestPlatform.Common.dll</HintPath> </Reference> <Reference Include="Microsoft.VisualStudio.TestPlatform.ObjectModel"> - <HintPath>..\..\..\packages\Microsoft.TestPlatform.TranslationLayer.15.0.0-preview-20170201-02\lib\net46\Microsoft.VisualStudio.TestPlatform.ObjectModel.dll</HintPath> + <HintPath>..\..\..\packages\Microsoft.TestPlatform.TranslationLayer.15.0.0\lib\net46\Microsoft.VisualStudio.TestPlatform.ObjectModel.dll</HintPath> </Reference> - <Reference Include="Microsoft.CSharp" /> - <Reference Include="System.Runtime.Serialization" /> - <Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" /> - <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" /> - <Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" /> - <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" /> </ItemGroup> <ItemGroup> <Compile Include="Properties\AssemblyInfo.cs" /> @@ -74,7 +81,6 @@ <Compile Include="MonoDevelop.DotNetCore.Templating\EmptyDirectoryRemover.cs" /> <Compile Include="MonoDevelop.DotNetCore.Templating\FileTemplateProcessor.cs" /> <Compile Include="MonoDevelop.DotNetCore\DotNetCoreNotInstalledDialog.cs" /> - <Compile Include="MonoDevelop.DotNetCore\DotNetCoreFolderNodeBuilderExtension.cs" /> <Compile Include="MonoDevelop.DotNetCore\DotNetCoreProjectFileRenamedHandler.cs" /> <Compile Include="MonoDevelop.DotNetCore\DotNetCoreProjectReloadMonitor.cs" /> <Compile Include="MonoDevelop.DotNetCore\DotNetCoreProjectReader.cs" /> @@ -93,7 +99,6 @@ <Compile Include="MonoDevelop.DotNetCore.UnitTesting\IDotNetCoreTestProvider.cs" /> <Compile Include="MonoDevelop.DotNetCore.UnitTesting\IDotNetCoreTestRunner.cs" /> <Compile Include="MonoDevelop.DotNetCore.UnitTesting\TestResultBuilder.cs" /> - <Compile Include="MonoDevelop.DotNetCore\DotNetCoreProjectNodeBuilderExtension.cs" /> <Compile Include="MonoDevelop.DotNetCore\DotNetCoreSdkVersion.cs" /> <Compile Include="MonoDevelop.DotNetCore\DotNetCliToolReference.cs" /> <Compile Include="MonoDevelop.DotNetCore\DotNetCoreRuntimeOptionsPanel.cs" /> @@ -107,15 +112,36 @@ <Compile Include="MonoDevelop.DotNetCore\TargetFrameworkMonikerExtensions.cs" /> <Compile Include="MonoDevelop.DotNetCore\FilePathExtensions.cs" /> <Compile Include="MonoDevelop.DotNetCore\MSBuildPropertyGroupExtensions.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\ProjectDependenciesNode.cs" /> + <Compile Include="MonoDevelop.DotNetCore\ProjectReferenceExtensions.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\ProjectDependenciesNodeBuilder.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\AssemblyDependenciesNodeBuilder.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\AssemblyDependenciesNode.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\DotNetCoreProjectReferencesNodeBuilderExtension.cs" /> + <Compile Include="MonoDevelop.DotNetCore\DotNetMigrate.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\DependenciesNode.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\DependenciesNodeBuilder.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\DependenciesNodeBuilderExtension.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\PackageDependenciesNode.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\PackageDependenciesNodeBuilder.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\PackageDependencyNode.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\PackageDependencyNodeBuilder.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\TargetFrameworkNode.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\TargetFrameworkNodeBuilder.cs" /> + <Compile Include="MonoDevelop.DotNetCore.Commands\ProjectOrAssemblyDependenciesCommandHandler.cs" /> + <Compile Include="MonoDevelop.DotNetCore.Commands\PackageDependenciesNodeCommandHandler.cs" /> + <Compile Include="MonoDevelop.DotNetCore.Commands\PackageDependencyNodeCommandHandler.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\DotNetCoreFolderNodeBuilderExtension.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\DotNetCoreProjectNodeBuilderExtension.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\PackageDependencyNodeCache.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\SdkDependenciesNode.cs" /> + <Compile Include="MonoDevelop.DotNetCore.NodeBuilders\SdkDependenciesNodeBuilder.cs" /> + <Compile Include="MonoDevelop.DotNetCore\DotNetCoreRunConfigurationEditor.cs" /> + <Compile Include="MonoDevelop.DotNetCore\DotNetCoreRunConfiguration.cs" /> </ItemGroup> <ItemGroup> <Folder Include="MonoDevelop.DotNetCore\" /> - <Folder Include="Templates\" /> - <Folder Include="Templates\Projects\" /> - <Folder Include="Templates\Projects\Console\" /> <Folder Include="MonoDevelop.DotNetCore.Templating\" /> - <Folder Include="Templates\Projects\Library\" /> - <Folder Include="Templates\Projects\EmptyWeb\" /> <Folder Include="MonoDevelop.DotNetCore.UnitTesting\" /> </ItemGroup> <ItemGroup> @@ -159,6 +185,11 @@ <Name>MonoDevelop.UnitTesting</Name> <Private>False</Private> </ProjectReference> + <ProjectReference Include="..\..\..\external\xwt\Xwt\Xwt.csproj"> + <Project>{92494904-35FA-4DC9-BDE9-3A3E87AC49D3}</Project> + <Name>Xwt</Name> + <Private>False</Private> + </ProjectReference> </ItemGroup> <ItemGroup> <EmbeddedResource Include="Properties\MonoDevelop.DotNetCore.addin.xml"> @@ -170,61 +201,40 @@ <InternalsVisibleTo Include="MonoDevelop.DotNetCore.Tests" /> </ItemGroup> <ItemGroup> - <None Include="Templates\Projects\Console\ConsoleProject.csproj"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\Console\ConsoleProject.xpt.xml"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\Console\ConsoleProject.Program.cs.xft.xml"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\Console\ConsoleProject.Program.cs"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\Library\LibraryProject.csproj"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\Library\LibraryProject.MyClass.cs"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\Library\LibraryProject.MyClass.cs.xft.xml"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\Library\LibraryProject.xpt.xml"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\EmptyWeb\EmptyWebProject.csproj"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\EmptyWeb\EmptyWebProject.Program.cs"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\EmptyWeb\EmptyWebProject.Program.cs.xft.xml"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\EmptyWeb\EmptyWebProject.xpt.xml"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\EmptyWeb\EmptyWebProject.Startup.cs.xft.xml"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\EmptyWeb\EmptyWebProject.Startup.cs"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> <None Include="packages.config" /> - <None Include="Templates\Projects\XUnitTest\XUnitTestProject.Test.cs.xft.xml"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\XUnitTest\XUnitTestProject.csproj"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\XUnitTest\XUnitTestProject.xpt.xml"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> - <None Include="Templates\Projects\XUnitTest\XUnitTestProject.Test.cs"> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> - </None> + <None Include="pull-package.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <Target Name="CompilePullPackage" Inputs="pull-package.cs" Outputs="pull-package.exe"> + <Csc Sources="pull-package.cs" OutputAssembly="pull-package.exe" ToolExe="$(CscToolExe)" ToolPath="$(CscToolPath)" /> + </Target> + <Target Name="DownloadTemplates" BeforeTargets="Build" DependsOnTargets="CompilePullPackage"> + <ItemGroup> + <NuGetPackage Include="Microsoft.DotNet.Common.ProjectTemplates.1.x"> + <Url>$(NuGetUrl)Microsoft.DotNet.Common.ProjectTemplates.1.x/$(TemplatesVersion)</Url> + <OutputPackage>$(OutputPath)Templates\Microsoft.DotNet.Common.ProjectTemplates.1.x.$(TemplatesVersion).nupkg</OutputPackage> + </NuGetPackage> + <NuGetPackage Include="Microsoft.DotNet.Common.ProjectTemplates.2.0"> + <Url>$(NuGetUrl)Microsoft.DotNet.Common.ProjectTemplates.2.0/$(TemplatesVersion)</Url> + <OutputPackage>$(OutputPath)Templates\Microsoft.DotNet.Common.ProjectTemplates.2.0.$(TemplatesVersion).nupkg</OutputPackage> + </NuGetPackage> + <NuGetPackage Include="Microsoft.DotNet.Test.ProjectTemplates.1.x"> + <Url>$(NuGetUrl)Microsoft.DotNet.Test.ProjectTemplates.1.x/$(TemplatesVersion)</Url> + <OutputPackage>$(OutputPath)Templates\Microsoft.DotNet.Test.ProjectTemplates.1.x.$(TemplatesVersion).nupkg</OutputPackage> + </NuGetPackage> + <NuGetPackage Include="Microsoft.DotNet.Test.ProjectTemplates.2.0"> + <Url>$(NuGetUrl)Microsoft.DotNet.Test.ProjectTemplates.2.0/$(TemplatesVersion)</Url> + <OutputPackage>$(OutputPath)Templates\Microsoft.DotNet.Test.ProjectTemplates.2.0.$(TemplatesVersion).nupkg</OutputPackage> + </NuGetPackage> + <NuGetPackage Include="Microsoft.DotNet.Web.ProjectTemplates.1.x"> + <Url>$(NuGetUrl)Microsoft.DotNet.Web.ProjectTemplates.1.x/$(TemplatesVersion)</Url> + <OutputPackage>$(OutputPath)Templates\Microsoft.DotNet.Web.ProjectTemplates.1.x.$(TemplatesVersion).nupkg</OutputPackage> + </NuGetPackage> + <NuGetPackage Include="Microsoft.DotNet.Web.ProjectTemplates.2.0"> + <Url>$(NuGetUrl)Microsoft.DotNet.Web.ProjectTemplates.2.0/$(TemplatesVersion)</Url> + <OutputPackage>$(OutputPath)Templates\Microsoft.DotNet.Web.ProjectTemplates.2.0.$(TemplatesVersion).nupkg</OutputPackage> + </NuGetPackage> + </ItemGroup> + <Exec Command="$(MonoLauncher)$(MSBuildProjectDirectory)\pull-package.exe %(NuGetPackage.Url) %(NuGetPackage.OutputPackage)" Condition="!Exists('%(NuGetPackage.OutputPackage)')" WorkingDirectory="$(MSBuildProjectDirectory)" /> + </Target> </Project> diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreExecutionCommand.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreExecutionCommand.cs index 19360afff5..f9ab6ffa6f 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreExecutionCommand.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreExecutionCommand.cs @@ -45,5 +45,9 @@ namespace MonoDevelop.DotNetCore public bool PauseConsoleOutput { get; set; } public bool ExternalConsole { get; set; } + public bool LaunchBrowser { get; set; } + public string LaunchURL { get; set; } + public string ApplicationURL { get; set; } + public PipeTransportSettings PipeTransport { get; set; } } -} +}
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreExecutionHandler.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreExecutionHandler.cs index 0d3b2f54da..b58de1b8b3 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreExecutionHandler.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreExecutionHandler.cs @@ -26,6 +26,12 @@ using MonoDevelop.Core; using MonoDevelop.Core.Execution; +using MonoDevelop.Ide; +using System; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System.Net.Sockets; namespace MonoDevelop.DotNetCore { @@ -40,12 +46,60 @@ namespace MonoDevelop.DotNetCore { var dotNetCoreCommand = (DotNetCoreExecutionCommand)command; - return Runtime.ProcessService.StartConsoleProcess ( + // ApplicationURL is passed to ASP.NET Core server via ASPNETCORE_URLS enviorment variable + var envVariables = dotNetCoreCommand.EnvironmentVariables.ToDictionary ((arg) => arg.Key, (arg) => arg.Value); + envVariables ["ASPNETCORE_URLS"] = dotNetCoreCommand.ApplicationURL; + + var process = Runtime.ProcessService.StartConsoleProcess ( dotNetCoreCommand.Command, dotNetCoreCommand.Arguments, dotNetCoreCommand.WorkingDirectory, console, - dotNetCoreCommand.EnvironmentVariables); + envVariables); + if (dotNetCoreCommand.LaunchBrowser) { + LaunchBrowser (dotNetCoreCommand.ApplicationURL, dotNetCoreCommand.LaunchURL, process.Task).Ignore (); + } + return process; + } + + public static async Task LaunchBrowser (string appUrl, string launchUrl, Task processTask) + { + launchUrl = launchUrl ?? ""; + Uri launchUri; + //Check if lanuchUrl is valid absolute url and use it if it is... + if (!Uri.TryCreate (launchUrl, UriKind.Absolute, out launchUri)) { + //Otherwise check if appUrl is valid absolute and lanuchUrl is relative then concat them... + Uri appUri; + if (!Uri.TryCreate (appUrl, UriKind.Absolute, out appUri)) { + LoggingService.LogWarning ("Failed to launch browser because invalid launch and app urls."); + return; + } + if (!Uri.TryCreate (launchUrl, UriKind.Relative, out launchUri)) { + LoggingService.LogWarning ("Failed to launch browser because invalid launch url."); + return; + } + launchUri = new Uri (appUri, launchUri); + } + + //Try to connect every 50ms while process is running + while (!processTask.IsCompleted) { + await Task.Delay (50); + using (var tcpClient = new TcpClient ()) { + try { + tcpClient.Connect (launchUri.Host, launchUri.Port); + break; + } catch { + } + } + } + + if (processTask.IsCompleted) { + LoggingService.LogDebug ("Failed to launch browser because process exited before server started listening."); + return; + } + + // Process is still alive hence we succesfully connected inside loop to web server, launch browser + DesktopService.ShowUrl (launchUri.AbsoluteUri); } } } diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectBuilderMaintainer.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectBuilderMaintainer.cs index 16b70001ae..6d2e63c70d 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectBuilderMaintainer.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectBuilderMaintainer.cs @@ -58,7 +58,7 @@ namespace MonoDevelop.DotNetCore { foreach (DotNetProject project in GetAllNonDotNetCoreProjects (dotNetCoreProject.ParentSolution)) { foreach (ProjectReference projectReference in project.References) { - if (projectReference.ReferenceType == ReferenceType.Project) { + if (projectReference.IsProjectReference ()) { Project resolvedProject = projectReference.ResolveProject (project.ParentSolution); if (resolvedProject == dotNetCoreProject) { yield return project; diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs index f84af7db30..1e5cf06cbc 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs @@ -132,16 +132,20 @@ namespace MonoDevelop.DotNetCore DotNetCoreExecutionCommand CreateDotNetCoreExecutionCommand (ConfigurationSelector configSel, DotNetProjectConfiguration configuration, ProjectRunConfiguration runConfiguration) { FilePath outputFileName = GetOutputFileName (configuration); - var assemblyRunConfiguration = runConfiguration as AssemblyRunConfiguration; + var dotnetCoreRunConfiguration = runConfiguration as DotNetCoreRunConfiguration; return new DotNetCoreExecutionCommand ( - assemblyRunConfiguration?.StartWorkingDirectory ?? Project.BaseDirectory, + string.IsNullOrEmpty (dotnetCoreRunConfiguration?.StartWorkingDirectory) ? Project.BaseDirectory : dotnetCoreRunConfiguration.StartWorkingDirectory, outputFileName, - assemblyRunConfiguration?.StartArguments + dotnetCoreRunConfiguration?.StartArguments ) { - EnvironmentVariables = assemblyRunConfiguration?.EnvironmentVariables, - PauseConsoleOutput = assemblyRunConfiguration?.PauseConsoleOutput ?? false, - ExternalConsole = assemblyRunConfiguration?.ExternalConsole ?? false + EnvironmentVariables = dotnetCoreRunConfiguration?.EnvironmentVariables, + PauseConsoleOutput = dotnetCoreRunConfiguration?.PauseConsoleOutput ?? false, + ExternalConsole = dotnetCoreRunConfiguration?.ExternalConsole ?? false, + LaunchBrowser = dotnetCoreRunConfiguration?.LaunchBrowser ?? false, + LaunchURL = dotnetCoreRunConfiguration?.LaunchUrl, + ApplicationURL = dotnetCoreRunConfiguration?.ApplicationURL, + PipeTransport = dotnetCoreRunConfiguration?.PipeTransport }; } @@ -351,6 +355,10 @@ namespace MonoDevelop.DotNetCore get { return dotNetCoreMSBuildProject.HasSdk; } } + public bool IsWeb { + get { return (dotNetCoreMSBuildProject.Sdk?.IndexOf ("Microsoft.NET.Sdk.Web", System.StringComparison.OrdinalIgnoreCase) ?? -1) != -1; } + } + protected override void OnPrepareForEvaluation (MSBuildProject project) { base.OnPrepareForEvaluation (project); @@ -474,10 +482,30 @@ namespace MonoDevelop.DotNetCore internal IEnumerable<TargetFramework> GetSupportedTargetFrameworks () { - var supportedTargetFrameworks = new DotNetCoreProjectSupportedTargetFrameworks (Project.TargetFramework); + var supportedTargetFrameworks = new DotNetCoreProjectSupportedTargetFrameworks (Project); return supportedTargetFrameworks.GetFrameworks (); } + /// <summary> + /// Handle a new project being created and added to a new solution. In this case + /// the NuGet packages should be restored. Need to avoid running a restore when + /// a solution is being opened so check that project's parent solution is open in + /// the IDE. + /// </summary> + protected override void OnBoundToSolution () + { + base.OnBoundToSolution (); + + if (Project.Loading) + return; + + if (IdeApp.ProjectOperations.CurrentSelectedSolution != Project.ParentSolution) + return; + + if (ProjectNeedsRestore ()) + RestorePackagesInProjectHandler.Run (Project); + } + internal bool RestoreAfterSave { get; set; } protected override Task OnSave (ProgressMonitor monitor) @@ -513,5 +541,10 @@ namespace MonoDevelop.DotNetCore }); }); } + + protected override ProjectRunConfiguration OnCreateRunConfiguration (string name) + { + return new DotNetCoreRunConfiguration (name); + } } } diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectSupportedTargetFrameworks.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectSupportedTargetFrameworks.cs index edf4ce4cef..e4b14dc9ee 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectSupportedTargetFrameworks.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectSupportedTargetFrameworks.cs @@ -27,6 +27,7 @@ using System.Collections.Generic; using MonoDevelop.Core; using MonoDevelop.Core.Assemblies; +using MonoDevelop.Projects; namespace MonoDevelop.DotNetCore { @@ -35,11 +36,13 @@ namespace MonoDevelop.DotNetCore const int HighestNetStandard1xMinorVersionSupported = 6; const int HighestNetCoreApp1xMinorVersionSupported = 1; + DotNetProject project; TargetFramework framework; - public DotNetCoreProjectSupportedTargetFrameworks (TargetFramework framework) + public DotNetCoreProjectSupportedTargetFrameworks (DotNetProject project) { - this.framework = framework; + this.project = project; + framework = project.TargetFramework; } public IEnumerable<TargetFramework> GetFrameworks () @@ -48,6 +51,8 @@ namespace MonoDevelop.DotNetCore return GetNetStandardTargetFrameworks (); } else if (framework.IsNetCoreApp ()) { return GetNetCoreAppTargetFrameworks (); + } else if (framework.IsNetFramework ()) { + return GetNetFrameworkTargetFrameworks (); } return new TargetFramework [0]; @@ -71,5 +76,15 @@ namespace MonoDevelop.DotNetCore { return GetTargetFrameworksVersion1x (".NETCoreApp", HighestNetCoreApp1xMinorVersionSupported); } + + IEnumerable<TargetFramework> GetNetFrameworkTargetFrameworks () + { + foreach (var targetFramework in Runtime.SystemAssemblyService.GetTargetFrameworks ()) { + if (!targetFramework.Hidden && + targetFramework.IsNetFramework () && + project.TargetRuntime.IsInstalled (targetFramework)) + yield return targetFramework; + } + } } } diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreRunConfiguration.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreRunConfiguration.cs new file mode 100644 index 0000000000..ff3118f41d --- /dev/null +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreRunConfiguration.cs @@ -0,0 +1,107 @@ +// +// DotNetCoreRunConfiguration.cs +// +// Author: +// David Karlaš <david.karlas@xamarin.com> +// +// Copyright (c) 2017 Xamarin, Inc (http://www.xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using System.Net; +using MonoDevelop.Core.Serialization; +using MonoDevelop.Projects; +using System.Net.Sockets; +using System.Collections.Generic; +using System.Linq; + +namespace MonoDevelop.DotNetCore +{ + public class DotNetCoreRunConfiguration : AssemblyRunConfiguration + { + public DotNetCoreRunConfiguration (string name) + : base (name) + { + } + + protected override void Initialize (Project project) + { + base.Initialize (project); + if (project.GetFlavor<DotNetCoreProjectExtension> ()?.IsWeb ?? false && string.IsNullOrEmpty (ApplicationURL)) { + var tcpListner = new TcpListener (IPAddress.Loopback, 0); + tcpListner.Start (); + ApplicationURL = $"http://localhost:{((IPEndPoint)tcpListner.LocalEndpoint).Port}"; + tcpListner.Stop (); + } + } + + [ItemProperty (DefaultValue = true)] + public bool LaunchBrowser { get; set; } = true; + + [ItemProperty (DefaultValue = null)] + public string LaunchUrl { get; set; } + + [ItemProperty (DefaultValue = null)] + public string ApplicationURL { get; set; } + + [ItemProperty (DefaultValue = null)] + public PipeTransportSettings PipeTransport { get; set; } + + protected override void OnCopyFrom (ProjectRunConfiguration config, bool isRename) + { + base.OnCopyFrom (config, isRename); + + var other = (DotNetCoreRunConfiguration)config; + + LaunchBrowser = other.LaunchBrowser; + LaunchUrl = other.LaunchUrl; + ApplicationURL = other.ApplicationURL; + if (other.PipeTransport == null) + PipeTransport = null; + else + PipeTransport = new PipeTransportSettings (other.PipeTransport); + } + } + + public class PipeTransportSettings + { + public PipeTransportSettings () + { } + + public PipeTransportSettings (PipeTransportSettings copy) + { + WorkingDirectory = copy.WorkingDirectory; + Program = copy.Program; + Arguments = copy.Arguments.ToArray ();//make copy of array + DebuggerPath = copy.DebuggerPath; + EnvironmentVariables = new EnvironmentVariableCollection (copy.EnvironmentVariables); + } + + [ItemProperty (DefaultValue = null)] + public string WorkingDirectory { get; set; } + [ItemProperty (DefaultValue = null)] + public string Program { get; set; } + [ItemProperty (SkipEmpty = true)] + public string [] Arguments { get; set; } = new string [0]; + [ItemProperty (DefaultValue = null)] + public string DebuggerPath { get; set; } + [ItemProperty (SkipEmpty = true, WrapObject = false)] + public EnvironmentVariableCollection EnvironmentVariables { get; private set; } = new EnvironmentVariableCollection (); + } +} diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreRunConfigurationEditor.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreRunConfigurationEditor.cs new file mode 100644 index 0000000000..63bee530eb --- /dev/null +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreRunConfigurationEditor.cs @@ -0,0 +1,166 @@ +// +// DotNetCoreRunConfigurationEditor.cs +// +// Author: +// David Karlaš <david.karlas@xamarin.com> +// +// Copyright (c) 2017 Xamarin, Inc (http://www.xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using MonoDevelop.Components; +using MonoDevelop.Core; +using MonoDevelop.Ide; +using MonoDevelop.Ide.Execution; +using MonoDevelop.Ide.Projects.OptionPanels; +using MonoDevelop.Projects; +using Xwt; +using Xwt.Drawing; + +namespace MonoDevelop.DotNetCore +{ + class DotNetCoreRunConfigurationEditor : RunConfigurationEditor + { + DotNetCoreRunConfigurationEditorWidget widget; + + public DotNetCoreRunConfigurationEditor () + { + widget = new DotNetCoreRunConfigurationEditorWidget (); + } + + public override Control CreateControl () + { + return new XwtControl (widget); + } + + public override void Load (Project project, SolutionItemRunConfiguration config) + { + widget.LoadCore (project, (DotNetCoreRunConfiguration)config); + widget.Changed += (sender, e) => NotifyChanged (); + } + + public override void Save () + { + widget.SaveCore (); + } + + public override bool Validate () + { + return widget.ValidateCore (); + } + } + + class DotNetCoreRunConfigurationEditorWidget : DotNetRunConfigurationEditorWidget + { + DotNetCoreRunConfiguration config; + CheckBox launchBrowser; + TextEntry launchUrl; + TextEntry applicationUrl; + XwtBoxTooltip applicationUrlWarningTooltip; + + public DotNetCoreRunConfigurationEditorWidget () + : base (false) + { + + } + + public void LoadCore (Project project, DotNetCoreRunConfiguration config) + { + this.config = config; + base.Load (project, config); + var coreProject = project.GetFlavor<DotNetCoreProjectExtension> (); + if (coreProject == null || !coreProject.IsWeb) + return; + var mainBox = new VBox (); + mainBox.Margin = 24; + + var appUrlTable = new Table (); + appUrlTable.Add (new Label (GettextCatalog.GetString ("App URL:")), 0, 0); + var applicationUrlBox = new HBox (); + applicationUrlWarningTooltip = new XwtBoxTooltip (new Xwt.ImageView (ImageService.GetIcon (Ide.Gui.Stock.Warning, Gtk.IconSize.Menu))) { + ToolTip = GettextCatalog.GetString ("Invalid URL"), + Severity = Ide.Tasks.TaskSeverity.Warning + }; + applicationUrlBox.PackStart (applicationUrl = new TextEntry (), true, true); + applicationUrlBox.PackStart (applicationUrlWarningTooltip); + appUrlTable.Add (applicationUrlBox, 1, 0, hexpand: true); + appUrlTable.Add (new Label (GettextCatalog.GetString ("Where your app should listen for connections")) { Sensitive = false }, 1, 1, hexpand: true); + mainBox.PackStart (appUrlTable); + + mainBox.PackStart (launchBrowser = new CheckBox (GettextCatalog.GetString ("Open URL in web browser when app starts:")), marginTop: 16); + + var browserTable = new Table (); + browserTable.MarginLeft = 16; + var offset = 0; + //offset = 1; // just so uncommenting Browser Combobox works as expected + //browserTable.Add (new Label (GettextCatalog.GetString ("Web Browser:")), 0, 0, hpos: WidgetPlacement.End); + //var browsersCombobox = new ComboBox (); + //browsersCombobox.Items.Add ("Chrome"); + //browsersCombobox.Items.Add ("Firefox"); + //browsersCombobox.Items.Add ("Opera"); + //browsersCombobox.Items.Add ("Safari"); + //browserTable.Add (browsersCombobox, 1, 0, hpos: WidgetPlacement.Start); + browserTable.Add (launchUrl = new TextEntry (), 1, offset, hexpand: true); + browserTable.Add (new Label (GettextCatalog.GetString ("URL:")), 0, offset, hpos: WidgetPlacement.End); + browserTable.Add (new Label (GettextCatalog.GetString ("Absolute or relative to App URL")) { Sensitive = false }, 1, offset + 1); + mainBox.PackStart (browserTable); + + Add (mainBox, GettextCatalog.GetString ("ASP.NET Core")); + + launchBrowser.Active = config.LaunchBrowser; + launchUrl.Text = config.LaunchUrl; + applicationUrl.Text = config.ApplicationURL; + + UpdateUI (); + + launchBrowser.Toggled += delegate { NotifyChanged (); UpdateUI (); }; + launchUrl.Changed += delegate { NotifyChanged (); }; + applicationUrl.Changed += delegate { NotifyChanged (); UpdateUI (); }; + } + + void UpdateUI () + { + launchUrl.Sensitive = launchBrowser.Active; + applicationUrlWarningTooltip.Visible = !IsValidUrl (applicationUrl.Text); + } + + bool IsValidUrl (string url) + { + Uri dummy; + return Uri.TryCreate (url, UriKind.Absolute, out dummy); + } + + public void SaveCore () + { + base.Save (); + if (applicationUrl != null) {//applicationUrl != null means it's web project, hence set values + config.LaunchBrowser = launchBrowser.Active; + config.LaunchUrl = launchUrl.Text; + config.ApplicationURL = applicationUrl.Text; + } + } + + public bool ValidateCore () + { + if (!base.Validate ()) + return false; + return applicationUrl == null || IsValidUrl (applicationUrl.Text);//applicationUrl == null means it's not web project, hence it's valid config + } + } +} diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetMigrate.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetMigrate.cs new file mode 100644 index 0000000000..b12e4d22d9 --- /dev/null +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetMigrate.cs @@ -0,0 +1,196 @@ +// +// DotNetMigrate.cs +// +// Author: +// David Karlaš <david.karlas@xamarin.com> +// +// Copyright (c) 2017 Xamarin, Inc (http://www.xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using MonoDevelop.Components.Commands; +using MonoDevelop.Core; +using MonoDevelop.Ide; +using MonoDevelop.Ide.Gui; +using MonoDevelop.Ide.Gui.Components; +using MonoDevelop.Ide.Projects; +using MonoDevelop.PackageManagement.Commands; +using MonoDevelop.Projects; + +namespace MonoDevelop.DotNetCore +{ + // Put better message on .xproj projects to explain user what can be done + class ProjXNodeBuilderExtension : NodeBuilderExtension + { + public override bool CanBuildNode (Type dataType) + { + return typeof (UnknownProject).IsAssignableFrom (dataType); + } + + public override void BuildNode (ITreeBuilder treeBuilder, object dataObject, NodeInfo nodeInfo) + { + if (!DotNetMigrateCommandHandler.IsMigratableProject (dataObject as UnknownProject)) + return; + + nodeInfo.StatusMessage = GettextCatalog.GetString ("Project format is not supported by {0}.\nUse 'Migrate to New Format' command on solution or single project to migrate to format supported by {0}.", BrandingService.ApplicationName); + } + } + + class DotNetMigrateCommandHandler : CommandHandler + { + public static bool IsMigratableProject (UnknownProject project) + { + if (project == null) + return false; + if (!project.FileName.HasExtension (".xproj")) + return false; + return File.Exists (Path.Combine (Path.GetDirectoryName (project.FileName), "project.json")); + } + + async Task<bool> Migrate (UnknownProject project, Solution solution, ProgressMonitor monitor) + { + FilePath projectFile; + string migrationFile; + if (project == null) { + migrationFile = solution.FileName; + } else { + projectFile = project.FileName; + migrationFile = Path.Combine (Path.GetDirectoryName (projectFile), "project.json"); + } + var dotnetPath = new DotNetCorePath (); + if (dotnetPath.IsMissing) { + monitor.ReportError (GettextCatalog.GetString (".NET Core is not installed")); + return false; + } + + var process = Runtime.ProcessService.StartProcess ( + dotnetPath.FileName, + $"migrate \"{migrationFile}\"", + Path.GetDirectoryName (migrationFile), + monitor.Log, + monitor.Log, + null); + + await process.Task; + + if (process.ExitCode > 0) { + monitor.ReportError (GettextCatalog.GetString ("An unspecified error occurred while running '{0}'", $"dotnet migrate({process.ExitCode})")); + return false; + } + + if (project != null) { + string newProjectFile; + if (File.Exists (Path.ChangeExtension (projectFile, ".csproj"))) + newProjectFile = Path.ChangeExtension (projectFile, ".csproj"); + else if (File.Exists (Path.ChangeExtension (projectFile, ".fsproj"))) + newProjectFile = Path.ChangeExtension (projectFile, ".fsproj"); + else if (File.Exists (Path.ChangeExtension (projectFile, ".vbproj"))) + newProjectFile = Path.ChangeExtension (projectFile, ".vbproj"); + else { + monitor.ReportError (GettextCatalog.GetString ("Migrated project file not found.")); + return false; + } + var newProject = await project.ParentFolder.AddItem (monitor, newProjectFile); + project.ParentFolder.Items.Remove (project); + await newProject.ParentSolution.SaveAsync (monitor); + + RestorePackagesInProjectHandler.Run ((DotNetProject)newProject); + } else { + solution.NeedsReload = true; + FileService.NotifyFileChanged (solution.FileName); + } + return true; + } + + protected override async void Run (object dataItem) + { + var project = IdeApp.ProjectOperations.CurrentSelectedProject as UnknownProject; + var solution = IdeApp.ProjectOperations.CurrentSelectedSolution; + UnknownProject [] selectedProjects = null; + bool wholeSolution = false; + if (project == null) { + // ContextMenu on Solution + var dlg = new ProjectSelectorDialog (); + try { + dlg.Title = GettextCatalog.GetString ("Select projects to migrate"); + dlg.RootItem = solution; + dlg.AllowEmptySelection = false; + dlg.SelectableFilter = (arg) => IsMigratableProject (arg as UnknownProject); + dlg.SelectedItem = IdeApp.ProjectOperations.CurrentSelectedObject; + dlg.SelectableItemTypes = new Type [] { typeof (UnknownProject) }; + dlg.ActiveItems = solution.GetAllProjects ().OfType<UnknownProject> ().Where (p => p.FileName.HasExtension (".xproj")); + dlg.ShowCheckboxes = true; + if (MessageService.RunCustomDialog (dlg, IdeApp.Workbench.RootWindow) == (int)Gtk.ResponseType.Ok) { + if (dlg.ActiveItems.SequenceEqual (solution.GetAllProjects ().OfType<UnknownProject> ().Where (p => p.FileName.HasExtension (".xproj")))) + wholeSolution = true; + else + selectedProjects = dlg.ActiveItems.OfType<UnknownProject> ().ToArray (); + } else { + return; + } + } finally { + dlg.Destroy (); + dlg.Dispose (); + } + } else { + selectedProjects = new UnknownProject [] { project }; + } + using (var monitor = CreateOutputProgressMonitor ()) { + try { + monitor.BeginTask (GettextCatalog.GetString ("Migrating…"), 1); + if (wholeSolution) { + if (!await Migrate (null, solution, monitor)) + return; + } else { + foreach (var proj in selectedProjects) + if (!await Migrate (proj, solution, monitor)) + return; + } + monitor.ReportSuccess (GettextCatalog.GetString ("Successfully migrated")); + } catch (Exception e) { + monitor.ReportError (GettextCatalog.GetString ("Failed to migrate") + Environment.NewLine + e); + } + } + } + + ProgressMonitor CreateOutputProgressMonitor () + { + return IdeApp.Workbench.ProgressMonitors.GetOutputProgressMonitor ( + "DotNetCoreMigration", + GettextCatalog.GetString (".NET Core Migration"), + Stock.PadExecute, + true, + true); + } + + protected override void Update (CommandInfo info) + { + if (IsMigratableProject (IdeApp.ProjectOperations.CurrentSelectedProject as UnknownProject)) + info.Visible = true; + else if (IdeApp.ProjectOperations.CurrentSelectedSolution?.GetAllProjects ().OfType<UnknownProject> ().Any (p => IsMigratableProject (p)) ?? false) + info.Visible = true; + else + info.Visible = false; + } + } +} diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreServices.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/ProjectReferenceExtensions.cs index cc4058c658..ba27b8ff7f 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreServices.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/ProjectReferenceExtensions.cs @@ -1,10 +1,10 @@ // -// DotNetCoreServices.cs +// ProjectReferenceExtensions.cs // // Author: // Matt Ward <matt.ward@xamarin.com> // -// Copyright (c) 2016 Xamarin Inc. (http://xamarin.com) +// Copyright (c) 2017 Xamarin Inc. (http://xamarin.com) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -23,18 +23,21 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -using MonoDevelop.Core; + +using MonoDevelop.Projects; namespace MonoDevelop.DotNetCore { - class DotNetCoreServices + static class ProjectReferenceExtensions { - static readonly DotNetCoreProjectFileRenamedHandler projectFileRenamedHandler = - new DotNetCoreProjectFileRenamedHandler (); + public static bool IsProjectReference (this ProjectReference reference) + { + return reference.ReferenceType == ReferenceType.Project; + } - public static void Initialize () + public static bool IsAssemblyReference (this ProjectReference reference) { - // Do nothing. + return reference.ReferenceType == ReferenceType.Assembly; } } } diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs index b2d3199969..2415245fc2 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs @@ -38,5 +38,10 @@ namespace MonoDevelop.DotNetCore { return framework.Id.Identifier == ".NETCoreApp"; } + + public static bool IsNetFramework (this TargetFramework framework) + { + return framework.Id.IsNetFramework (); + } } } diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkMonikerExtensions.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkMonikerExtensions.cs index ced06a7ec5..3cd0bdd459 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkMonikerExtensions.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkMonikerExtensions.cs @@ -32,6 +32,9 @@ namespace MonoDevelop.DotNetCore { public static string GetShortFrameworkName (this TargetFrameworkMoniker framework) { + if (framework.IsNetFramework ()) + return GetShortNetFrameworkName (framework); + string identifier = GetShortFrameworkIdentifier (framework); return identifier + framework.Version; } @@ -48,5 +51,15 @@ namespace MonoDevelop.DotNetCore return shortFrameworkIdentifier.ToLower (); } + + static string GetShortNetFrameworkName (TargetFrameworkMoniker framework) + { + return "net" + framework.Version.Replace (".", string.Empty); + } + + public static bool IsNetFramework (this TargetFrameworkMoniker framework) + { + return framework.Identifier == ".NETFramework"; + } } } diff --git a/main/src/addins/MonoDevelop.DotNetCore/Properties/MonoDevelop.DotNetCore.addin.xml b/main/src/addins/MonoDevelop.DotNetCore/Properties/MonoDevelop.DotNetCore.addin.xml index 6be9fdd51f..8be018a75e 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/Properties/MonoDevelop.DotNetCore.addin.xml +++ b/main/src/addins/MonoDevelop.DotNetCore/Properties/MonoDevelop.DotNetCore.addin.xml @@ -18,19 +18,79 @@ </Category> </Extension> - <Extension path="/MonoDevelop/Ide/ProjectTemplates"> - <ProjectTemplate - id="DotNetCoreConsoleProject" - file="Templates/Projects/Console/ConsoleProject.xpt.xml" /> - <ProjectTemplate - id="DotNetCoreLibraryProject" - file="Templates/Projects/Library/LibraryProject.xpt.xml" /> - <ProjectTemplate - id="DotNetCoreEmptyWebProject" - file="Templates/Projects/EmptyWeb/EmptyWebProject.xpt.xml" /> - <ProjectTemplate - id="DotNetCoreEmptyWebProject" - file="Templates/Projects/XUnitTest/XUnitTestProject.xpt.xml" /> + <Extension path="/MonoDevelop/Ide/Templates"> + <Template + id="Microsoft.Common.Console.CSharp" + _overrideDescription="Creates a new .NET Core console project." + path="Templates/Microsoft.DotNet.Common.ProjectTemplates.1.x.1.0.0-beta1-20170216-123.nupkg" + icon="md-console-project" + imageId="md-console-project" + category="netcore/app/general"/> + <Template + id="Microsoft.Common.Console.FSharp" + _overrideDescription="Creates a new .NET Core console project." + path="Templates/Microsoft.DotNet.Common.ProjectTemplates.1.x.1.0.0-beta1-20170216-123.nupkg" + icon="md-console-project" + imageId="md-console-project" + category="netcore/app/general"/> + <Template + _overrideName=".NET Standard Library" + _overrideDescription="Creates a new .NET Standard class library project." + id="Microsoft.Common.Library.CSharp" + path="Templates/Microsoft.DotNet.Common.ProjectTemplates.1.x.1.0.0-beta1-20170216-123.nupkg" + icon="md-library-project" + imageId="md-library-project" + category="multiplat/library/general" /> + <Template + _overrideName=".NET Standard Library" + _overrideDescription="Creates a new .NET Standard class library project." + id="Microsoft.Common.Library.FSharp" + path="Templates/Microsoft.DotNet.Common.ProjectTemplates.1.x.1.0.0-beta1-20170216-123.nupkg" + icon="md-library-project" + imageId="md-library-project" + category="multiplat/library/general" /> + <Template + id="Microsoft.Test.xUnit.CSharp" + _overrideDescription="Creates a new xUnit test project." + path="Templates/Microsoft.DotNet.Test.ProjectTemplates.1.x.1.0.0-beta1-20170216-123.nupkg" + icon="md-test-project" + imageId="md-test-project" + category="netcore/test/general" /> + <Template + id="Microsoft.Test.xUnit.FSharp" + _overrideDescription="Creates a new xUnit test project." + path="Templates/Microsoft.DotNet.Test.ProjectTemplates.1.x.1.0.0-beta1-20170216-123.nupkg" + icon="md-test-project" + imageId="md-test-project" + category="netcore/test/general" /> + <Template + id="Microsoft.Web.Empty.CSharp" + _overrideDescription="Creates a new ASP.NET Core web project." + path="Templates/Microsoft.DotNet.Web.ProjectTemplates.1.x.1.0.0-beta1-20170216-123.nupkg" + icon="md-aspnet-empty-project" + imageId="md-aspnet-empty-project" + category="netcore/app/aspnet" /> + <Template + id="Microsoft.Web.Mvc.CSharp" + _overrideDescription="Creates a new ASP.NET MVC Core web project." + path="Templates/Microsoft.DotNet.Web.ProjectTemplates.1.x.1.0.0-beta1-20170216-123.nupkg" + icon="md-aspnet-empty-project" + imageId="md-aspnet-empty-project" + category="netcore/app/aspnet" /> + <Template + id="Microsoft.Web.Mvc.FSharp" + _overrideDescription="Creates a new ASP.NET MVC Core web project." + path="Templates/Microsoft.DotNet.Web.ProjectTemplates.1.x.1.0.0-beta1-20170216-123.nupkg" + icon="md-aspnet-empty-project" + imageId="md-aspnet-empty-project" + category="netcore/app/aspnet" /> + <Template + id="Microsoft.Web.WebApi.CSharp" + _overrideDescription="Creates a new ASP.NET Web API Core web project." + path="Templates/Microsoft.DotNet.Web.ProjectTemplates.1.x.1.0.0-beta1-20170216-123.nupkg" + icon="md-aspnet-empty-project" + imageId="md-aspnet-empty-project" + category="netcore/app/aspnet" /> </Extension> <Extension path="/MonoDevelop/Ide/ProjectTemplateWizards"> @@ -38,7 +98,9 @@ </Extension> <Extension path="/MonoDevelop/Ide/Pads/ProjectPad"> - <NodeBuilder class="MonoDevelop.DotNetCore.DotNetCoreFolderNodeBuilderExtension" /> + <NodeBuilder class="MonoDevelop.DotNetCore.NodeBuilders.DotNetCoreFolderNodeBuilderExtension" /> + <NodeBuilder class="MonoDevelop.DotNetCore.NodeBuilders.DotNetCoreProjectNodeBuilderExtension" /> + <NodeBuilder class="MonoDevelop.DotNetCore.ProjXNodeBuilderExtension" /> </Extension> <Extension path="/MonoDevelop/ProjectModel/WorkspaceObjectReaders"> @@ -49,8 +111,13 @@ <Class id="DnxTestProvider" class="MonoDevelop.DotNetCore.UnitTesting.DotNetCoreTestProvider" /> </Extension> - <Extension path="/MonoDevelop/Ide/Pads/ProjectPad"> - <NodeBuilder class="MonoDevelop.DotNetCore.DotNetCoreProjectNodeBuilderExtension" /> + <ExtensionPoint path="/MonoDevelop/DotNetCore/ContextMenu/ProjectPad/PackageDependency"> + <ExtensionNodeSet id="MonoDevelop.Components.Commands.ItemSet"/> + </ExtensionPoint> + + <Extension path="/MonoDevelop/DotNetCore/ContextMenu/ProjectPad/PackageDependency"> + <CommandItem id="MonoDevelop.PackageManagement.Commands.PackageReferenceNodeCommands.UpdatePackage" /> + <CommandItem id="MonoDevelop.Ide.Commands.EditCommands.Delete" /> </Extension> <Extension path="/MonoDevelop/ProjectModel/Gui/ItemOptionPanels/Build/General"> @@ -67,4 +134,68 @@ class="MonoDevelop.DotNetCore.DummyMSBuildOptionsPanel" /> </Condition> </Extension> + + <Extension path = "/MonoDevelop/Ide/Commands"> + <Command id = "MonoDevelop.DotNetCore.Commands.DotNetMigrate" + defaultHandler = "MonoDevelop.DotNetCore.DotNetMigrateCommandHandler" + _label = "Migrate to New Format" + description="Migrates old .NET Core project to new format"/> + </Extension> + + <Extension path="/MonoDevelop/Ide/ContextMenu/ProjectPad"> + <Condition + id="ItemType" + value="MonoDevelop.DotNetCore.NodeBuilders.DependenciesNode"> + <CommandItem + id="MonoDevelop.Ide.Commands.ProjectCommands.AddReference" /> + <SeparatorItem + id="DependenciesEditReferenceSeparator" /> + <CommandItem + id="MonoDevelop.PackageManagement.Commands.AddPackages" _label = "Add _Packages..." /> + <CommandItem + id="MonoDevelop.PackageManagement.Commands.UpdateAllPackagesInProject" /> + <CommandItem + id="MonoDevelop.PackageManagement.Commands.Restore" /> + </Condition> + <Condition id="ItemType" value="MonoDevelop.DotNetCore.NodeBuilders.PackageDependenciesNode"> + <CommandItem + id="MonoDevelop.PackageManagement.Commands.AddPackages" _label = "Add _Packages..." /> + <CommandItem + id="MonoDevelop.PackageManagement.Commands.UpdateAllPackagesInProject" /> + <CommandItem + id="MonoDevelop.PackageManagement.Commands.Restore" /> + </Condition> + <Condition + id="ItemType" + value="MonoDevelop.DotNetCore.NodeBuilders.AssemblyDependenciesNode|MonoDevelop.DotNetCore.NodeBuilders.ProjectDependenciesNode"> + <CommandItem + id="MonoDevelop.Ide.Commands.ProjectCommands.AddReference" + insertbefore="MonoDevelop.PackageManagement.Commands.AddPackages" /> + </Condition> + <Condition id="ItemType" value="UnknownProject|Solution"> + <CommandItem + id="MonoDevelop.DotNetCore.Commands.DotNetMigrate" + insertbefore="MonoDevelop.Ide.Commands.ProjectCommands.Build" /> + <SeparatorItem + id="DotNetMigrateSeparator" + insertafter="MonoDevelop.DotNetCore.Commands.DotNetMigrate" + insertbefore="MonoDevelop.Ide.Commands.ProjectCommands.Build" /> + </Condition> + </Extension> + + <Extension path="/MonoDevelop/Ide/Pads/ProjectPad"> + <NodeBuilder class="MonoDevelop.DotNetCore.NodeBuilders.DependenciesNodeBuilderExtension" /> + <NodeBuilder class="MonoDevelop.DotNetCore.NodeBuilders.DependenciesNodeBuilder" /> + <NodeBuilder class="MonoDevelop.DotNetCore.NodeBuilders.PackageDependenciesNodeBuilder" /> + <NodeBuilder class="MonoDevelop.DotNetCore.NodeBuilders.TargetFrameworkNodeBuilder" /> + <NodeBuilder class="MonoDevelop.DotNetCore.NodeBuilders.PackageDependencyNodeBuilder" /> + <NodeBuilder class="MonoDevelop.DotNetCore.NodeBuilders.ProjectDependenciesNodeBuilder" /> + <NodeBuilder class="MonoDevelop.DotNetCore.NodeBuilders.AssemblyDependenciesNodeBuilder" /> + <NodeBuilder class="MonoDevelop.DotNetCore.NodeBuilders.SdkDependenciesNodeBuilder" /> + <NodeBuilder class="MonoDevelop.DotNetCore.NodeBuilders.DotNetCoreProjectReferencesNodeBuilderExtension" /> + </Extension> + + <Extension path = "/MonoDevelop/Ide/RunConfigurationEditors"> + <Class class="MonoDevelop.DotNetCore.DotNetCoreRunConfigurationEditor" runConfigurationType="MonoDevelop.DotNetCore.DotNetCoreRunConfiguration" /> + </Extension> </ExtensionModel>
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Console/ConsoleProject.Program.cs b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Console/ConsoleProject.Program.cs deleted file mode 100755 index c81448f540..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Console/ConsoleProject.Program.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -class Program -{ - static void Main(string[] args) - { - Console.WriteLine("Hello World!"); - } -} diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Console/ConsoleProject.Program.cs.xft.xml b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Console/ConsoleProject.Program.cs.xft.xml deleted file mode 100644 index f48622775d..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Console/ConsoleProject.Program.cs.xft.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0"?> -<Template - originator="Matt Ward" - created="2015/09/22" - lastModified="2015/09/22"> - - <TemplateConfiguration> - <_Name>Console Program.cs</_Name> - </TemplateConfiguration> - - <TemplateFiles> - <File - name="Program.cs" - DefaultName="Program.cs" - src="ConsoleProject.Program.cs" - BuildAction="Compile" - AddStandardHeader="True" /> - </TemplateFiles> -</Template>
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Console/ConsoleProject.csproj b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Console/ConsoleProject.csproj deleted file mode 100644 index 5e1611f89d..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Console/ConsoleProject.csproj +++ /dev/null @@ -1,8 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <OutputType>Exe</OutputType> - <TargetFramework>netcoreapp1.0</TargetFramework> - </PropertyGroup> - -</Project> diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Console/ConsoleProject.xpt.xml b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Console/ConsoleProject.xpt.xml deleted file mode 100644 index 6b34e03785..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Console/ConsoleProject.xpt.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0"?> -<Template - originator="Matt Ward" - created="06/09/2015" - lastModified="31/10/2016"> - - <TemplateConfiguration> - <_Name>Console Application (.NET Core)</_Name> - <Category>netcore/app/general</Category> - <Icon>md-console-project</Icon> - <Image id="md-console-project" /> - <LanguageName>C#</LanguageName> - <_Description>Creates a new .NET Core console project.</_Description> - <DefaultFilename>ConsoleProject</DefaultFilename> - <Wizard>MonoDevelop.DotNetCore.ProjectTemplateWizard</Wizard> - <DefaultParameters>Template=ConsoleProject;OpenFile=Program.cs;Files=Program.cs;ExternalConsole=true</DefaultParameters> - </TemplateConfiguration> - - <Combine name="${ProjectName}" directory="."> - <Project name="${ProjectName}" type="C#" directory="./" if="CreateDotNetCoreProject"> - </Project> - </Combine> -</Template>
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.Program.cs b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.Program.cs deleted file mode 100755 index 9046074545..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.Program.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Hosting; - -namespace ${Namespace} -{ - public class Program - { - public static void Main(string[] args) - { - var host = new WebHostBuilder() - .UseKestrel() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseIISIntegration() - .UseStartup<Startup>() - .Build(); - - host.Run(); - } - } -}
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.Program.cs.xft.xml b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.Program.cs.xft.xml deleted file mode 100644 index 4bb9067fc2..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.Program.cs.xft.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0"?> -<Template - originator="Matt Ward" - created="2015/09/22" - lastModified="2015/09/22"> - - <TemplateConfiguration> - <_Name>Empty web Program.cs</_Name> - </TemplateConfiguration> - - <TemplateFiles> - <File - name="Program.cs" - DefaultName="Program.cs" - src="EmptyWebProject.Program.cs" - BuildAction="Compile" - AddStandardHeader="True" /> - </TemplateFiles> -</Template>
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.Startup.cs b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.Startup.cs deleted file mode 100755 index 857cd56db1..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.Startup.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -namespace ${Namespace} -{ - public class Startup - { - // This method gets called by the runtime. Use this method to add services to the container. - // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 - public void ConfigureServices(IServiceCollection services) - { - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) - { - loggerFactory.AddConsole(); - - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - - app.Run(async (context) => - { - await context.Response.WriteAsync("Hello World!"); - }); - } - } -}
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.Startup.cs.xft.xml b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.Startup.cs.xft.xml deleted file mode 100644 index 4bfb057a29..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.Startup.cs.xft.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0"?> -<Template - originator="Matt Ward" - created="2015/09/22" - lastModified="2015/09/22"> - - <TemplateConfiguration> - <_Name>Empty web Startup.cs</_Name> - </TemplateConfiguration> - - <TemplateFiles> - <File - name="Startup.cs" - DefaultName="Startup.cs" - src="EmptyWebProject.Startup.cs" - BuildAction="Compile" - AddStandardHeader="True" /> - </TemplateFiles> -</Template>
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.csproj b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.csproj deleted file mode 100644 index f71ef36b61..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.csproj +++ /dev/null @@ -1,11 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk.Web"> - - <PropertyGroup> - <TargetFramework>netcoreapp1.0</TargetFramework> - </PropertyGroup> - - <ItemGroup> - <PackageReference Include="Microsoft.AspNetCore" Version="1.0.3" /> - </ItemGroup> - -</Project> diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.xpt.xml b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.xpt.xml deleted file mode 100644 index 35b5311939..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/EmptyWeb/EmptyWebProject.xpt.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0"?> -<Template - originator="Matt Ward" - created="06/09/2015" - lastModified="31/10/2016"> - - <TemplateConfiguration> - <_Name>ASP.NET Core Empty Web Application</_Name> - <Category>netcore/app/aspnet</Category> - <Icon>md-aspnet-empty-project</Icon> - <Image id="md-aspnet-empty-project" /> - <LanguageName>C#</LanguageName> - <_Description>Creates a new ASP.NET Core web project.</_Description> - <DefaultFilename>WebApp</DefaultFilename> - <Wizard>MonoDevelop.DotNetCore.ProjectTemplateWizard</Wizard> - <DefaultParameters>Template=EmptyWebProject;CreateWebRoot=true;OpenFile=Startup.cs;Files=Startup.cs|Program.cs</DefaultParameters> - </TemplateConfiguration> - - <Combine name="${ProjectName}" directory="."> - <Project name="${ProjectName}" type="C#" directory="./src" if="CreateDotNetCoreProject"> - </Project> - </Combine> -</Template>
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Library/LibraryProject.MyClass.cs b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Library/LibraryProject.MyClass.cs deleted file mode 100755 index fc20e2f546..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Library/LibraryProject.MyClass.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace ${Namespace} -{ - public class MyClass - { - public MyClass() - { - } - } -} diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Library/LibraryProject.MyClass.cs.xft.xml b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Library/LibraryProject.MyClass.cs.xft.xml deleted file mode 100644 index 3f7e462005..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Library/LibraryProject.MyClass.cs.xft.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0"?> -<Template - originator="Matt Ward" - created="2015/09/13" - lastModified="2015/09/13"> - - <TemplateConfiguration> - <_Name>Library MyClass.cs</_Name> - </TemplateConfiguration> - - <TemplateFiles> - <File - name="MyClass.cs" - DefaultName="MyClass.cs" - src="LibraryProject.MyClass.cs" - BuildAction="Compile" - AddStandardHeader="True" /> - </TemplateFiles> -</Template>
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Library/LibraryProject.csproj b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Library/LibraryProject.csproj deleted file mode 100644 index 20861435dc..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Library/LibraryProject.csproj +++ /dev/null @@ -1,7 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <TargetFramework>netstandard1.4</TargetFramework> - </PropertyGroup> - -</Project> diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Library/LibraryProject.xpt.xml b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Library/LibraryProject.xpt.xml deleted file mode 100644 index 529ca1fd7c..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/Library/LibraryProject.xpt.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0"?> -<Template - originator="Matt Ward" - created="12/09/2015" - lastModified="31/10/2016"> - - <TemplateConfiguration> - <_Name>Class Library (.NET Core)</_Name> - <Category>netcore/library/general</Category> - <Icon>md-library-project</Icon> - <Image id="md-library-project" /> - <LanguageName>C#</LanguageName> - <_Description>Creates a new .NET Core class library project.</_Description> - <DefaultFilename>ClassLibrary</DefaultFilename> - <Wizard>MonoDevelop.DotNetCore.ProjectTemplateWizard</Wizard> - <DefaultParameters>Template=LibraryProject;OpenFile=MyClass.cs;Files=MyClass.cs</DefaultParameters> - </TemplateConfiguration> - - <Combine name="${ProjectName}" directory="."> - <Project name="${ProjectName}" type="C#" directory="./" if="CreateDotNetCoreProject"> - </Project> - </Combine> -</Template>
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/XUnitTest/XUnitTestProject.Test.cs b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/XUnitTest/XUnitTestProject.Test.cs deleted file mode 100755 index 02156e0bbb..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/XUnitTest/XUnitTestProject.Test.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using Xunit; - -namespace ${Namespace} -{ - public class Test - { - [Fact] - public void TestCase() - { - } - } -} diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/XUnitTest/XUnitTestProject.Test.cs.xft.xml b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/XUnitTest/XUnitTestProject.Test.cs.xft.xml deleted file mode 100644 index 2f41bb949e..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/XUnitTest/XUnitTestProject.Test.cs.xft.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0"?> -<Template - originator="Matt Ward" - created="2017/02/07" - lastModified="2017/02/07"> - - <TemplateConfiguration> - <_Name>Xunit Test.cs</_Name> - </TemplateConfiguration> - - <TemplateFiles> - <File - name="Test.cs" - DefaultName="Test.cs" - src="XUnitTestProject.Test.cs" - BuildAction="Compile" - AddStandardHeader="True" /> - </TemplateFiles> -</Template>
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/XUnitTest/XUnitTestProject.csproj b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/XUnitTest/XUnitTestProject.csproj deleted file mode 100644 index 6c4af8a52a..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/XUnitTest/XUnitTestProject.csproj +++ /dev/null @@ -1,13 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <TargetFramework>netcoreapp1.0</TargetFramework> - </PropertyGroup> - - <ItemGroup> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170123-02" /> - <PackageReference Include="xunit" Version="2.2.0-beta5-build3474" /> - <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0-beta5-build1225" /> - </ItemGroup> - -</Project> diff --git a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/XUnitTest/XUnitTestProject.xpt.xml b/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/XUnitTest/XUnitTestProject.xpt.xml deleted file mode 100644 index f0f55cd3d6..0000000000 --- a/main/src/addins/MonoDevelop.DotNetCore/Templates/Projects/XUnitTest/XUnitTestProject.xpt.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0"?> -<Template - originator="Matt Ward" - created="12/09/2015" - lastModified="31/10/2016"> - - <TemplateConfiguration> - <_Name>xUnit Library (.NET Core)</_Name> - <Category>netcore/test/general</Category> - <Icon>md-test-project</Icon> - <Image id="md-test-project" /> - <LanguageName>C#</LanguageName> - <_Description>Creates a new xUnit test project.</_Description> - <DefaultFilename>ClassLibrary</DefaultFilename> - <Wizard>MonoDevelop.DotNetCore.ProjectTemplateWizard</Wizard> - <DefaultParameters>Template=XUnitTestProject;OpenFile=Test.cs;Files=Test.cs</DefaultParameters> - </TemplateConfiguration> - - <Combine name="${ProjectName}" directory="."> - <Project name="${ProjectName}" type="C#" directory="./" if="CreateDotNetCoreProject"> - </Project> - </Combine> -</Template>
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DotNetCore/packages.config b/main/src/addins/MonoDevelop.DotNetCore/packages.config index 7d187e2074..10ab51cf54 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/packages.config +++ b/main/src/addins/MonoDevelop.DotNetCore/packages.config @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="Microsoft.TestPlatform.TranslationLayer" version="15.0.0-preview-20170201-02" targetFramework="net46" /> + <package id="Microsoft.TestPlatform.TranslationLayer" version="15.0.0" targetFramework="net46" /> <package id="Newtonsoft.Json" version="8.0.3" targetFramework="net46" /> </packages>
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DotNetCore/pull-package.cs b/main/src/addins/MonoDevelop.DotNetCore/pull-package.cs new file mode 100644 index 0000000000..15eaedd2a2 --- /dev/null +++ b/main/src/addins/MonoDevelop.DotNetCore/pull-package.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; +using System.Linq; +using System.Net; + +public class App +{ + static string CacheDirectory { + get { + return Path.Combine ( + Environment.GetFolderPath (Environment.SpecialFolder.Personal), + "Cache", + "xs-compilation" + ); + } + } + + public static int Main (string [] args) + { + //Reason for this cache is not to save time on downloading file on fresh build + //but in case downloading fails/you don't have internet connection it uses old cache + //so this cache should probably be called backup :) + + var sourceUrl = new Uri (args [0]); + var destFile = args [1]; + var cachePath = Path.Combine (CacheDirectory, Path.GetFileName (destFile)); + var cacheTmpPath = cachePath + ".tmp"; + + Console.WriteLine ("Creating directories: {0} and {1}", CacheDirectory, Path.GetDirectoryName (destFile)); + Directory.CreateDirectory (CacheDirectory); + Directory.CreateDirectory (Path.GetDirectoryName (destFile)); + + Console.WriteLine ("Downloading file: '{0}' to cache at '{1}'", sourceUrl, cachePath); + try { + WebClient wc = new WebClient (); + wc.DownloadFile (sourceUrl, cacheTmpPath); + File.Delete (cachePath); + File.Move (cacheTmpPath, cachePath); + } catch (Exception ex) { + Console.WriteLine ("Could not download the package from {0}. {1}", sourceUrl, ex); + } + + if (File.Exists (cachePath)) { + Console.WriteLine ("Using the file from the cache directory. Copying {0} to {1}", cachePath, destFile); + File.Delete (destFile); + File.Copy (cachePath, destFile); + return 0; + } else { + Console.WriteLine ("The file was not found in the cache directory... failing"); + return 1; + } + } +}
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackageManagementStartupHandler.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackageManagementStartupHandler.cs index b2f6cc5881..570bb2f338 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackageManagementStartupHandler.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackageManagementStartupHandler.cs @@ -163,9 +163,6 @@ namespace MonoDevelop.PackageManagement.Commands return; } - //check that the projects have the correct backing system for project.json - RefreshProjectsIfNecessary (projects); - //queue up in a timeout in case this was kicked off from a command GLib.Timeout.Add (0, () => { if (projects.Count == 1) { @@ -185,19 +182,5 @@ namespace MonoDevelop.PackageManagement.Commands return false; }); } - - static void RefreshProjectsIfNecessary (List<DotNetProject> projects) - { - foreach (var solution in projects.GroupBy (p => p.ParentSolution)) { - var solutionManager = (MonoDevelopSolutionManager)PackageManagementServices.Workspace.GetSolutionManager (solution.Key); - foreach (var nugetProject in solutionManager.GetNuGetProjects ()) { - var msbuildProject = nugetProject as NuGet.ProjectManagement.MSBuildNuGetProject; - if (msbuildProject != null && solution.Any (p => p.FileName == msbuildProject.MSBuildNuGetProjectSystem.ProjectFullPath)) { - solutionManager.ClearProjectCache (); - break; - } - } - } - } } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackageReferenceNodeCommandHandler.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackageReferenceNodeCommandHandler.cs index aaa7c92eb5..2d69ec0c26 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackageReferenceNodeCommandHandler.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/PackageReferenceNodeCommandHandler.cs @@ -69,6 +69,22 @@ namespace MonoDevelop.PackageManagement.Commands PackageId = packageReferenceNode.Id
};
}
+
+ static internal IPackageAction CreateUninstallPackageAction (DotNetProject project, string packageId)
+ {
+ var solutionManager = PackageManagementServices.Workspace.GetSolutionManager (project.ParentSolution);
+ return new UninstallNuGetPackageAction (solutionManager, new DotNetProjectProxy (project)) {
+ PackageId = packageId
+ };
+ }
+
+ internal static IPackageAction CreateUninstallPackagesAction (DotNetProject project, string[] packageIds)
+ {
+ var solutionManager = PackageManagementServices.Workspace.GetSolutionManager (project.ParentSolution);
+ var action = new UninstallNuGetPackagesAction (solutionManager, new DotNetProjectProxy (project));
+ action.AddPackageIds (packageIds);
+ return action;
+ }
[CommandUpdateHandler (EditCommands.Delete)]
public void UpdateRemoveItem (CommandInfo info)
@@ -87,22 +103,30 @@ namespace MonoDevelop.PackageManagement.Commands {
var packageReferenceNode = (PackageReferenceNode)CurrentNode.DataItem;
+ UpdatePackage (
+ packageReferenceNode.Project,
+ packageReferenceNode.Id,
+ !packageReferenceNode.IsReleaseVersion ());
+ }
+
+ internal static void UpdatePackage (IDotNetProject project, string packageId, bool includePrerelease)
+ {
try {
- var solutionManager = PackageManagementServices.Workspace.GetSolutionManager (packageReferenceNode.Project.ParentSolution);
- var action = new UpdateNuGetPackageAction (solutionManager, packageReferenceNode.Project) {
- PackageId = packageReferenceNode.Id,
- IncludePrerelease = !packageReferenceNode.IsReleaseVersion ()
+ var solutionManager = PackageManagementServices.Workspace.GetSolutionManager (project.ParentSolution);
+ var action = new UpdateNuGetPackageAction (solutionManager, project) {
+ PackageId = packageId,
+ IncludePrerelease = includePrerelease
};
- ProgressMonitorStatusMessage progressMessage = ProgressMonitorStatusMessageFactory.CreateUpdatingSinglePackageMessage (packageReferenceNode.Id, packageReferenceNode.Project);
+ ProgressMonitorStatusMessage progressMessage = ProgressMonitorStatusMessageFactory.CreateUpdatingSinglePackageMessage (packageId, project);
UpdatePackage (progressMessage, action);
} catch (Exception ex) {
- ProgressMonitorStatusMessage progressMessage = ProgressMonitorStatusMessageFactory.CreateUpdatingSinglePackageMessage (packageReferenceNode.Id);
+ ProgressMonitorStatusMessage progressMessage = ProgressMonitorStatusMessageFactory.CreateUpdatingSinglePackageMessage (packageId);
PackageManagementServices.BackgroundPackageActionRunner.ShowError (progressMessage, ex);
}
}
- void UpdatePackage (ProgressMonitorStatusMessage progressMessage, IPackageAction action)
+ static void UpdatePackage (ProgressMonitorStatusMessage progressMessage, IPackageAction action)
{
try {
PackageManagementServices.BackgroundPackageActionRunner.Run (progressMessage, action);
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/ProjectPackagesProjectNodeBuilderExtension.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/ProjectPackagesProjectNodeBuilderExtension.cs index a2d44bcb48..e5a7b107ba 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/ProjectPackagesProjectNodeBuilderExtension.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.NodeBuilders/ProjectPackagesProjectNodeBuilderExtension.cs @@ -114,12 +114,21 @@ namespace MonoDevelop.PackageManagement.NodeBuilders public override bool HasChildNodes (ITreeBuilder builder, object dataObject)
{
- return true;
+ return ShowPackagesFolderForProject ((DotNetProject)dataObject);
+ }
+
+ bool ShowPackagesFolderForProject (DotNetProject project)
+ {
+ return !project.IsDotNetCoreProject ();
}
public override void BuildChildNodes (ITreeBuilder treeBuilder, object dataObject)
{
var project = (DotNetProject)dataObject;
+
+ if (!ShowPackagesFolderForProject (project))
+ return;
+
var folderNode = new ProjectPackagesFolderNode (project);
folderNode.RefreshPackages ();
treeBuilder.AddChild (folderNode);
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetPackageManager.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetPackageManager.cs index 05f8b43288..c861b57c03 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetPackageManager.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetPackageManager.cs @@ -247,6 +247,28 @@ namespace MonoDevelop.PackageManagement.Tests.Helpers return Task.FromResult (0); } + + public IBuildIntegratedNuGetProject PreviewBuildIntegratedProject; + public List<NuGetProjectAction> PreviewBuildIntegratedProjectActions; + public INuGetProjectContext PreviewBuildIntegratedContext; + public CancellationToken PreviewBuildIntegratedCancellationToken; + public BuildIntegratedProjectAction BuildIntegratedProjectAction; + + public Task<BuildIntegratedProjectAction> PreviewBuildIntegratedProjectActionsAsync ( + IBuildIntegratedNuGetProject buildIntegratedProject, + IEnumerable<NuGetProjectAction> nuGetProjectActions, + INuGetProjectContext nuGetProjectContext, + CancellationToken token) + { + PreviewBuildIntegratedProject = buildIntegratedProject; + PreviewBuildIntegratedProjectActions = nuGetProjectActions.ToList (); + PreviewBuildIntegratedContext = nuGetProjectContext; + PreviewBuildIntegratedCancellationToken = token; + + BeforePreviewUninstallPackagesAsync (); + + return Task.FromResult (BuildIntegratedProjectAction); + } } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableUninstallNuGetPackagesAction.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableUninstallNuGetPackagesAction.cs new file mode 100644 index 0000000000..4e68f3936f --- /dev/null +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableUninstallNuGetPackagesAction.cs @@ -0,0 +1,66 @@ +// +// TestableUninstallNuGetPackagesAction.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2017 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +namespace MonoDevelop.PackageManagement.Tests.Helpers +{ + class TestableUninstallNuGetPackagesAction : UninstallNuGetPackagesAction + { + public FakeNuGetProjectContext ProjectContext; + public FakeNuGetPackageManager PackageManager; + public PackageManagementEvents PackageManagementEvents; + + public TestableUninstallNuGetPackagesAction ( + FakeSolutionManager solutionManager, + FakeDotNetProject project) + : this ( + solutionManager, + project, + new FakeNuGetProjectContext (), + new FakeNuGetPackageManager (), + new PackageManagementEvents ()) + { + } + + public TestableUninstallNuGetPackagesAction ( + FakeSolutionManager solutionManager, + FakeDotNetProject dotNetProject, + FakeNuGetProjectContext projectContext, + FakeNuGetPackageManager packageManager, + PackageManagementEvents packageManagementEvents) + : base ( + solutionManager, + dotNetProject, + projectContext, + packageManager, + packageManagementEvents) + { + ProjectContext = projectContext; + PackageManager = packageManager; + + PackageManagementEvents = packageManagementEvents; + } + } +} diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.csproj b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.csproj index 10052bfc57..3639c01116 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.csproj +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.csproj @@ -200,6 +200,8 @@ <Compile Include="MonoDevelop.PackageManagement.Tests.Helpers\FakeMSBuildEvaluatedPropertyCollection.cs" /> <Compile Include="MonoDevelop.PackageManagement.Tests.Helpers\TestableProjectPackageReference.cs" /> <Compile Include="MonoDevelop.PackageManagement.Tests\ProjectPackageReferenceTests.cs" /> + <Compile Include="MonoDevelop.PackageManagement.Tests\UninstallNuGetPackagesActionTests.cs" /> + <Compile Include="MonoDevelop.PackageManagement.Tests.Helpers\TestableUninstallNuGetPackagesAction.cs" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\..\..\core\MonoDevelop.Core\MonoDevelop.Core.csproj"> diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetCoreNuGetProjectTests.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetCoreNuGetProjectTests.cs index f866c33dec..e9148330f5 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetCoreNuGetProjectTests.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetCoreNuGetProjectTests.cs @@ -123,7 +123,20 @@ namespace MonoDevelop.PackageManagement.Tests Assert.IsFalse (result); Assert.IsFalse (project.IsSaved); Assert.AreEqual (MessageLevel.Warning, context.LastLogLevel); - Assert.AreEqual ("Package 'NUnit.2.6.1' does not exist in project 'MyProject'", context.LastMessageLogged); + Assert.AreEqual ("Package 'NUnit' does not exist in project 'MyProject'", context.LastMessageLogged); + } + + [Test] + public async Task UninstallPackageAsync_DifferentPackageVersionInstalled_PackageReferenceRemoved () + { + CreateNuGetProject (); + AddDotNetProjectPackageReference ("NUnit", "2.6.1"); + + bool result = await UninstallPackageAsync ("NUnit", "3.5"); + + Assert.IsFalse (dotNetProject.Items.OfType<ProjectPackageReference> ().Any ()); + Assert.IsTrue (result); + Assert.IsTrue (project.IsSaved); } [Test] diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/UninstallNuGetPackagesActionTests.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/UninstallNuGetPackagesActionTests.cs new file mode 100644 index 0000000000..5e7395ede2 --- /dev/null +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/UninstallNuGetPackagesActionTests.cs @@ -0,0 +1,136 @@ +// +// UninstallNuGetPackagesActionTests.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2017 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System.Linq; +using MonoDevelop.PackageManagement.Tests.Helpers; +using NuGet.PackageManagement; +using NUnit.Framework; + +namespace MonoDevelop.PackageManagement.Tests +{ + [TestFixture] + public class UninstallNuGetPackagesActionTests + { + TestableUninstallNuGetPackagesAction action; + FakeSolutionManager solutionManager; + FakeDotNetProject project; + FakeNuGetProject nugetProject; + FakeNuGetPackageManager packageManager; + + void CreateAction (params string[] packageIds) + { + project = new FakeDotNetProject (@"d:\projects\MyProject\MyProject.csproj"); + project.Name = "MyProject"; + solutionManager = new FakeSolutionManager (); + nugetProject = new FakeNuGetProject (project); + solutionManager.NuGetProjects[project] = nugetProject; + + action = new TestableUninstallNuGetPackagesAction ( + solutionManager, + project); + + packageManager = action.PackageManager; + + action.AddPackageIds (packageIds); + } + + [Test] + public void Execute_TwoPackageIds_ActionsResolvedFromNuGetPackageManager () + { + CreateAction ("Test1", "Test2"); + + action.Execute (); + + Assert.AreEqual (nugetProject, packageManager.PreviewBuildIntegratedProject); + Assert.AreEqual ("Test1", packageManager.PreviewBuildIntegratedProjectActions[0].PackageIdentity.Id); + Assert.AreEqual ("Test2", packageManager.PreviewBuildIntegratedProjectActions[1].PackageIdentity.Id); + Assert.AreEqual (NuGetProjectActionType.Uninstall, packageManager.PreviewBuildIntegratedProjectActions[0].NuGetProjectActionType); + Assert.AreEqual (NuGetProjectActionType.Uninstall, packageManager.PreviewBuildIntegratedProjectActions[1].NuGetProjectActionType); + Assert.AreEqual (action.ProjectContext, packageManager.PreviewBuildIntegratedContext); + } + + [Test] + public void Execute_TwoPackageIds_ActionsAvailableForInstrumentation () + { + CreateAction ("Test1", "Test2"); + + action.Execute (); + + Assert.AreEqual (action.GetNuGetProjectActions (), packageManager.PreviewBuildIntegratedProjectActions); + } + + [Test] + public void NewInstance_NotExecutedAndGetNuGetProjectActions_NullReferenceExceptionNotThrown () + { + CreateAction ("Test1", "Test2"); + + Assert.AreEqual (0, action.GetNuGetProjectActions ().Count ()); + } + + [Test] + public void Execute_TwoPackageIds_ExecutesBuilldIntegratedActionReturnedFromNuGetPackageManager () + { + CreateAction ("Test1", "Test2"); + + action.Execute (); + + Assert.AreEqual (packageManager.BuildIntegratedProjectAction, packageManager.ExecutedActions[0]); + Assert.AreEqual (1, packageManager.ExecutedActions.Count); + Assert.AreEqual (nugetProject, packageManager.ExecutedNuGetProject); + Assert.AreEqual (action.ProjectContext, packageManager.ExecutedProjectContext); + } + + [Test] + public void Execute_TwoPackageIds_OnAfterExecuteActionsIsCalled () + { + CreateAction ("Test1", "Test2"); + + action.Execute (); + + Assert.AreEqual (packageManager.PreviewBuildIntegratedProjectActions, nugetProject.ActionsPassedToOnAfterExecuteActions); + } + + [Test] + public void Execute_TwoPackageIds_PostProcessingIsRun () + { + CreateAction ("Test1", "Test2"); + + action.Execute (); + + Assert.AreEqual (action.ProjectContext, nugetProject.PostProcessProjectContext); + } + + [Test] + public void Execute_TwoPackageIds_OnBeforeUninstallIsCalled () + { + CreateAction ("Test1", "Test2"); + + action.Execute (); + + Assert.AreEqual (packageManager.PreviewBuildIntegratedProjectActions, nugetProject.ActionsPassedToOnBeforeUninstall); + } + } +} diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.addin.xml b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.addin.xml index 79d846a20c..5278d96067 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.addin.xml +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.addin.xml @@ -91,14 +91,6 @@ <CommandItem
id="MonoDevelop.PackageManagement.Commands.Restore" />
</Condition>
- <Condition id="ItemType" value="MonoDevelop.PackageManagement.NodeBuilders.DependenciesNode|MonoDevelop.PackageManagement.NodeBuilders.PackageDependenciesNode">
- <CommandItem
- id="MonoDevelop.PackageManagement.Commands.AddPackages" _label = "Add _Packages..." />
- <CommandItem
- id="MonoDevelop.PackageManagement.Commands.UpdateAllPackagesInProject" />
- <CommandItem
- id="MonoDevelop.PackageManagement.Commands.Restore" />
- </Condition>
</Extension>
<Extension path="/MonoDevelop/Ide/ContextMenu/ProjectPad/Add">
@@ -137,11 +129,6 @@ <NodeBuilder class="MonoDevelop.PackageManagement.NodeBuilders.ProjectReferenceNodeBuilderExtension" />
<NodeBuilder class="MonoDevelop.PackageManagement.NodeBuilders.ProjectReferencesNodeBuilderExtension" />
<NodeBuilder class="MonoDevelop.PackageManagement.NodeBuilders.ProjectReferencesFromPackagesFolderNodeBuilder" />
- <NodeBuilder class="MonoDevelop.PackageManagement.NodeBuilders.DependenciesNodeBuilderExtension" />
- <NodeBuilder class="MonoDevelop.PackageManagement.NodeBuilders.DependenciesNodeBuilder" />
- <NodeBuilder class="MonoDevelop.PackageManagement.NodeBuilders.PackageDependenciesNodeBuilder" />
- <NodeBuilder class="MonoDevelop.PackageManagement.NodeBuilders.TargetFrameworkNodeBuilder" />
- <NodeBuilder class="MonoDevelop.PackageManagement.NodeBuilders.PackageDependencyNodeBuilder" />
</Extension>
<ExtensionPoint path = "/MonoDevelop/PackageManagement/ContextMenu/ProjectPad/PackageReference">
@@ -155,15 +142,6 @@ <CommandItem id="MonoDevelop.Ide.Commands.EditCommands.Delete" />
</Extension>
- <ExtensionPoint path="/MonoDevelop/PackageManagement/ContextMenu/ProjectPad/PackageDependency">
- <ExtensionNodeSet id="MonoDevelop.Components.Commands.ItemSet"/>
- </ExtensionPoint>
-
- <Extension path="/MonoDevelop/PackageManagement/ContextMenu/ProjectPad/PackageDependency">
- <CommandItem id="MonoDevelop.PackageManagement.Commands.PackageReferenceNodeCommands.UpdatePackage" />
- <CommandItem id="MonoDevelop.Ide.Commands.EditCommands.Delete" />
- </Extension>
-
<Extension path="/MonoDevelop/DesignerSupport/PropertyProviders">
<Class class="MonoDevelop.PackageManagement.NodeBuilders.PackageReferenceNodePropertyProvider" />
</Extension>
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj index 877f78ba77..5047875419 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj @@ -390,16 +390,6 @@ <Compile Include="MonoDevelop.PackageManagement\DotNetCorePath.cs" /> <Compile Include="MonoDevelop.PackageManagement\LoggingProgressMonitor.cs" /> <Compile Include="MonoDevelop.PackageManagement\DotNetCoreFrameworkCompatibility.cs" /> - <Compile Include="MonoDevelop.PackageManagement.NodeBuilders\DependenciesNodeBuilderExtension.cs" /> - <Compile Include="MonoDevelop.PackageManagement.NodeBuilders\DependenciesNode.cs" /> - <Compile Include="MonoDevelop.PackageManagement.NodeBuilders\DependenciesNodeBuilder.cs" /> - <Compile Include="MonoDevelop.PackageManagement.NodeBuilders\PackageDependenciesNode.cs" /> - <Compile Include="MonoDevelop.PackageManagement.NodeBuilders\PackageDependenciesNodeBuilder.cs" /> - <Compile Include="MonoDevelop.PackageManagement.NodeBuilders\TargetFrameworkNode.cs" /> - <Compile Include="MonoDevelop.PackageManagement.NodeBuilders\TargetFrameworkNodeBuilder.cs" /> - <Compile Include="MonoDevelop.PackageManagement.NodeBuilders\PackageDependencyNode.cs" /> - <Compile Include="MonoDevelop.PackageManagement.NodeBuilders\PackageDependencyNodeBuilder.cs" /> - <Compile Include="MonoDevelop.PackageManagement.Commands\PackageDependenciesNodeCommandHandler.cs" /> <Compile Include="MonoDevelop.PackageManagement.Gui\PackageSourcesLoadErrorWidget.cs" /> <Compile Include="MonoDevelop.PackageManagement.Gui\PackageSourcesLoadErrorWidget.UI.cs"> <DependentUpon>PackageSourcesLoadErrorWidget.cs</DependentUpon> @@ -425,7 +415,7 @@ <Compile Include="NuGet.Commands\MSBuildRestoreResult.cs" /> <Compile Include="MonoDevelop.PackageManagement\HttpClientFactory.cs" /> <Compile Include="NuGet.CommandLine\SettingsCredentialProvider.cs" /> - <Compile Include="MonoDevelop.PackageManagement.Commands\PackageDependencyNodeCommandHandler.cs" /> + <Compile Include="MonoDevelop.PackageManagement\UninstallNuGetPackagesAction.cs" /> </ItemGroup> <ItemGroup> <EmbeddedResource Include="MonoDevelop.PackageManagement.addin.xml" /> diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetCoreNuGetProject.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetCoreNuGetProject.cs index 584e5e3d85..5d3139f394 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetCoreNuGetProject.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetCoreNuGetProject.cs @@ -25,7 +25,6 @@ // THE SOFTWARE. using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -48,6 +47,7 @@ namespace MonoDevelop.PackageManagement IPackageManagementEvents packageManagementEvents; string msbuildProjectPath; string projectName; + bool restoreRequired; public DotNetCoreNuGetProject ( DotNetProject project, @@ -178,10 +178,10 @@ namespace MonoDevelop.PackageManagement bool RemovePackageReference (PackageIdentity packageIdentity, INuGetProjectContext context) { - ProjectPackageReference packageReference = project.GetPackageReference (packageIdentity); + ProjectPackageReference packageReference = project.GetPackageReference (packageIdentity, matchVersion: false); if (packageReference == null) { - context.Log (MessageLevel.Warning, GettextCatalog.GetString ("Package '{0}' does not exist in project '{1}'", packageIdentity, project.Name)); + context.Log (MessageLevel.Warning, GettextCatalog.GetString ("Package '{0}' does not exist in project '{1}'", packageIdentity.Id, project.Name)); return false; } @@ -265,8 +265,12 @@ namespace MonoDevelop.PackageManagement return Task.FromResult (false); } - public override Task PostProcessAsync (INuGetProjectContext nuGetProjectContext, System.Threading.CancellationToken token) + public override Task PostProcessAsync (INuGetProjectContext nuGetProjectContext, CancellationToken token) { + if (restoreRequired) { + return RestorePackages (nuGetProjectContext, token); + } + Runtime.RunInMainThread (() => { DotNetProject.NotifyModified ("References"); }); @@ -276,12 +280,36 @@ namespace MonoDevelop.PackageManagement return base.PostProcessAsync (nuGetProjectContext, token); } + async Task RestorePackages (INuGetProjectContext nuGetProjectContext, CancellationToken token) + { + var packageRestorer = await Runtime.RunInMainThread (() => { + var solutionManager = PackageManagementServices.Workspace.GetSolutionManager (project.ParentSolution); + return new MonoDevelopBuildIntegratedRestorer (solutionManager); + }); + + var restoreTask = packageRestorer.RestorePackages (this, token); + using (var task = new PackageRestoreTask (restoreTask)) { + await restoreTask; + } + + if (!packageRestorer.LockFileChanged) { + // Need to refresh the references since the restore did not. + await Runtime.RunInMainThread (() => { + DotNetProject.NotifyModified ("References"); + packageManagementEvents.OnFileChanged (project.GetNuGetAssetsFilePath ()); + }); + } + + await base.PostProcessAsync (nuGetProjectContext, token); + } + public void OnBeforeUninstall (IEnumerable<NuGetProjectAction> actions) { } public void OnAfterExecuteActions (IEnumerable<NuGetProjectAction> actions) { + restoreRequired = actions.Any (action => action.NuGetProjectActionType == NuGetProjectActionType.Install); } public void NotifyProjectReferencesChanged () diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs index 7eba9a6cc6..bb337593ad 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs @@ -189,6 +189,12 @@ namespace MonoDevelop.PackageManagement .FirstOrDefault (projectItem => projectItem.Equals (packageIdentity, matchVersion));
}
+ public static bool HasPackageReference (this DotNetProject project, string packageId)
+ {
+ return project.Items.OfType<ProjectPackageReference> ()
+ .Any (projectItem => StringComparer.OrdinalIgnoreCase.Equals (projectItem.Include, packageId));
+ }
+
public static FilePath GetNuGetAssetsFilePath (this DotNetProject project)
{
return project.BaseIntermediateOutputPath.Combine (LockFileFormat.AssetsFileName);
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/INuGetPackageManager.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/INuGetPackageManager.cs index 7bbcddf983..d26fc483af 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/INuGetPackageManager.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/INuGetPackageManager.cs @@ -70,6 +70,12 @@ namespace MonoDevelop.PackageManagement INuGetProjectContext nuGetProjectContext, CancellationToken token); + Task<BuildIntegratedProjectAction> PreviewBuildIntegratedProjectActionsAsync( + IBuildIntegratedNuGetProject buildIntegratedProject, + IEnumerable<NuGetProjectAction> nuGetProjectActions, + INuGetProjectContext nuGetProjectContext, + CancellationToken token); + Task<ResolvedPackage> GetLatestVersionAsync ( string packageId, NuGetProject project, diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopBuildIntegratedRestorer.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopBuildIntegratedRestorer.cs index 5b59342475..f11a4b1082 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopBuildIntegratedRestorer.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopBuildIntegratedRestorer.cs @@ -74,6 +74,8 @@ namespace MonoDevelop.PackageManagement context = CreateRestoreContext ();
}
+ public bool LockFileChanged { get; private set; }
+
public async Task RestorePackages (
IEnumerable<BuildIntegratedNuGetProject> projects,
CancellationToken cancellationToken)
@@ -92,7 +94,8 @@ namespace MonoDevelop.PackageManagement } } - if (changedLocks.Count > 0) { + if (changedLocks.Count > 0) {
+ LockFileChanged = true; await Runtime.RunInMainThread (() => { FileService.NotifyFilesChanged (changedLocks); foreach (var project in affectedProjects) { @@ -113,6 +116,7 @@ namespace MonoDevelop.PackageManagement if (projectToReload != null) {
await ReloadProject (projectToReload, changedLock);
} else if (changedLock != null) { + LockFileChanged = true;
await Runtime.RunInMainThread (() => { FileService.NotifyFileChanged (changedLock); NotifyProjectReferencesChanged (project); @@ -219,6 +223,7 @@ namespace MonoDevelop.PackageManagement {
return Runtime.RunInMainThread (async () => {
if (changedLock != null) {
+ LockFileChanged = true;
FileService.NotifyFileChanged (changedLock);
}
await projectToReload.ReevaluateProject (new ProgressMonitor ());
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopNuGetPackageManager.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopNuGetPackageManager.cs index fd33dc0dd8..6ce4b5637c 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopNuGetPackageManager.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopNuGetPackageManager.cs @@ -183,6 +183,20 @@ namespace MonoDevelop.PackageManagement ); } + public Task<BuildIntegratedProjectAction> PreviewBuildIntegratedProjectActionsAsync( + IBuildIntegratedNuGetProject buildIntegratedProject, + IEnumerable<NuGetProjectAction> nuGetProjectActions, + INuGetProjectContext nuGetProjectContext, + CancellationToken token) + { + return packageManager.PreviewBuildIntegratedProjectActionsAsync ( + (BuildIntegratedNuGetProject)buildIntegratedProject, + nuGetProjectActions, + nuGetProjectContext, + token + ); + } + public async Task OpenReadmeFiles ( NuGetProject nuGetProject, IEnumerable<PackageIdentity> packages, diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/NuGetPackageLicenseAuditor.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/NuGetPackageLicenseAuditor.cs index 2549e3653a..524df2d83e 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/NuGetPackageLicenseAuditor.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/NuGetPackageLicenseAuditor.cs @@ -32,6 +32,7 @@ using System.Threading.Tasks; using MonoDevelop.Core;
using NuGet.Common;
using NuGet.PackageManagement;
+using NuGet.Packaging;
using NuGet.Packaging.Core;
using NuGet.Protocol.Core.Types;
@@ -151,7 +152,12 @@ namespace MonoDevelop.PackageManagement var packages = new HashSet<PackageIdentity> (PackageIdentity.Comparer);
foreach (NuGetProjectAction action in installActions) {
- packages.Add (action.PackageIdentity);
+ var buildIntegratedAction = action as BuildIntegratedProjectAction;
+ if (buildIntegratedAction != null) {
+ packages.AddRange (GetPackages (buildIntegratedAction.GetProjectActions ()));
+ } else {
+ packages.Add (action.PackageIdentity);
+ }
}
return packages;
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageUpdateChecker.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageUpdateChecker.cs deleted file mode 100644 index 8850375e3e..0000000000 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageUpdateChecker.cs +++ /dev/null @@ -1,100 +0,0 @@ -//
-// PackageUpdateChecker.cs
-//
-// Author:
-// Matt Ward <matt.ward@xamarin.com>
-//
-// Copyright (c) 2014 Xamarin Inc. (http://xamarin.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-using System;
-using ICSharpCode.PackageManagement;
-using MonoDevelop.Core;
-
-namespace MonoDevelop.PackageManagement
-{
- public class PackageUpdateChecker
- {
- IUpdatedPackagesInSolution updatedPackagesInSolution;
- IPackageManagementProgressMonitorFactory progressMonitorFactory;
-
- public PackageUpdateChecker ()
- : this (
- PackageManagementServices.UpdatedPackagesInSolution,
- PackageManagementServices.ProgressMonitorFactory)
- {
- }
-
- public PackageUpdateChecker (
- IUpdatedPackagesInSolution updatedPackagesInSolution,
- IPackageManagementProgressMonitorFactory progressMonitorFactory)
- {
- this.updatedPackagesInSolution = updatedPackagesInSolution;
- this.progressMonitorFactory = progressMonitorFactory;
- }
-
- public void Run ()
- {
- try {
- CheckForPackageUpdatesWithProgressMonitor ();
- } catch (Exception ex) {
- LoggingService.LogInternalError ("PackageUpdateChecker error.", ex);
- }
- }
-
- void CheckForPackageUpdatesWithProgressMonitor ()
- {
- ProgressMonitorStatusMessage progressMessage = ProgressMonitorStatusMessageFactory.CreateCheckingForPackageUpdatesMessage ();
- using (ProgressMonitor progressMonitor = CreateProgressMonitor (progressMessage)) {
- try {
- using (var eventMonitor = new PackageUpdatesEventMonitor (progressMonitor)) {
- CheckForPackageUpdates (progressMonitor, progressMessage, eventMonitor);
- }
- } catch (Exception ex) {
- LoggingService.LogInternalError (ex);
- progressMonitor.Log.WriteLine (ex.Message);
- progressMonitor.ReportError (progressMessage.Error, null);
- progressMonitor.ShowPackageConsole ();
- }
- }
- }
-
- ProgressMonitor CreateProgressMonitor (ProgressMonitorStatusMessage progressMessage)
- {
- return progressMonitorFactory.CreateProgressMonitor (progressMessage.Status);
- }
-
- void CheckForPackageUpdates (
- ProgressMonitor progressMonitor,
- ProgressMonitorStatusMessage progressMessage,
- PackageUpdatesEventMonitor eventMonitor)
- {
- updatedPackagesInSolution.CheckForUpdates ();
- if (updatedPackagesInSolution.AnyUpdates ()) {
- progressMonitor.ReportSuccess (GettextCatalog.GetString ("Package updates are available."));
- } else if (eventMonitor.WarningReported) {
- progressMonitor.ReportWarning (progressMessage.Warning);
- } else {
- progressMonitor.ReportSuccess (progressMessage.Success);
- }
- }
- }
-}
-
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProgressMonitorStatusMessageFactory.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProgressMonitorStatusMessageFactory.cs index 9971a783cd..7b26a48c65 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProgressMonitorStatusMessageFactory.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProgressMonitorStatusMessageFactory.cs @@ -141,6 +141,16 @@ namespace MonoDevelop.PackageManagement );
}
+ public static ProgressMonitorStatusMessage CreateRemovingPackagesFromProjectMessage (int count)
+ {
+ return new ProgressMonitorStatusMessage (
+ GettextCatalog.GetString ("Removing {0} packages...", count),
+ GettextCatalog.GetString ("{0} packages successfully removed.", count),
+ GettextCatalog.GetString ("Could not remove packages."),
+ GettextCatalog.GetString ("{0} packages removed with warnings.", count)
+ );
+ }
+
public static ProgressMonitorStatusMessage CreateRestoringPackagesInSolutionMessage ()
{
return new ProgressMonitorStatusMessage (
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RestoreNuGetPackagesAction.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RestoreNuGetPackagesAction.cs index 66061fc176..9953f640ef 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RestoreNuGetPackagesAction.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RestoreNuGetPackagesAction.cs @@ -54,6 +54,7 @@ namespace MonoDevelop.PackageManagement RestorePackagesConfigProjects = true;
solutionManager = PackageManagementServices.Workspace.GetSolutionManager (solution);
+ solutionManager.ClearProjectCache ();
nugetProjects = solutionManager.GetNuGetProjects ().ToList ();
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/UninstallNuGetPackagesAction.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/UninstallNuGetPackagesAction.cs new file mode 100644 index 0000000000..c90e254c89 --- /dev/null +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/UninstallNuGetPackagesAction.cs @@ -0,0 +1,137 @@ +// +// UninstallNuGetPackagesAction.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2017 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using NuGet.PackageManagement; +using NuGet.Packaging.Core; +using NuGet.ProjectManagement; + +namespace MonoDevelop.PackageManagement +{ + class UninstallNuGetPackagesAction : IPackageAction, INuGetProjectActionsProvider + { + INuGetPackageManager packageManager; + IDotNetProject dotNetProject; + NuGetProject project; + INuGetProjectContext context; + IPackageManagementEvents packageManagementEvents; + IEnumerable<NuGetProjectAction> actions; + List<string> packageIds = new List<string> (); + + public UninstallNuGetPackagesAction ( + IMonoDevelopSolutionManager solutionManager, + IDotNetProject dotNetProject) + : this ( + solutionManager, + dotNetProject, + new NuGetProjectContext (), + new MonoDevelopNuGetPackageManager (solutionManager), + PackageManagementServices.PackageManagementEvents) + { + } + + public UninstallNuGetPackagesAction ( + IMonoDevelopSolutionManager solutionManager, + IDotNetProject dotNetProject, + INuGetProjectContext projectContext, + INuGetPackageManager packageManager, + IPackageManagementEvents packageManagementEvents) + { + this.dotNetProject = dotNetProject; + this.context = projectContext; + this.packageManager = packageManager; + this.packageManagementEvents = packageManagementEvents; + + project = solutionManager.GetNuGetProject (dotNetProject); + } + + public void AddPackageIds (IEnumerable<string> packageIds) + { + this.packageIds.AddRange (packageIds); + } + + public void Execute () + { + Execute (CancellationToken.None); + } + + public void Execute (CancellationToken cancellationToken) + { + using (var monitor = new NuGetPackageEventsMonitor (dotNetProject, packageManagementEvents)) { + ExecuteAsync (cancellationToken).Wait (); + } + } + + async Task ExecuteAsync (CancellationToken cancellationToken) + { + var buildIntegratedProject = project as IBuildIntegratedNuGetProject; + + actions = CreateUninstallActions (); + + var buildAction = await packageManager.PreviewBuildIntegratedProjectActionsAsync ( + buildIntegratedProject, + actions, + context, + cancellationToken); + + project.OnBeforeUninstall (actions); + + await packageManager.ExecuteNuGetProjectActionsAsync ( + project, + new [] { buildAction }, + context, + cancellationToken); + + project.OnAfterExecuteActions (actions); + + await project.RunPostProcessAsync (context, cancellationToken); + } + + IEnumerable<NuGetProjectAction> CreateUninstallActions () + { + return packageIds.Select (CreateUninstallProjectAction).ToArray (); + } + + NuGetProjectAction CreateUninstallProjectAction (string packageId) + { + var package = new PackageIdentity (packageId, null); + return NuGetProjectAction.CreateUninstallProjectAction (package, project); + } + + public IEnumerable<NuGetProjectAction> GetNuGetProjectActions () + { + return actions ?? Enumerable.Empty<NuGetProjectAction> (); + } + + public bool HasPackageScriptsToRun () + { + return false; + } + } +} diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.Rename/RenameRefactoring.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.Rename/RenameRefactoring.cs index 933e9b068e..d313fc4ccb 100644 --- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.Rename/RenameRefactoring.cs +++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.Rename/RenameRefactoring.cs @@ -151,7 +151,7 @@ namespace MonoDevelop.Refactoring.Rename editor.ReplaceText (v.Offset, v.RemovalLength, v.InsertedText); } } - })); + }) { TextLinkPurpose = TextLinkPurpose.Rename }); } public class RenameProperties diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor.Theatrics/SmartScrolledWindow.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor.Theatrics/SmartScrolledWindow.cs index 70c84a6805..13d6d059cb 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor.Theatrics/SmartScrolledWindow.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor.Theatrics/SmartScrolledWindow.cs @@ -46,7 +46,7 @@ namespace Mono.TextEditor.Theatrics } } - public class SmartScrolledWindowContainerChild : Container.ContainerChild + internal class SmartScrolledWindowContainerChild : Container.ContainerChild { public ChildPosition ChildPosition { get; diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/GtkGestures.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/GtkGestures.cs deleted file mode 100644 index b0dccb73bb..0000000000 --- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/GtkGestures.cs +++ /dev/null @@ -1,254 +0,0 @@ -// -// GtkGestures.cs -// -// Author: -// Michael Hutchinson <mhutch@xamarin.com> -// -// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Runtime.InteropServices; -using Gdk; -using MonoDevelop.Components; -using MonoDevelop.Core; - -namespace Mono.TextEditor -{ - static class GtkGestures - { - const int GDK_GESTURE_MAGNIFY = 37; - const int GDK_GESTURE_ROTATE = 38; - const int GDK_GESTURE_SWIPE = 39;
-
- [DllImport (PangoUtil.LIBGDK, CallingConvention = CallingConvention.Cdecl)] - static extern bool gdk_quartz_supports_gesture_events (); - - static bool isSupported; - - static GtkGestures () - { - if (Platform.IsMac) { - try { - isSupported = gdk_quartz_supports_gesture_events () && Environment.GetEnvironmentVariable ("DISABLE_ZOOM_GESTURE") == null; - } catch (EntryPointNotFoundException) { - } - } - } - - public static bool IsSupported { get { return isSupported; } } - - public static void AddGestureMagnifyHandler (this Gtk.Widget widget, EventHandler<GestureMagnifyEventArgs> handler) - { - if (!isSupported) - throw new NotSupportedException (); - var signal = GLib.Signal.Lookup (widget, "gesture-magnify-event", typeof(GestureMagnifyEventArgs)); - signal.AddDelegate (new EventHandler<GestureMagnifyEventArgs> (handler)); - } - - public static void AddGestureRotateHandler (this Gtk.Widget widget, EventHandler<GestureRotateEventArgs> handler) - { - if (!isSupported) - throw new NotSupportedException (); - var signal = GLib.Signal.Lookup (widget, "gesture-rotate-event", typeof(GestureRotateEventArgs)); - signal.AddDelegate (new EventHandler<GestureRotateEventArgs> (handler)); - } - - public static void AddGestureSwipeHandler (this Gtk.Widget widget, EventHandler<GestureSwipeEventArgs> handler) - { - if (!isSupported) - throw new NotSupportedException (); - var signal = GLib.Signal.Lookup (widget, "gesture-swipe-event", typeof(GestureSwipeEventArgs)); - signal.AddDelegate (new EventHandler<GestureSwipeEventArgs> (handler)); - } - } - - public unsafe class GestureMagnifyEventArgs : GLib.SignalArgs - { - //have to force pack=4, or Mono aligns doubles to 8 bytes - [StructLayout (LayoutKind.Sequential, Pack=4)] - struct GdkEventGestureMagnify - { - public Gdk.EventType type; - public IntPtr window; - public sbyte send_event; - public uint time; - public double x, y; - public uint state; - public double magnification; - public IntPtr device; - public double x_root, y_root; - } - - // I tried to mimic the GTK# pattern of having a subclassed Event object on the EventArgs, but I gave up on - // figuring out how to get GTK# to marshal the event to a custom GestureMagnifyEvent class. Instead we just - // lift all the accessors up to the args class and dereference the handle directly. - GdkEventGestureMagnify *evt { - get { - var handle = ((Event)Args[0]).Handle; - return (GdkEventGestureMagnify *) handle; - } - } - - public Gdk.Window Window { - get { - return (Gdk.Window) GLib.Object.GetObject (evt->window); - } - } - - public Device Device { - get { - return (Device) GLib.Object.GetObject (evt->device); - } - } - - public uint Time { get { return evt->time; } } - public double X { get { return evt->x; } } - public double Y { get { return evt->y; } } - public ModifierType State { get { return (ModifierType) evt->state; } } - public double Magnification { get { return evt->magnification; } } - public double XRoot { get { return evt->x_root; } } - public double YRoot { get { return evt->y_root; } } - } - - public unsafe class GestureRotateEventArgs : GLib.SignalArgs - { - [StructLayout (LayoutKind.Sequential, Pack=4)] - struct GdkEventGestureRotate - { - public Gdk.EventType type; - public IntPtr window; - public sbyte send_event; - public uint time; - public double x, y; - public uint state; - public double rotation; - public IntPtr device; - public double x_root, y_root; - } - - GdkEventGestureRotate *evt { - get { - var handle = ((Event)Args[0]).Handle; - return (GdkEventGestureRotate *) handle; - } - } - - public Gdk.Window Window { - get { - return (Gdk.Window) GLib.Object.GetObject (evt->window); - } - } - - public Device Device { - get { - return (Device) GLib.Object.GetObject (evt->device); - } - } - - public uint Time { get { return evt->time; } } - public double X { get { return evt->x; } } - public double Y { get { return evt->y; } } - public ModifierType State { get { return (ModifierType) evt->state; } } - public double Rotation { get { return evt->rotation; } } - public double XRoot { get { return evt->x_root; } } - public double YRoot { get { return evt->y_root; } } - } - - public unsafe class GestureSwipeEventArgs : GLib.SignalArgs - { - [StructLayout (LayoutKind.Sequential, Pack=4)] - struct GdkEventGestureSwipe - { - public Gdk.EventType type; - public IntPtr window; - public sbyte send_event; - public uint time; - public double x, y; - public uint state; - public double delta_x, delta_y; - public IntPtr device; - public double x_root, y_root; - } - - GdkEventGestureSwipe *evt { - get { - var handle = ((Event)Args[0]).Handle; - return (GdkEventGestureSwipe *) handle; - } - } - - public Gdk.Window Window { - get { - return (Gdk.Window) GLib.Object.GetObject (evt->window); - } - } - - public Device Device { - get { - return (Device) GLib.Object.GetObject (evt->device); - } - } - - public uint Time { get { return evt->time; } } - public double X { get { return evt->x; } } - public double Y { get { return evt->y; } } - public ModifierType State { get { return (ModifierType) evt->state; } } - public double DeltaX { get { return evt->delta_x; } } - public double DeltaY { get { return evt->delta_y; } } - public double XRoot { get { return evt->x_root; } } - public double YRoot { get { return evt->y_root; } } - } - - /* - void PrintOffsets () - { - GdkEventGestureMagnify *v = (GdkEventGestureMagnify *)0; - Console.WriteLine ("type {0}", (int)&(v->type)); - Console.WriteLine ("window {0}", (int)&(v->window)); - Console.WriteLine ("send_event {0}", (int)&(v->send_event)); - Console.WriteLine ("time {0}", (int)&(v->time)); - Console.WriteLine ("x {0}", (int)&(v->x)); - Console.WriteLine ("y {0}", (int)&(v->y)); - Console.WriteLine ("state {0}", (int)&(v->state)); - Console.WriteLine ("magnification {0}", (int)&(v->magnification)); - Console.WriteLine ("x_root {0}", (int)&(v->x_root)); - Console.WriteLine ("y_root {0}", (int)&(v->y_root)); - } - - // gcc -m32 test.c `pkg-config --cflags gtk+-2.0` - #include <gtk/gtk.h> - - int main (int argc, char* argv) - { - GdkEventGestureMagnify *v = (GdkEventGestureMagnify *)0; - printf ("type %d\n", (int)&(v->type)); - printf ("window %d\n", (int)&(v->window)); - printf ("send_event %d\n", (int)&(v->send_event)); - printf ("time %d\n", (int)&(v->time)); - printf ("x %d\n", (int)&(v->x)); - printf ("y %d\n", (int)&(v->y)); - printf ("state %d\n", (int)&(v->state)); - printf ("magnification %d\n", (int)&(v->magnification)); - printf ("x_root %d\n", (int)&(v->x_root)); - printf ("y_root %d\n", (int)&(v->y_root)); - } - */ -} diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/LayoutCache.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/LayoutCache.cs index 4fad068cdd..9a31affd87 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/LayoutCache.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/LayoutCache.cs @@ -64,7 +64,7 @@ namespace Mono.TextEditor } #endregion - public class LayoutProxy : IDisposable + internal class LayoutProxy : IDisposable { readonly LayoutCache layoutCache; readonly Pango.Layout layout; diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/MonoTextEditor.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/MonoTextEditor.cs index a4b3eaa897..977e7df5fd 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/MonoTextEditor.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/MonoTextEditor.cs @@ -196,7 +196,7 @@ namespace Mono.TextEditor } } - public class EditorContainerChild : Container.ContainerChild + internal class EditorContainerChild : Container.ContainerChild { public int X { get; set; } public int Y { get; set; } diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextArea.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextArea.cs index 8817365133..e63906fc91 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextArea.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextArea.cs @@ -2432,7 +2432,7 @@ namespace Mono.TextEditor In, Out, Bounce } - public class RegionPulseAnimation : IAnimationDrawer + internal class RegionPulseAnimation : IAnimationDrawer { MonoTextEditor editor; diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextEditorAccessibility.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextEditorAccessibility.cs index e51285e27d..69687907c7 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextEditorAccessibility.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextEditorAccessibility.cs @@ -374,7 +374,7 @@ namespace Mono.TextEditor } } - public class BaseWidgetAccessible : Gtk.Accessible, Atk.ComponentImplementor + internal class BaseWidgetAccessible : Gtk.Accessible, Atk.ComponentImplementor { private Gtk.Widget widget; private uint focus_id = 0; diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs index e3c3d7f3f9..9acd89252a 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs @@ -203,7 +203,7 @@ namespace Mono.TextEditor selectedRegions.Clear (); } - public class SearchWorkerArguments + internal class SearchWorkerArguments { public int FirstLine { get; set; } @@ -802,7 +802,7 @@ namespace Mono.TextEditor LayoutDescriptor descriptor; if (!containsPreedit && layoutDict.TryGetValue (line, out descriptor)) { bool isInvalid; - if (descriptor.Equals (line, offset, length, selectionStart, selectionEnd, out isInvalid) && descriptor.Layout != null) { + if (descriptor.Equals (line, offset, length, selectionStart, selectionEnd, out isInvalid) && descriptor?.Layout?.Layout != null) { return descriptor.Layout; } descriptor.Dispose (); @@ -1227,7 +1227,7 @@ namespace Mono.TextEditor return Encoding.UTF8.GetString (bytes, 0, index).Length; } - public class LayoutWrapper : IDisposable + internal class LayoutWrapper : IDisposable { readonly TextViewMargin parent; @@ -1317,7 +1317,7 @@ namespace Mono.TextEditor } } - public class BackgroundColor + internal class BackgroundColor { public readonly Cairo.Color Color; public readonly int FromIdx; @@ -1355,6 +1355,8 @@ namespace Mono.TextEditor public Pango.Rectangle IndexToPos (int index) { + if (Layout == null) + return Pango.Rectangle.Zero; return Layout.IndexToPos (index); } diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/BehaviorPanel.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/BehaviorPanel.cs index 0b413efb49..bf60e42f33 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/BehaviorPanel.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/BehaviorPanel.cs @@ -32,7 +32,7 @@ using MonoDevelop.Ide.Editor; namespace MonoDevelop.SourceEditor.OptionPanels { - public partial class BehaviorPanel : Gtk.Bin, IOptionsPanel + partial class BehaviorPanel : Gtk.Bin, IOptionsPanel { public BehaviorPanel () { diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/HighlightingPanel.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/HighlightingPanel.cs index 80a3af868a..432c9ab61c 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/HighlightingPanel.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/HighlightingPanel.cs @@ -39,7 +39,7 @@ using System.Diagnostics; namespace MonoDevelop.SourceEditor.OptionPanels { - public partial class HighlightingPanel : Gtk.Bin, IOptionsPanel + partial class HighlightingPanel : Gtk.Bin, IOptionsPanel { string schemeName; ListStore styleStore = new ListStore (typeof (string), typeof (MonoDevelop.Ide.Editor.Highlighting.EditorTheme), typeof (bool)); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/MarkerPanel.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/MarkerPanel.cs index 823fc3add0..ab8d320bbf 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/MarkerPanel.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/MarkerPanel.cs @@ -33,7 +33,7 @@ using MonoDevelop.Ide; namespace MonoDevelop.SourceEditor.OptionPanels { - public partial class MarkerPanel : Gtk.Bin, IOptionsPanel + partial class MarkerPanel : Gtk.Bin, IOptionsPanel { bool showLineNumbers; diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/NewColorShemeDialog.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/NewColorShemeDialog.cs index d65170afa7..ca12d8fa90 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/NewColorShemeDialog.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/NewColorShemeDialog.cs @@ -30,7 +30,7 @@ using MonoDevelop.Ide.Editor.Highlighting; namespace MonoDevelop.SourceEditor.OptionPanels { - public partial class NewColorShemeDialog : Gtk.Dialog + partial class NewColorShemeDialog : Gtk.Dialog { Gtk.ListStore store = new Gtk.ListStore (typeof(string)); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs index 5e50e51c76..73c8aab6a2 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs @@ -958,7 +958,7 @@ namespace MonoDevelop.SourceEditor.QuickTasks switch (drawingStep) { case 0: var displayScale = Core.Platform.IsMac ? GtkWorkarounds.GetScaleFactor (mode) : 1.0; - CachedDraw (cr, ref mode.backgroundSurface, allocation, draw: (c, o) => mode.DrawBackground (c, allocation), forceScale: displayScale); + mode.DrawBackground (cr, allocation); drawingStep++; return true; case 1: diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.csproj b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.csproj index 9e9ef2f05b..4a97e84ba9 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.csproj +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.csproj @@ -198,7 +198,6 @@ <Compile Include="Mono.TextEditor\Gui\DashedLineMargin.cs" /> <Compile Include="Mono.TextEditor\Gui\FoldingScreenbackgroundRenderer.cs" /> <Compile Include="Mono.TextEditor\Gui\FoldMarkerMargin.cs" /> - <Compile Include="Mono.TextEditor\Gui\GtkGestures.cs" /> <Compile Include="Mono.TextEditor\Gui\GutterMargin.cs" /> <Compile Include="Mono.TextEditor\Gui\IAnimationDrawer.cs" /> <Compile Include="Mono.TextEditor\Gui\IBackgroundRenderer.cs" /> diff --git a/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.BehaviorPanel.cs b/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.BehaviorPanel.cs index bdcae8703c..d052176e1d 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.BehaviorPanel.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.BehaviorPanel.cs @@ -2,7 +2,7 @@ // This file has been generated by the GUI designer. Do not modify. namespace MonoDevelop.SourceEditor.OptionPanels { - public partial class BehaviorPanel + partial class BehaviorPanel { private global::Gtk.VBox vbox1; diff --git a/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.CompletionAppearancePanel.cs b/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.CompletionAppearancePanel.cs index 5bce3c3b27..3fbe176705 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.CompletionAppearancePanel.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.CompletionAppearancePanel.cs @@ -2,7 +2,7 @@ // This file has been generated by the GUI designer. Do not modify. namespace MonoDevelop.SourceEditor.OptionPanels { - public partial class CompletionAppearancePanel + partial class CompletionAppearancePanel { private global::Gtk.VBox vbox1; diff --git a/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.HighlightingPanel.cs b/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.HighlightingPanel.cs index ded620fec7..f66ed07605 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.HighlightingPanel.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.HighlightingPanel.cs @@ -2,7 +2,7 @@ // This file has been generated by the GUI designer. Do not modify. namespace MonoDevelop.SourceEditor.OptionPanels { - public partial class HighlightingPanel + partial class HighlightingPanel { private global::Gtk.VBox vbox5; diff --git a/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.MarkerPanel.cs b/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.MarkerPanel.cs index 740062f8fd..a42521e0d2 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.MarkerPanel.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.MarkerPanel.cs @@ -2,7 +2,7 @@ // This file has been generated by the GUI designer. Do not modify. namespace MonoDevelop.SourceEditor.OptionPanels { - public partial class MarkerPanel + partial class MarkerPanel { private global::Gtk.VBox vbox1; diff --git a/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.NewColorShemeDialog.cs b/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.NewColorShemeDialog.cs index efa3323b30..1dbba5b78b 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.NewColorShemeDialog.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/MonoDevelop.SourceEditor.OptionPanels.NewColorShemeDialog.cs @@ -2,7 +2,7 @@ // This file has been generated by the GUI designer. Do not modify. namespace MonoDevelop.SourceEditor.OptionPanels { - public partial class NewColorShemeDialog + partial class NewColorShemeDialog { private global::Gtk.Table table1; diff --git a/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/gui.stetic b/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/gui.stetic index 26eb5ddad4..edacf8aab7 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/gui.stetic +++ b/main/src/addins/MonoDevelop.SourceEditor2/gtk-gui/gui.stetic @@ -264,6 +264,7 @@ </widget> <widget class="Gtk.Bin" id="MonoDevelop.SourceEditor.OptionPanels.MarkerPanel" design-size="416 434"> <property name="MemberName" /> + <property name="GeneratePublic">False</property> <child> <widget class="Gtk.VBox" id="vbox1"> <property name="MemberName" /> @@ -572,6 +573,7 @@ </widget> <widget class="Gtk.Bin" id="MonoDevelop.SourceEditor.OptionPanels.BehaviorPanel" design-size="426 436"> <property name="MemberName" /> + <property name="GeneratePublic">False</property> <child> <widget class="Gtk.VBox" id="vbox1"> <property name="MemberName" /> @@ -925,6 +927,7 @@ </widget> <widget class="Gtk.Bin" id="MonoDevelop.SourceEditor.OptionPanels.HighlightingPanel" design-size="1074 503"> <property name="MemberName" /> + <property name="GeneratePublic">False</property> <child> <widget class="Gtk.VBox" id="vbox5"> <property name="MemberName" /> @@ -1985,4 +1988,4 @@ </widget> </child> </widget> -</stetic-interface> +</stetic-interface>
\ No newline at end of file diff --git a/main/src/addins/TextTemplating/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs b/main/src/addins/TextTemplating/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs index bac0fd4ec0..7720093b36 100644 --- a/main/src/addins/TextTemplating/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs +++ b/main/src/addins/TextTemplating/Mono.TextTemplating/Mono.TextTemplating/TemplatingEngine.cs @@ -183,8 +183,11 @@ namespace Mono.TextTemplating continue; string resolvedAssem = host.ResolveAssemblyReference (assem); - if (!string.IsNullOrEmpty (resolvedAssem) && File.Exists (resolvedAssem)) { - resolved [AssemblyName.GetAssemblyName (resolvedAssem).FullName] = resolvedAssem; + if (!string.IsNullOrEmpty (resolvedAssem)) { + var assemblyName = resolvedAssem; + if (File.Exists (resolvedAssem)) + assemblyName = AssemblyName.GetAssemblyName (resolvedAssem).FullName; + resolved [assemblyName] = resolvedAssem; } else { pt.LogError ("Could not resolve assembly reference '" + assem + "'"); return null; diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Highlighting/XmlReadHelper.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Highlighting/XmlReadHelper.cs index 87634ccea5..bdf9ab1eb7 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Highlighting/XmlReadHelper.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Highlighting/XmlReadHelper.cs @@ -37,7 +37,7 @@ namespace Mono.TextEditor.Highlighting public delegate bool ReaderCallback (); public delegate bool ReaderCallbackWithData (ReadCallbackData data); - public class ReadCallbackData { + internal class ReadCallbackData { bool skipNextRead = false; public bool SkipNextRead { get { return skipNextRead; } diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/FileSettingsStore.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/FileSettingsStore.cs index 00e9261896..34239773d8 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/FileSettingsStore.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/FileSettingsStore.cs @@ -31,7 +31,7 @@ namespace Mono.TextEditor.Utils static class FileSettingsStore { - public class Settings + internal class Settings { public int CaretOffset { get; set; } diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/RedBlackTree.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/RedBlackTree.cs index e6d793716a..7acfd25f54 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/RedBlackTree.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/RedBlackTree.cs @@ -470,7 +470,7 @@ namespace Mono.TextEditor.Utils #endregion - public class RedBlackTreeNodeEventArgs : EventArgs + internal class RedBlackTreeNodeEventArgs : EventArgs { public T Node { get; private set; } diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Actions/ClipboardActions.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Actions/ClipboardActions.cs index d3d87c4567..7b22b9ff46 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Actions/ClipboardActions.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Actions/ClipboardActions.cs @@ -64,7 +64,7 @@ namespace Mono.TextEditor clipboard.SetWithData (CopyOperation.TargetEntries, operation.ClipboardGetFunc, operation.ClipboardClearFunc); } - public class CopyOperation + internal class CopyOperation { public const int TextType = 1; public const int HTMLTextType = 2; diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs index 176d07e6b7..6857982653 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs @@ -622,7 +622,7 @@ namespace Mono.TextEditor #endregion #region Undo/Redo operations - public class UndoOperation + internal class UndoOperation { TextChangeEventArgs args; @@ -1887,7 +1887,7 @@ namespace Mono.TextEditor } - public class SnapshotDocument : TextDocument + internal class SnapshotDocument : TextDocument { readonly ITextSourceVersion version; public override ITextSourceVersion Version { diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/HeightTree.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/HeightTree.cs index 6157abccef..a79a98c8f4 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/HeightTree.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/HeightTree.cs @@ -114,7 +114,7 @@ namespace Mono.TextEditor handler (this, e); } - public class HeightChangedEventArgs : EventArgs + internal class HeightChangedEventArgs : EventArgs { public int Line { get; set; } @@ -235,7 +235,7 @@ namespace Mono.TextEditor OnLineUpdateFrom (new HeightChangedEventArgs (lineNumber)); } - public class FoldMarker + internal class FoldMarker { public readonly int Line; public readonly int Count; @@ -526,7 +526,7 @@ namespace Mono.TextEditor } } - public class HeightNode : IRedBlackTreeNode + internal class HeightNode : IRedBlackTreeNode { public double totalHeight; public double height; diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetRuntime.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetRuntime.cs index 60aff87963..e3320c91d4 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetRuntime.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetRuntime.cs @@ -178,10 +178,7 @@ namespace MonoDevelop.Core.Assemblies } } - /// <summary> - /// Given an assembly file name, returns the corresponding debug information file name. - /// (.mdb for Mono, .pdb for MS.NET) - /// </summary> + [Obsolete ("Use DotNetProject.GetAssemblyDebugInfoFile()")] public abstract string GetAssemblyDebugInfoFile (string assemblyPath); /// <summary> diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ExecutionTarget.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ExecutionTarget.cs index 711849a89b..0cc2485439 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ExecutionTarget.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ExecutionTarget.cs @@ -72,6 +72,18 @@ namespace MonoDevelop.Core.Execution public bool Notable { get; set; } /// <summary> + /// Gets or sets the image name that should be used for this <see cref="MonoDevelop.Core.Execution.ExecutionTarget"/>. + /// </summary> + /// <value>The name of the image.</value> + public string Image { get; set; } + + /// <summary> + /// Gets or sets the tooltip that should be used for this <see cref="MonoDevelop.Core.Execution.ExecutionTarget"/>. + /// </summary> + /// <value>The text to be shown in the tooltip.</value> + public string Tooltip { get; set; } + + /// <summary> /// Target group on which this target is included /// </summary> public ExecutionTargetGroup ParentGroup { get; internal set; } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ExternalConsoleFactory.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ExternalConsoleFactory.cs index 50231e64ca..bdffae79fa 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ExternalConsoleFactory.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ExternalConsoleFactory.cs @@ -38,7 +38,7 @@ namespace MonoDevelop.Core.Execution public ExternalConsole CreateConsole (bool closeOnDispose, CancellationToken cancellationToken = default (CancellationToken)) { - var c = new ExternalConsole (closeOnDispose); + var c = new ExternalConsole (closeOnDispose, null); if (cancellationToken != default(CancellationToken)) c.BindToCancelToken (cancellationToken); return c; @@ -46,19 +46,22 @@ namespace MonoDevelop.Core.Execution protected override OperationConsole OnCreateConsole (CreateConsoleOptions options) { - return new ExternalConsole (true); + return new ExternalConsole (!options.PauseWhenFinished, options.Title); } } public sealed class ExternalConsole: OperationConsole { - internal ExternalConsole (bool closeOnDispose) + internal ExternalConsole (bool closeOnDispose, string title) { CloseOnDispose = closeOnDispose; + Title = title; } public bool CloseOnDispose { get; set; } + public string Title { get; set; } + public override TextReader In { get { return Console.In; } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/OperationConsoleFactory.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/OperationConsoleFactory.cs index daa81a7e22..52632626f8 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/OperationConsoleFactory.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/OperationConsoleFactory.cs @@ -35,10 +35,11 @@ namespace MonoDevelop.Core.Execution { public class CreateConsoleOptions { - public static readonly CreateConsoleOptions Default = new CreateConsoleOptions { BringToFront = true }; + public static readonly CreateConsoleOptions Default = new CreateConsoleOptions { BringToFront = true, PauseWhenFinished = true }; public bool BringToFront { get; private set; } public string Title { get; private set; } + public bool PauseWhenFinished { get; private set; } CreateConsoleOptions () { @@ -48,6 +49,7 @@ namespace MonoDevelop.Core.Execution { this.BringToFront = options.BringToFront; this.Title = options.Title; + this.PauseWhenFinished = options.PauseWhenFinished; } public CreateConsoleOptions (bool bringToFront) @@ -72,6 +74,15 @@ namespace MonoDevelop.Core.Execution result.Title = title; return result; } + + public CreateConsoleOptions WithPauseWhenFinished (bool pausedWhenFinished) + { + if (pausedWhenFinished == PauseWhenFinished) + return this; + var result = new CreateConsoleOptions (this); + result.PauseWhenFinished = pausedWhenFinished; + return result; + } } public OperationConsole CreateConsole (CancellationToken cancellationToken = default (CancellationToken)) diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessService.cs index 2d12c35878..96fddffb6e 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessService.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessService.cs @@ -206,7 +206,7 @@ namespace MonoDevelop.Core.Execution dict[kvp.Key] = kvp.Value; var p = externalConsoleHandler (command, arguments, workingDirectory, dict, - GettextCatalog.GetString ("{0} External Console", BrandingService.ApplicationName), + externalConsole?.Title ?? GettextCatalog.GetString ("{0} External Console", BrandingService.ApplicationName), externalConsole != null ? !externalConsole.CloseOnDispose : false); if (p != null) { diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/RemoteProcessConnection.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/RemoteProcessConnection.cs index 7ce7b5f8e4..da72f423a9 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/RemoteProcessConnection.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/RemoteProcessConnection.cs @@ -508,21 +508,30 @@ namespace MonoDevelop.Core.Execution return; } - lock (pendingMessageTasks) { - var t = Task.Run (() => { - msg = LoadMessageData (msg); - if (type == 0) - ProcessResponse (msg); - else - ProcessRemoteMessage (msg); - }); - t.ContinueWith (ta => { - lock (pendingMessageTasks) { - pendingMessageTasks.Remove (ta); - } - }).Ignore (); + HandleMessage (msg, type); + } + } + + async void HandleMessage (BinaryMessage msg, byte type) + { + var t = Task.Run (() => { + msg = LoadMessageData (msg); + if (type == 0) + ProcessResponse (msg); + else + ProcessRemoteMessage (msg); + }); + + try { + lock (pendingMessageTasks) pendingMessageTasks.Add (t); - } + + await t.ConfigureAwait (false); + } catch (Exception e) { + LoggingService.LogError ("RemoteProcessConnection.HandleMessage failed", e); + } finally { + lock (pendingMessageTasks) + pendingMessageTasks.Remove (t); } } @@ -530,7 +539,8 @@ namespace MonoDevelop.Core.Execution public Task ProcessPendingMessages () { - return Task.WhenAll (pendingMessageTasks.ToArray ()); + lock (pendingMessageTasks) + return Task.WhenAll (pendingMessageTasks.ToArray ()); } BinaryMessage LoadMessageData (BinaryMessage msg) diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs index 42ef306d01..516cf9f505 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs @@ -181,8 +181,11 @@ namespace MonoDevelop.Projects.MSBuild internal static string DefaultExtensionsPath { get { - if (extensionsPath == null) - extensionsPath = Environment.GetEnvironmentVariable ("MSBuildExtensionsPath"); + if (extensionsPath == null) { + var path = Environment.GetEnvironmentVariable ("MSBuildExtensionsPath"); + if (path != null && !IsExternalMSBuildExtensionsPath (path)) + extensionsPath = path; + } if (extensionsPath == null) { // NOTE: code from mcs/tools/gacutil/driver.cs @@ -200,6 +203,40 @@ namespace MonoDevelop.Projects.MSBuild } } + static string macOSXExternalXBuildDir; + + static string DefaultMacOSXExternalXBuildDir { + get { + if (macOSXExternalXBuildDir == null) { + var path = Environment.GetEnvironmentVariable ("MSBuildExtensionsPath"); + if (path != null && IsExternalMSBuildExtensionsPath (path)) + macOSXExternalXBuildDir = path; + else + macOSXExternalXBuildDir = MacOSXExternalXBuildDir; + } + return macOSXExternalXBuildDir; + } + } + + static bool IsExternalMSBuildExtensionsPath (string path) + { + // Mono has a hack to allow loading msbuild targets from different locations. Besides the default location + // inside Mono, targets are also loaded from /Library/Frameworks/Mono.framework/External/xbuild. + // When evaluating an msbuild project, MSBuildExtensionsPath is replaced by those locations. + + // This check is a workaround for a special corner case that happens, for example, when building the Xamarin SDKs. + // In that case, the MSBuildExtensionsPath env var is specified to point to a local version of the msbuild targets + // that are usually installed in /Library/Frameworks/Mono.framework/External/xbuild. + // However, by setting this variable, the new value replaces the default build target location, and msbuild + // can't finde Microsoft.Common.props. + + // This check is done to avoid overwriting the default msbuild builds target location when what is being + // specified in MSBuildExtensionsPath is actually a path that intends to replace the external build + // targets path. + + return Platform.IsMac && path.Contains ("Mono.framework/External/xbuild"); + } + static string DotConfigExtensionsPath = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData), Path.Combine ("xbuild", "tasks")); const string MacOSXExternalXBuildDir = "/Library/Frameworks/Mono.framework/External/xbuild"; @@ -209,7 +246,7 @@ namespace MonoDevelop.Projects.MSBuild if (Platform.IsWindows) yield return null; if (Platform.IsMac) - yield return MacOSXExternalXBuildDir; + yield return DefaultMacOSXExternalXBuildDir; yield return DotConfigExtensionsPath; yield return DefaultExtensionsPath; } @@ -498,7 +535,13 @@ namespace MonoDevelop.Projects.MSBuild i += 3; return EvaluateMember (type, null, prop, i, out val); } - int n = prop.IndexOf ('.'); + + int n = prop.IndexOf ('['); + if (n > 0) { + return EvaluateStringAtIndex (prop, n, out val); + } + + n = prop.IndexOf ('.'); if (n == -1) { needsItemEvaluation |= (!ignorePropsWithTransforms && propertiesWithTransforms.Contains (prop)); val = GetPropertyValue (prop) ?? string.Empty; @@ -790,7 +833,32 @@ namespace MonoDevelop.Projects.MSBuild } else flags |= BindingFlags.NonPublic; - return type.GetMember (memberName, flags | BindingFlags.Public); + return type.GetMember (memberName, flags | BindingFlags.Public | BindingFlags.IgnoreCase); + } + + bool EvaluateStringAtIndex (string prop, int i, out object val) + { + val = null; + + int j = prop.IndexOf (']'); + if (j == -1) + return false; + + if (j < prop.Length - 1 || j - i < 2) + return false; + + string indexText = prop.Substring (i + 1, j - (i + 1)); + int index = -1; + if (!int.TryParse (indexText, out index)) + return false; + + prop = prop.Substring (0, i); + string propertyValue = GetPropertyValue (prop) ?? string.Empty; + if (propertyValue.Length <= index) + return false; + + val = propertyValue.Substring (index, 1); + return true; } static Tuple<Type, string []> [] supportedTypeMembers = { diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs index fe94d5a5c0..8421eb513e 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs @@ -368,6 +368,13 @@ namespace MonoDevelop.Projects.MSBuild }); } + internal Task<bool> SaveAsync (string fileName, string content) + { + return Task.Run (() => { + return TextFile.WriteFile (fileName, content, format.ByteOrderMark, true); + }); + } + public string SaveToString () { IsNewProject = false; diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Policies/PolicyService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Policies/PolicyService.cs index e4bc64f5f2..57892037cf 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Policies/PolicyService.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Policies/PolicyService.cs @@ -1220,6 +1220,12 @@ namespace MonoDevelop.Projects.Policies defaultPolicies = null; if (Directory.Exists (PoliciesFolder)) { + // Remove duplicate generated by a bug in the policy saving code + foreach (var file in Directory.GetFiles (PoliciesFolder, "*.mdpolicy.mdpolicy.xml")) + File.Delete (file); + foreach (var file in Directory.GetFiles (PoliciesFolder, "*.mdpolicy.mdpolicy.xml.previous")) + File.Delete (file); + foreach (var file in Directory.GetFiles (PoliciesFolder, "*.mdpolicy.xml")) { try { LoadPolicy (file); diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs index d0a7dfe9b2..b0d0205832 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs @@ -613,7 +613,7 @@ namespace MonoDevelop.Projects // Debug info file if (conf.DebugSymbols) { - string mdbFile = TargetRuntime.GetAssemblyDebugInfoFile (conf.CompiledOutputName); + string mdbFile = GetAssemblyDebugInfoFile (conf.Selector, conf.CompiledOutputName); list.Add (mdbFile); } @@ -714,9 +714,12 @@ namespace MonoDevelop.Projects list.Add (file, copyIfNewer); if (File.Exists (file + ".config")) list.Add (file + ".config", copyIfNewer); - string mdbFile = TargetRuntime.GetAssemblyDebugInfoFile (file); - if (File.Exists (mdbFile)) - list.Add (mdbFile, copyIfNewer); + string debugFile = file + ".mdb"; + if (File.Exists (debugFile)) + list.Add (debugFile, copyIfNewer); + debugFile = Path.ChangeExtension (file, ".pdb"); + if (File.Exists (debugFile)) + list.Add (debugFile, copyIfNewer); } } else { @@ -1131,7 +1134,7 @@ namespace MonoDevelop.Projects if (GeneratesDebugInfoFile && conf != null && conf.DebugSymbols) { string file = GetOutputFileName (configuration); if (file != null) { - file = TargetRuntime.GetAssemblyDebugInfoFile (file); + file = GetAssemblyDebugInfoFile (configuration, file); var finfo = new FileInfo (file); if (finfo.Exists) { var debugFileBuildTime = finfo.LastWriteTime; @@ -1143,6 +1146,25 @@ namespace MonoDevelop.Projects return outputBuildTime; } + public FilePath GetAssemblyDebugInfoFile (ConfigurationSelector configuration) + { + return GetAssemblyDebugInfoFile (configuration, GetOutputFileName (configuration)); + } + + public FilePath GetAssemblyDebugInfoFile (ConfigurationSelector configuration, FilePath exeFile) + { + if (CheckUseMSBuildEngine (configuration)) { + var mono = TargetRuntime as MonoTargetRuntime; + if (mono != null) { + var version = mono.MonoRuntimeInfo?.RuntimeVersion; + if (version == null || (version < new Version (4, 9, 0))) + return exeFile + ".mdb"; + } + return exeFile.ChangeExtension (".pdb"); + } else + return exeFile + ".mdb"; + } + public IList<string> GetUserAssemblyPaths (ConfigurationSelector configuration) { if (ParentSolution == null) diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs index bbdf03097b..85374ec22d 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs @@ -631,10 +631,10 @@ namespace MonoDevelop.Projects SetFastBuildCheckDirty (); modifiedInMemory = false; - await WriteProjectAsync (monitor); + string content = await WriteProjectAsync (monitor); // Doesn't save the file to disk if the content did not change - if (await sourceProject.SaveAsync (FileName)) { + if (await sourceProject.SaveAsync (FileName, content)) { if (userProject != null) { if (!userProject.GetAllObjects ().Any ()) File.Delete (userProject.FileName); @@ -1157,10 +1157,11 @@ namespace MonoDevelop.Projects MSBuildResult result = null; await Task.Run (async delegate { + bool operationRequiresExclusiveLock = false; TimerCounter buildTimer = null; switch (target) { - case "Build": buildTimer = Counters.BuildMSBuildProjectTimer; break; - case "Clean": buildTimer = Counters.CleanMSBuildProjectTimer; break; + case "Build": buildTimer = Counters.BuildMSBuildProjectTimer; operationRequiresExclusiveLock = true; break; + case "Clean": buildTimer = Counters.CleanMSBuildProjectTimer; operationRequiresExclusiveLock = true; break; } var t1 = Counters.RunMSBuildTargetTimer.BeginTiming (GetProjectEventMetadata (configuration)); @@ -1169,7 +1170,11 @@ namespace MonoDevelop.Projects bool newBuilderRequested = false; RemoteProjectBuilder builder = await GetProjectBuilder ().ConfigureAwait (false); - if (builder.IsBusy) { + + // If the builder requires an exclusive lock and it is busy, create a new locked builder. + // Fast operations that don't require an exclusive lock can use any builder, either locked or not + + if (builder.IsBusy && operationRequiresExclusiveLock) { builder.ReleaseReference (); newBuilderRequested = true; builder = await RequestLockedBuilder ().ConfigureAwait (false); @@ -1339,8 +1344,8 @@ namespace MonoDevelop.Projects if (modifiedInMemory) { try { modifiedInMemory = false; - await WriteProjectAsync (new ProgressMonitor ()); - await projectBuilder.RefreshWithContent (sourceProject.SaveToString ()); + string content = await WriteProjectAsync (new ProgressMonitor ()); + await projectBuilder.RefreshWithContent (content); } catch { projectBuilder.ReleaseReference (); throw; @@ -1372,8 +1377,8 @@ namespace MonoDevelop.Projects pb.AddReference (); if (modifiedInMemory) { try { - await WriteProjectAsync (new ProgressMonitor ()); - await pb.RefreshWithContent (sourceProject.SaveToString ()); + string content = await WriteProjectAsync (new ProgressMonitor ()); + await pb.RefreshWithContent (content); } catch { pb.Dispose (); throw; @@ -2201,11 +2206,12 @@ namespace MonoDevelop.Projects AsyncCriticalSection writeProjectLock = new AsyncCriticalSection (); - internal async Task WriteProjectAsync (ProgressMonitor monitor) + internal async Task<string> WriteProjectAsync (ProgressMonitor monitor) { using (await writeProjectLock.EnterAsync ().ConfigureAwait (false)) { - await Task.Run (() => { + return await Task.Run (() => { WriteProject (monitor); + return sourceProject.SaveToString (); }).ConfigureAwait (false); } } @@ -3087,8 +3093,11 @@ namespace MonoDevelop.Projects if (UseAdvancedGlobSupport) { // Add remove items if necessary foreach (var removed in loadedProjectItems.Where (i => i.WildcardItem == globItem && !expandedList.Any (newItem => newItem.ProjectItem.Include == i.Include))) { - var removeItem = new MSBuildItem (removed.ItemName) { Remove = removed.Include }; - msproject.AddItem (removeItem); + var file = removed as ProjectFile; + if (file == null || File.Exists (file.FilePath)) { + var removeItem = new MSBuildItem (removed.ItemName) { Remove = removed.Include }; + msproject.AddItem (removeItem); + } unusedItems.UnionWith (FindUpdateItemsForItem (globItem, removed.Include)); } diff --git a/main/src/core/MonoDevelop.Ide/ExtensionModel/Templates.addin.xml b/main/src/core/MonoDevelop.Ide/ExtensionModel/Templates.addin.xml index c3e112602f..e936cf1dc5 100644 --- a/main/src/core/MonoDevelop.Ide/ExtensionModel/Templates.addin.xml +++ b/main/src/core/MonoDevelop.Ide/ExtensionModel/Templates.addin.xml @@ -21,6 +21,11 @@ <ExtensionNode name="ProjectTemplate" type="MonoDevelop.Ide.Codons.ProjectTemplateCodon"/> </ExtensionPoint> +<ExtensionPoint path = "/MonoDevelop/Ide/Templates" name = "Microsoft Templating Engine templates"> + <Description>Microsoft templating engine project templates to be shown in the New Project dialog.</Description> + <ExtensionNode name="Template" type="MonoDevelop.Ide.Codons.TemplateExtensionNode"/> +</ExtensionPoint> + <ExtensionPoint path = "/MonoDevelop/Ide/ProjectTemplatePackageInstallers" name = "Project template package installers"> <Description>Installs packages defined in the project template. Must implement MonoDevelop.Ide.Templates.ProjectTemplatePackageInstaller</Description> <ExtensionNode name="Class" /> @@ -121,6 +126,7 @@ <Extension path="/MonoDevelop/Ide/ProjectTemplatingProviders"> <Class id="MonoDevelop.ProjectTemplatingProvider" class="MonoDevelop.Ide.Templates.ProjectTemplatingProvider" /> + <Class id="MonoDevelop.MicrosoftTemplateEngineProjectTemplatingProvider" class="MonoDevelop.Ide.Templates.MicrosoftTemplateEngineProjectTemplatingProvider" /> </Extension> <Extension path="/MonoDevelop/Ide/TemplateImages"> diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarController.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarController.cs index a356ab36fe..5b1bc7cce5 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarController.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarController.cs @@ -472,7 +472,7 @@ namespace MonoDevelop.Components.MainToolbar } var target = item.ExecutionTarget; - if (target == null || !target.Enabled || item.Project != project) + if (target == null || item.Project != project) continue; if (target is ExecutionTargetGroup) @@ -977,6 +977,18 @@ namespace MonoDevelop.Components.MainToolbar public SolutionItem Project { get; } + public string Image { + get { + return ExecutionTarget?.Image; + } + } + + public string Tooltip { + get { + return ExecutionTarget?.Tooltip; + } + } + public IRuntimeMutableModel GetMutableModel () { if (Command != null) @@ -1006,7 +1018,7 @@ namespace MonoDevelop.Components.MainToolbar public RuntimeMutableModel (ExecutionTarget target, bool fullName) { - Enabled = !(target is ExecutionTargetGroup); + Enabled = !(target is ExecutionTargetGroup) && target.Enabled; Visible = true; if (target == null) DisplayString = FullDisplayString = string.Empty; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarModels.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarModels.cs index 280e33fdac..3330c0f5d0 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarModels.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarModels.cs @@ -84,6 +84,18 @@ namespace MonoDevelop.Components.MainToolbar bool Notable { get; } /// <summary> + /// Gets the menu item's image. + /// </summary> + /// <value>The image name.</value> + string Image { get; } + + /// <summary> + /// Gets the menu item's tooltip. + /// </summary> + /// <value>The tooltip text</value> + string Tooltip { get; } + + /// <summary> /// Gets the project to which this runtime belongs. /// </summary> /// <value>The project.</value> diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Codons/TemplateExtensionNode.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Codons/TemplateExtensionNode.cs new file mode 100644 index 0000000000..9fffc654b8 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Codons/TemplateExtensionNode.cs @@ -0,0 +1,89 @@ +// +// TemplateExtensionNode.cs +// +// Author: +// David Karlaš <david.karlas@xamarin.com> +// +// Copyright (c) 2017 Xamarin, Inc (http://www.xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using Mono.Addins; + +namespace MonoDevelop.Ide.Codons +{ + [ExtensionNode (Description = "Template informations.")] + internal class TemplateExtensionNode : ExtensionNode + { + [NodeAttribute ("category", "Category used to place template into correct category inside new project dialog.")] + string category; + + public string Category { + get { + return category; + } + } + + [NodeAttribute ("path", "Either .nupkg file or folder.")] + string path; + + public string ScanPath { + get { + return Addin.GetFilePath (path); + } + } + + + [NodeAttribute ("icon", "Icon to display in new project dialog.")] + string icon; + + public string Icon { + get { + return ImageService.GetStockId (Addin, icon, Gtk.IconSize.Dnd); + } + } + + + [NodeAttribute ("imageId", "ImageId of image showed in new project dialog description of project.")] + string imageId; + + public string ImageId { + get { + return imageId; + } + } + + [NodeAttribute ("_overrideName", "If template.json is outside AddIn creator control use this to change name.", Localizable = true)] + string overrideName; + public string OverrideName { + get { + return overrideName; + } + } + + + [NodeAttribute ("_overrideDescription", "If template.json is outside AddIn creator control use this to change description.", Localizable = true)] + string overrideDescription; + public string OverrideDescription { + get { + return overrideDescription; + } + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs index 9772c3f82f..6e1a9e79c1 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs @@ -131,6 +131,9 @@ namespace MonoDevelop.Ide.Editor.Extension deleteOrBackspaceTriggerChar = Editor.GetCharAt (Editor.CaretOffset - 1); res = base.KeyPress (descriptor); + if (Editor.EditMode == EditMode.TextLink && Editor.TextLinkPurpose == TextLinkPurpose.Rename) { + return res; + } if (descriptor.KeyChar == (char)16 || descriptor.KeyChar == (char)17) return res; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/TextPasteHandler.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/TextPasteHandler.cs index ee3518ecc0..c4f205af02 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/TextPasteHandler.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/TextPasteHandler.cs @@ -24,6 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; +using System.Threading.Tasks; using MonoDevelop.Core.Text; namespace MonoDevelop.Ide.Editor.Extension @@ -58,7 +59,7 @@ namespace MonoDevelop.Ide.Editor.Extension /// </summary> /// <param name="offset">The offset the text was pasted at.</param> /// <param name="length">The length of the text pasted.</param> - public abstract void PostFomatPastedText (int offset, int length); + public abstract Task PostFomatPastedText (int offset, int length); } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs index 70576c62b2..659d346406 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs @@ -162,7 +162,7 @@ namespace MonoDevelop.Ide.Editor.Highlighting this.state = state; } - static readonly TimeSpan matchTimeout = TimeSpan.FromMilliseconds (200); + static readonly TimeSpan matchTimeout = TimeSpan.FromMilliseconds (100); public Task<HighlightedLine> GetColoredSegments (ITextSource text, int offset, int length) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditor.cs index 107f942e1f..198126f346 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditor.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditor.cs @@ -555,12 +555,22 @@ namespace MonoDevelop.Ide.Editor textEditorImpl.StartInsertionMode (insertionModeOptions); } + TextLinkModeOptions textLinkModeOptions; public void StartTextLinkMode (TextLinkModeOptions textLinkModeOptions) { if (textLinkModeOptions == null) throw new ArgumentNullException (nameof (textLinkModeOptions)); Runtime.AssertMainThread (); textEditorImpl.StartTextLinkMode (textLinkModeOptions); + this.textLinkModeOptions = textLinkModeOptions; + } + + internal TextLinkPurpose TextLinkPurpose { + get { + if (EditMode != EditMode.TextLink || textLinkModeOptions == null) + return TextLinkPurpose.Unknown; + return textLinkModeOptions.TextLinkPurpose; + } } public void InsertAtCaret (string text) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextLinkModeOptions.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextLinkModeOptions.cs index ef20516cf9..5be3ff5e64 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextLinkModeOptions.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextLinkModeOptions.cs @@ -28,6 +28,12 @@ using System.Collections.Generic; namespace MonoDevelop.Ide.Editor { + public enum TextLinkPurpose + { + Unknown, + Rename + } + /// <summary> /// This class contains information the editor needs to initiate the text link mode. /// </summary> @@ -50,6 +56,8 @@ namespace MonoDevelop.Ide.Editor private set; } + public TextLinkPurpose TextLinkPurpose { get; set; } + /// <summary> /// Initializes a new instance of the <see cref="MonoDevelop.Ide.Editor.TextLinkModeOptions"/> class. /// </summary> diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/AssemblyRunConfigurationEditor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/AssemblyRunConfigurationEditor.cs index a32a808e05..2db97fc7eb 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/AssemblyRunConfigurationEditor.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/AssemblyRunConfigurationEditor.cs @@ -64,7 +64,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels } } - class DotNetRunConfigurationEditorWidget: Notebook + public class DotNetRunConfigurationEditorWidget: Notebook { RadioButton radioStartProject; RadioButton radioStartApp; @@ -80,6 +80,12 @@ namespace MonoDevelop.Ide.Projects.OptionPanels InformationPopoverWidget appEntryInfoIcon; public DotNetRunConfigurationEditorWidget () + : this (true) + { + + } + + public DotNetRunConfigurationEditorWidget (bool includeAdvancedTab) { VBox mainBox = new VBox (); @@ -140,7 +146,8 @@ namespace MonoDevelop.Ide.Projects.OptionPanels table.Add (box, 1, 1, hexpand: true); adBox.PackStart (table); - Add (adBox, GettextCatalog.GetString ("Advanced")); + if (includeAdvancedTab) + Add (adBox, GettextCatalog.GetString ("Advanced")); monoSettingsButton.Clicked += EditRuntimeClicked; radioStartProject.ActiveChanged += (sender, e) => UpdateStatus (); @@ -240,7 +247,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels envVars.StoreValues (config.EnvironmentVariables); } - void NotifyChanged () + protected void NotifyChanged () { Changed?.Invoke (this, EventArgs.Empty); } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/GtkNewProjectDialogBackend.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/GtkNewProjectDialogBackend.cs index b193b6d67c..1f1996aaad 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/GtkNewProjectDialogBackend.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/GtkNewProjectDialogBackend.cs @@ -193,6 +193,11 @@ namespace MonoDevelop.Ide.Projects void TemplatesTreeViewSelectionChanged (object sender, EventArgs e)
{
controller.SelectedTemplate = GetSelectedTemplate ();
+ if (templateTextRenderer.RenderRecentTemplate && controller.SelectedTemplate != null) {
+ // reset selected language if a recent template has been selected
+ templateTextRenderer.SelectedLanguage = controller.SelectedTemplate.Language;
+ controller.SelectedLanguage = controller.SelectedTemplate.Language;
+ }
ShowSelectedTemplate ();
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/GtkTemplateCellRenderer.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/GtkTemplateCellRenderer.cs index 9317cdf5ec..d70df2aba0 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/GtkTemplateCellRenderer.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/GtkTemplateCellRenderer.cs @@ -250,11 +250,12 @@ namespace MonoDevelop.Ide.Projects string GetSelectedLanguage ()
{
- if (!Template.AvailableLanguages.Any ()) {
+ if (!Template.AvailableLanguages.Any ())
return String.Empty;
- } else if (Template.AvailableLanguages.Contains (SelectedLanguage)) {
+ else if (RenderRecentTemplate)
+ return Template.Language;
+ else if (Template.AvailableLanguages.Contains (SelectedLanguage))
return SelectedLanguage;
- }
return Template.AvailableLanguages.First ();
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs index 41a7c7c4ea..c277db2a9b 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs @@ -573,7 +573,7 @@ namespace MonoDevelop.Ide.Projects if (wizardProvider.HasWizard)
wizardProvider.BeforeProjectIsCreated ();
- if (!CreateProject ())
+ if (!await CreateProject ())
return;
Solution parentSolution = null;
@@ -679,7 +679,7 @@ namespace MonoDevelop.Ide.Projects .ToList ();
}
- bool CreateProject ()
+ async Task<bool> CreateProject ()
{
if (!projectConfiguration.IsValid ()) {
MessageService.ShowError (projectConfiguration.GetErrorMessage ());
@@ -724,7 +724,7 @@ namespace MonoDevelop.Ide.Projects DisposeExistingNewItems ();
try {
- result = IdeApp.Services.TemplatingService.ProcessTemplate (template, projectConfiguration, ParentFolder);
+ result = await IdeApp.Services.TemplatingService.ProcessTemplate (template, projectConfiguration, ParentFolder);
if (!result.WorkspaceItems.Any ())
return false;
} catch (UserException ex) {
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/IProjectTemplatingProvider.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/IProjectTemplatingProvider.cs index 79c81bbb0c..52fae3978e 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/IProjectTemplatingProvider.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/IProjectTemplatingProvider.cs @@ -25,6 +25,7 @@ // THE SOFTWARE.
using System.Collections.Generic;
+using System.Threading.Tasks;
using MonoDevelop.Ide.Projects;
using MonoDevelop.Projects;
@@ -35,7 +36,7 @@ namespace MonoDevelop.Ide.Templates IEnumerable<SolutionTemplate> GetTemplates ();
bool CanProcessTemplate (SolutionTemplate template);
- ProcessedTemplateResult ProcessTemplate (SolutionTemplate template, NewProjectConfiguration config, SolutionFolder parentFolder);
+ Task<ProcessedTemplateResult> ProcessTemplate (SolutionTemplate template, NewProjectConfiguration config, SolutionFolder parentFolder);
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineProcessedTemplateResult.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineProcessedTemplateResult.cs new file mode 100644 index 0000000000..c977bcf200 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineProcessedTemplateResult.cs @@ -0,0 +1,67 @@ +// +// MicrosoftTemplateEngineProcessedTemplateResult.cs +// +// Author: +// David Karlaš <david.karlas@xamarin.com> +// +// Copyright (c) 2017 Xamarin, Inc (http://www.xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using System.Collections.Generic; +using Microsoft.TemplateEngine.Edge.Template; +using MonoDevelop.Projects; + +namespace MonoDevelop.Ide.Templates +{ + class MicrosoftTemplateEngineProcessedTemplateResult : ProcessedTemplateResult + { + readonly IWorkspaceFileObject[] workspaceItems; + + public MicrosoftTemplateEngineProcessedTemplateResult (IWorkspaceFileObject[] workspaceItems, string solutionFileName, string projectBasePath) + { + this.workspaceItems = workspaceItems; + this.SolutionFileName = solutionFileName; + this.ProjectBasePath = projectBasePath; + } + + public override IEnumerable<string> Actions { + get { + yield break; + } + } + + public override IList<PackageReferencesForCreatedProject> PackageReferences { + get { + throw new NotImplementedException (); + } + } + + public override IEnumerable<IWorkspaceFileObject> WorkspaceItems { + get { + return workspaceItems; + } + } + + public override bool HasPackages () + { + return false; + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineProjectTemplatingProvider.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineProjectTemplatingProvider.cs new file mode 100644 index 0000000000..2849a88599 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineProjectTemplatingProvider.cs @@ -0,0 +1,226 @@ +// +// MicrosoftTemplateEngineProjectTemplatingProvider.cs +// +// Author: +// David Karlaš <david.karlas@xamarin.com> +// +// Copyright (c) 2017 Xamarin, Inc (http://www.xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using System.Collections.Generic; +using Microsoft.TemplateEngine.Edge.Settings; +using Microsoft.TemplateEngine.Edge.Template; +using Microsoft.TemplateEngine.Utils; +using MonoDevelop.Ide.Projects; +using MonoDevelop.Projects; +using System.Linq; +using Microsoft.TemplateEngine.Orchestrator.RunnableProjects; +using MonoDevelop.Core; +using Microsoft.TemplateEngine.Edge; +using System.IO; +using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Config; +using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Macros; +using System.Threading.Tasks; +using Mono.Addins; +using MonoDevelop.Ide.Codons; +using Microsoft.TemplateEngine.Abstractions; + +namespace MonoDevelop.Ide.Templates +{ + class MicrosoftTemplateEngineProjectTemplatingProvider : IProjectTemplatingProvider + { + public bool CanProcessTemplate (SolutionTemplate template) + { + return template is MicrosoftTemplateEngineSolutionTemplate; + } + + static EngineEnvironmentSettings environmentSettings = new EngineEnvironmentSettings (new MyTemplateEngineHost (), (env) => new SettingsLoader (env)); + static TemplateCreator templateCreator = new TemplateCreator (environmentSettings); + + static bool dontUpdateCache = true; + + static MicrosoftTemplateEngineProjectTemplatingProvider () + { + AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Ide/Templates", OnExtensionChanged); + dontUpdateCache = false; + UpdateCache (); + } + + static List<TemplateExtensionNode> TemplatesNodes = new List<TemplateExtensionNode> (); + static List<MicrosoftTemplateEngineSolutionTemplate> templates = new List<MicrosoftTemplateEngineSolutionTemplate> (); + + static void UpdateCache () + { + if (dontUpdateCache)//Avoid updating cache while scan paths are added during registration + return; + var paths = new Paths (environmentSettings); + + //TODO: Uncomment this IF, but also add logic to invalidate/check if new templates were added from newly installed AddOns... + //if (!paths.Exists (paths.User.BaseDir) || !paths.Exists (paths.User.FirstRunCookie)) { + var _templateCache = new TemplateCache (environmentSettings); + foreach (var scanPath in TemplatesNodes.Select (t => t.ScanPath).Distinct ()) { + _templateCache.Scan (scanPath); + } + _templateCache.WriteTemplateCaches (); + paths.WriteAllText (paths.User.FirstRunCookie, ""); + //} + var templateInfos = templateCreator.List (false, (t, s) => new MatchInfo ()).ToDictionary (m => m.Info.Identity, m => m.Info); + var newTemplates = new List<MicrosoftTemplateEngineSolutionTemplate> (); + foreach (var template in TemplatesNodes) { + ITemplateInfo templateInfo; + if (!templateInfos.TryGetValue (template.Id, out templateInfo)) { + LoggingService.LogWarning ("Template {0} not found.", template.Id); + continue; + } + newTemplates.Add (new MicrosoftTemplateEngineSolutionTemplate (template, templateInfo)); + } + templates = newTemplates; + } + + static void OnExtensionChanged (object s, ExtensionNodeEventArgs args) + { + if (args.Change == ExtensionChange.Add) { + var codon = (TemplateExtensionNode)args.ExtensionNode; + try { + TemplatesNodes.Add (codon); + } catch (Exception e) { + string extId = null, addinId = null; + if (codon != null) { + if (codon.HasId) + extId = codon.Id; + if (codon.Addin != null) + addinId = codon.Addin.Id; + } + LoggingService.LogError ("Error loading template id {0} in addin {1}:\n{2}", + extId ?? "(null)", addinId ?? "(null)", e.ToString ()); + } + } else { + foreach (var pt in TemplatesNodes) { + var codon = (TemplateExtensionNode)args.ExtensionNode; + if (pt.Id == codon.Id) { + TemplatesNodes.Remove (pt); + break; + } + } + } + UpdateCache (); + } + + public IEnumerable<SolutionTemplate> GetTemplates () + { + return templates; + } + + static MonoDevelop.Core.Instrumentation.Counter TemplateCounter = MonoDevelop.Core.Instrumentation.InstrumentationService.CreateCounter ("Template Instantiated", "Project Model", id: "Core.Template.Instantiated"); + + public async Task<ProcessedTemplateResult> ProcessTemplate (SolutionTemplate template, NewProjectConfiguration config, SolutionFolder parentFolder) + { + var templateInfo = ((MicrosoftTemplateEngineSolutionTemplate)template).templateInfo; + var workspaceItems = new List<IWorkspaceFileObject> (); + var result = await templateCreator.InstantiateAsync ( + templateInfo, + config.ProjectName, + config.GetValidProjectName (), + config.ProjectLocation, + new Dictionary<string, string> (), + true, + false); + if (result.ResultInfo.PrimaryOutputs.Any ()) { + foreach (var res in result.ResultInfo.PrimaryOutputs) { + var fullPath = Path.Combine (config.ProjectLocation, res.Path); + //This happens if some project is excluded by modifiers, e.g. Test project disabled in wizard settings by user + if (!File.Exists (fullPath)) + continue; + workspaceItems.Add (await MonoDevelop.Projects.Services.ProjectService.ReadSolutionItem (new Core.ProgressMonitor (), fullPath)); + } + } else { + //TODO: Remove this code once https://github.com/dotnet/templating/pull/342 is released in NuGet feed and we bump NuGet version of templating engine + foreach (var path in Directory.GetFiles (config.ProjectLocation, "*.*proj", SearchOption.AllDirectories)) { + if (path.EndsWith (".csproj", StringComparison.OrdinalIgnoreCase) || path.EndsWith (".fsproj", StringComparison.OrdinalIgnoreCase) || path.EndsWith (".vbproj", StringComparison.OrdinalIgnoreCase)) + workspaceItems.Add (await MonoDevelop.Projects.Services.ProjectService.ReadSolutionItem (new Core.ProgressMonitor (), path)); + } + } + + var metadata = new Dictionary<string, string> (); + metadata ["Id"] = templateInfo.Identity; + metadata ["Name"] = templateInfo.Name; + metadata ["Language"] = template.Language; + metadata ["Platform"] = string.Join(";", templateInfo.Classifications); + TemplateCounter.Inc (1, null, metadata); + + if (parentFolder == null) { + var solution = new Solution (); + solution.SetLocation (config.SolutionLocation, config.SolutionName); + foreach (var item in workspaceItems.Cast<SolutionFolderItem> ()) { + IConfigurationTarget configurationTarget = item as IConfigurationTarget; + if (configurationTarget != null) { + foreach (ItemConfiguration configuration in configurationTarget.Configurations) { + bool flag = false; + foreach (SolutionConfiguration solutionCollection in solution.Configurations) { + if (solutionCollection.Id == configuration.Id) + flag = true; + } + if (!flag) + solution.AddConfiguration (configuration.Id, true); + } + } + solution.RootFolder.AddItem (item); + } + return new MicrosoftTemplateEngineProcessedTemplateResult (new [] { solution }, solution.FileName, config.ProjectLocation); + } else { + return new MicrosoftTemplateEngineProcessedTemplateResult (workspaceItems.ToArray (), parentFolder.ParentSolution.FileName, config.ProjectLocation); + } + } + + class MyTemplateEngineHost : DefaultTemplateEngineHost + { + public MyTemplateEngineHost () : base (BrandingService.ApplicationName, BuildInfo.CompatVersion, "en-US", new Dictionary<string, string> { { "dotnet-cli-version", "0" } }, new Dictionary<Guid, Func<Type>> + { + { new Guid("0C434DF7-E2CB-4DEE-B216-D7C58C8EB4B3"), () => typeof(RunnableProjectGenerator) }, + { new Guid("3147965A-08E5-4523-B869-02C8E9A8AAA1"), () => typeof(BalancedNestingConfig) }, + { new Guid("3E8BCBF0-D631-45BA-A12D-FBF1DE03AA38"), () => typeof(ConditionalConfig) }, + { new Guid("A1E27A4B-9608-47F1-B3B8-F70DF62DC521"), () => typeof(FlagsConfig) }, + { new Guid("3FAE1942-7257-4247-B44D-2DDE07CB4A4A"), () => typeof(IncludeConfig) }, + { new Guid("3D33B3BF-F40E-43EB-A14D-F40516F880CD"), () => typeof(RegionConfig) }, + { new Guid("62DB7F1F-A10E-46F0-953F-A28A03A81CD1"), () => typeof(ReplacementConfig) }, + { new Guid("370996FE-2943-4AED-B2F6-EC03F0B75B4A"), () => typeof(ConstantMacro) }, + { new Guid("BB625F71-6404-4550-98AF-B2E546F46C5F"), () => typeof(EvaluateMacro) }, + { new Guid("10919008-4E13-4FA8-825C-3B4DA855578E"), () => typeof(GuidMacro) }, + { new Guid("F2B423D7-3C23-4489-816A-41D8D2A98596"), () => typeof(NowMacro) }, + { new Guid("011E8DC1-8544-4360-9B40-65FD916049B7"), () => typeof(RandomMacro) }, + { new Guid("8A4D4937-E23F-426D-8398-3BDBD1873ADB"), () => typeof(RegexMacro) }, + { new Guid("B57D64E0-9B4F-4ABE-9366-711170FD5294"), () => typeof(SwitchMacro) }, + { new Guid("10919118-4E13-4FA9-825C-3B4DA855578E"), () => typeof(CaseChangeMacro) } + }.ToList ()) + { + } + + public override bool TryGetHostParamDefault (string paramName, out string value) + { + if (paramName == "HostIdentifier") { + value = this.HostIdentifier; + return true; + } + value = null; + return false; + } + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineSolutionTemplate.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineSolutionTemplate.cs new file mode 100644 index 0000000000..4b6f0ef87c --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineSolutionTemplate.cs @@ -0,0 +1,64 @@ +// +// MicrosoftTemplateEngineSolutionTemplate.cs +// +// Author: +// David Karlaš <david.karlas@xamarin.com> +// +// Copyright (c) 2017 Xamarin, Inc (http://www.xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using Microsoft.TemplateEngine.Abstractions; +using Microsoft.TemplateEngine.Edge.Settings; +using System.Linq; +using MonoDevelop.Ide.Codons; + +namespace MonoDevelop.Ide.Templates +{ + class MicrosoftTemplateEngineSolutionTemplate : SolutionTemplate + { + internal readonly ITemplateInfo templateInfo; + //TemplateExtensionNode template; + + internal MicrosoftTemplateEngineSolutionTemplate (TemplateExtensionNode template, ITemplateInfo templateInfo) + : base (templateInfo.Identity, template.OverrideName ?? templateInfo.Name, template.Icon) + { + this.templateInfo = templateInfo; + Description = template.OverrideDescription ?? templateInfo.Description; + Category = template.Category; + string language; + if (templateInfo.Tags.TryGetValue ("Language", out language)) + Language = language; + else + Language = string.Empty; + GroupId = templateInfo.GroupIdentity; + //TODO: Support all this params + //Condition = template.Condition; + //ProjectFileExtension = template.FileExtension; + //Wizard = template.WizardPath; + //SupportedParameters = template.SupportedParameters; + //DefaultParameters = template.DefaultParameters; + ImageId = template.ImageId; + //ImageFile = template.ImageFile; + //Visibility = GetVisibility (template.Visibility); + + //HasProjects = (template.SolutionDescriptor.EntryDescriptors.Length > 0); + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/ProjectTemplatingProvider.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/ProjectTemplatingProvider.cs index b47ae8a685..0b917b754f 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/ProjectTemplatingProvider.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/ProjectTemplatingProvider.cs @@ -32,6 +32,7 @@ using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
using MonoDevelop.Ide.Projects;
using MonoDevelop.Projects;
using MonoDevelop.Core;
@@ -52,9 +53,9 @@ namespace MonoDevelop.Ide.Templates return template is DefaultSolutionTemplate;
}
- public ProcessedTemplateResult ProcessTemplate (SolutionTemplate template, NewProjectConfiguration config, SolutionFolder parentFolder)
+ public Task<ProcessedTemplateResult> ProcessTemplate (SolutionTemplate template, NewProjectConfiguration config, SolutionFolder parentFolder)
{
- return ProcessTemplate ((DefaultSolutionTemplate)template, config, parentFolder);
+ return Task.FromResult (ProcessTemplate ((DefaultSolutionTemplate)template, config, parentFolder));
}
ProcessedTemplateResult ProcessTemplate (DefaultSolutionTemplate template, NewProjectConfiguration config, SolutionFolder parentFolder)
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplatingService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplatingService.cs index 575ca442db..c08f0975f7 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplatingService.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplatingService.cs @@ -27,6 +27,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
using Mono.Addins;
using MonoDevelop.Components;
using MonoDevelop.Core;
@@ -137,11 +138,11 @@ namespace MonoDevelop.Ide.Templates return null;
}
- public ProcessedTemplateResult ProcessTemplate (SolutionTemplate template, NewProjectConfiguration config, SolutionFolder parentFolder)
+ public async Task<ProcessedTemplateResult> ProcessTemplate (SolutionTemplate template, NewProjectConfiguration config, SolutionFolder parentFolder)
{
IProjectTemplatingProvider provider = GetTemplatingProviderForTemplate (template);
if (provider != null) {
- var result = provider.ProcessTemplate (template, config, parentFolder);
+ var result = await provider.ProcessTemplate (template, config, parentFolder);
if (result.WorkspaceItems.Any ())
RecentTemplates.AddTemplate (template);
return result;
@@ -241,12 +242,20 @@ namespace MonoDevelop.Ide.Templates var templatePath = item.Uri.StartsWith (templateUriScheme, StringComparison.Ordinal) ? item.Uri.Substring (templateUriScheme.Length) : item.Uri;
var parts = templatePath.Split ('/');
var templateId = parts [parts.Length - 1];
- if (parts.Length > 2) {
- return IdeApp.Services.TemplatingService.GetTemplate ((template) => template.Id == templateId,
- (category) => category.Id == parts[0],
- (category) => category.Id == parts[1]);
- } else
- return IdeApp.Services.TemplatingService.GetTemplate (templateId);
+ SolutionTemplate recentTemplate = null;
+
+ if (parts.Length > 1)
+ recentTemplate = IdeApp.Services.TemplatingService.GetTemplate (
+ (template) => template.Id == templateId,
+ (category) => parts.Length > 1 ? category.Id == parts[0] : true,
+ (category) => parts.Length > 2 ? category.Id == parts[1] : true
+ );
+
+ // fallback to global template lookup if no category matched
+ // in this case the category is not guaranteed if a template is listed in more than one category
+ if (recentTemplate == null)
+ recentTemplate = IdeApp.Services.TemplatingService.GetTemplate (templateId);
+ return recentTemplate;
}
public void Dispose ()
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj index 9c31b83492..2d00524635 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj @@ -145,10 +145,6 @@ <HintPath>..\..\..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath> <Private>False</Private> </Reference> - <Reference Include="Newtonsoft.Json"> - <HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> - <Private>False</Private> - </Reference> <Reference Include="System.Collections.Immutable"> <HintPath>..\..\..\build\bin\System.Collections.Immutable.dll</HintPath> </Reference> @@ -175,8 +171,27 @@ <Reference Include="YamlDotNet"> <HintPath>..\..\..\packages\YamlDotNet.Signed.4.0.1-pre291\lib\net35\YamlDotNet.dll</HintPath> </Reference> - <Reference Include="Microsoft.CodeAnalysis.Features"> - <HintPath>..\..\..\build\bin\Microsoft.CodeAnalysis.Features.dll</HintPath> + <Reference Include="System.IO.Compression" /> + <Reference Include="Microsoft.TemplateEngine.Abstractions"> + <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Abstractions.1.0.0-beta1-20170223-126\lib\net45\Microsoft.TemplateEngine.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.TemplateEngine.Core.Contracts"> + <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Core.Contracts.1.0.0-beta1-20170223-126\lib\net45\Microsoft.TemplateEngine.Core.Contracts.dll</HintPath> + </Reference> + <Reference Include="Microsoft.TemplateEngine.Utils"> + <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Utils.1.0.0-beta1-20170223-126\lib\net45\Microsoft.TemplateEngine.Utils.dll</HintPath> + </Reference> + <Reference Include="Microsoft.TemplateEngine.Core"> + <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Core.1.0.0-beta1-20170223-126\lib\net45\Microsoft.TemplateEngine.Core.dll</HintPath> + </Reference> + <Reference Include="Microsoft.TemplateEngine.Orchestrator.RunnableProjects"> + <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Orchestrator.RunnableProjects.1.0.0-beta1-20170223-126\lib\net45\Microsoft.TemplateEngine.Orchestrator.RunnableProjects.dll</HintPath> + </Reference> + <Reference Include="Microsoft.TemplateEngine.Edge"> + <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Edge.1.0.0-beta1-20170223-126\lib\net45\Microsoft.TemplateEngine.Edge.dll</HintPath> + </Reference> + <Reference Include="Newtonsoft.Json"> + <HintPath>..\..\..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <Private>False</Private> </Reference> </ItemGroup> @@ -9228,6 +9243,10 @@ <Compile Include="MonoDevelop.Ide.TypeSystem\EditorNotificationServiceFactory.cs" /> <Compile Include="MonoDevelop.Ide.TypeSystem\GlobalOptionPersister.cs" /> <Compile Include="MonoDevelop.Ide.TypeSystem\TextPolicyDocumentOptionsProvider.cs" /> + <Compile Include="MonoDevelop.Ide.Templates\MicrosoftTemplateEngineProjectTemplatingProvider.cs" /> + <Compile Include="MonoDevelop.Ide.Templates\MicrosoftTemplateEngineSolutionTemplate.cs" /> + <Compile Include="MonoDevelop.Ide.Templates\MicrosoftTemplateEngineProcessedTemplateResult.cs" /> + <Compile Include="MonoDevelop.Ide.Codons\TemplateExtensionNode.cs" /> </ItemGroup> <ItemGroup> <None Include="Makefile.am" /> diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeStartup.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeStartup.cs index 404b3fa13b..1adfa34bc5 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeStartup.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdeStartup.cs @@ -96,7 +96,12 @@ namespace MonoDevelop.Ide SetupExceptionManager (); IdeApp.Customizer = options.IdeCustomizer ?? new IdeCustomizer (); - IdeApp.Customizer.Initialize (); + try { + IdeApp.Customizer.Initialize (); + } catch (UnauthorizedAccessException ua) { + LoggingService.LogError ("Unauthorized access: " + ua.Message); + return 1; + } try { GLibLogging.Enabled = true; diff --git a/main/src/core/MonoDevelop.Ide/packages.config b/main/src/core/MonoDevelop.Ide/packages.config index 8727eecaa8..7396c9edcb 100644 --- a/main/src/core/MonoDevelop.Ide/packages.config +++ b/main/src/core/MonoDevelop.Ide/packages.config @@ -1,6 +1,13 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" /> + <package id="Microsoft.TemplateEngine.Abstractions" version="1.0.0-beta1-20170223-126" targetFramework="net45" /> + <package id="Microsoft.TemplateEngine.Core" version="1.0.0-beta1-20170223-126" targetFramework="net45" /> + <package id="Microsoft.TemplateEngine.Core.Contracts" version="1.0.0-beta1-20170223-126" targetFramework="net45" /> + <package id="Microsoft.TemplateEngine.Edge" version="1.0.0-beta1-20170223-126" targetFramework="net45" /> + <package id="Microsoft.TemplateEngine.Orchestrator.RunnableProjects" version="1.0.0-beta1-20170223-126" targetFramework="net45" /> + <package id="Microsoft.TemplateEngine.Utils" version="1.0.0-beta1-20170223-126" targetFramework="net45" /> + <package id="Newtonsoft.Json" version="8.0.3" targetFramework="net45" /> <package id="SharpZipLib" version="0.86.0" targetFramework="net45" /> + <package id="System.IO.Compression" version="4.3.0" targetFramework="net45" /> <package id="YamlDotNet.Signed" version="4.0.1-pre291" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.v4.0.cs b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.v4.0.cs index 90401a3000..1de1c94e7c 100644 --- a/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.v4.0.cs +++ b/main/src/core/MonoDevelop.Projects.Formats.MSBuild/MonoDevelop.Projects.Formats.MSBuild/ProjectBuilder.v4.0.cs @@ -142,6 +142,11 @@ namespace MonoDevelop.Projects.MSBuild {
var p = engine.GetLoadedProjects (file).FirstOrDefault ();
if (p == null) {
+ + // HACK: workaround to MSBuild bug #53019. We need to ensure that $(BaseIntermediateOutputPath) exists before + // loading the project. + Directory.CreateDirectory (Path.Combine (Path.GetDirectoryName (file), "obj"));
+
var content = buildEngine.GetUnsavedProjectContent (file);
if (content == null)
p = engine.LoadProject (file);
diff --git a/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/ClipboardTests.cs b/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/ClipboardTests.cs index e97085202c..83091a2d1a 100644 --- a/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/ClipboardTests.cs +++ b/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/ClipboardTests.cs @@ -30,6 +30,7 @@ using Gtk; using MonoDevelop.Core.Text; using MonoDevelop.Ide.Editor; using MonoDevelop.Ide.Editor.Extension; +using System.Threading.Tasks; namespace Mono.TextEditor.Tests { @@ -49,8 +50,9 @@ namespace Mono.TextEditor.Tests return null; } - public override void PostFomatPastedText (int offset, int length) + public override Task PostFomatPastedText (int offset, int length) { + return Task.FromResult (true); } } |