diff options
author | Matt Ward <matt.ward@xamarin.com> | 2017-07-25 18:59:45 +0300 |
---|---|---|
committer | Matt Ward <matt.ward@xamarin.com> | 2017-07-25 18:59:45 +0300 |
commit | 202808927267a66dc29375f7f5a05870a587b4ea (patch) | |
tree | 9e4d53a0cd6c703a4b1fdf1c21abe98507a4f9b3 /main | |
parent | 916957afd71fb68b2dffdfc043e9a4fdfbc9fd36 (diff) | |
parent | 45e6ac29cf6e32967709cd8959afe36567ad8777 (diff) |
Merge branch 'master' into nuget-support-asset-target-fallback
Diffstat (limited to 'main')
190 files changed, 4076 insertions, 1848 deletions
diff --git a/main/build/MacOSX/Makefile.am b/main/build/MacOSX/Makefile.am index 00318c4334..41a43cbd25 100644 --- a/main/build/MacOSX/Makefile.am +++ b/main/build/MacOSX/Makefile.am @@ -31,7 +31,7 @@ render.exe: render.cs dmg: render.exe app ./make-dmg-bundle.sh -monostub: monostub.mm $(MONOSTUB_EXTRA_SOURCES) +monostub: monostub.mm $(MONOSTUB_EXTRA_SOURCES) $(MONOSTUB_STATIC_LINK) clang++ $(EXTERN_C_XM_REGISTRAR_DEFINE) $(MONOSTUB_DEFINES) -Wall -mmacosx-version-min=10.10 -m$(MONOSTUB_ARCH) -o $@ monostub.mm -framework AppKit -framework Quartz $(MONOSTUB_STATIC_LINK) -undefined dynamic_lookup # gcc -Wall -mmacosx-version-min=10.10 -m$(MONOSTUB_ARCH) -o $@ monostub.m -framework AppKit -isysroot $(SDK_PATH) cp monostub ../bin/MonoDevelop diff --git a/main/external/debugger-libs b/main/external/debugger-libs -Subproject fa8e6a9e7ec4784c4883d36233fe42200270b08 +Subproject c6707cddf1fbe6607ce725e9fe403282796985c diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Gui/MonoDevelop.FSharp.Gui.csproj b/main/external/fsharpbinding/MonoDevelop.FSharp.Gui/MonoDevelop.FSharp.Gui.csproj index 15bcd53295..561c50ad79 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Gui/MonoDevelop.FSharp.Gui.csproj +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Gui/MonoDevelop.FSharp.Gui.csproj @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> + <Import Project="..\..\..\MonoDevelop.props" /> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> @@ -11,6 +12,8 @@ <RootNamespace>MonoDevelop.FSharp.Gui</RootNamespace> <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> <TargetFrameworkProfile /> + <SignAssembly>true</SignAssembly> + <AssemblyOriginatorKeyFile>..\..\..\msbuild\MonoDevelop-Public.snk</AssemblyOriginatorKeyFile> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>True</DebugSymbols> diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/Completions.fs b/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/Completions.fs index 9edce0b26c..3f8ed87c80 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/Completions.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/Completions.fs @@ -47,28 +47,28 @@ module Completion = let symbolToIcon (symbolUse:FSharpSymbolUse) = match symbolUse with - | ActivePatternCase _ -> "ActivePatternCase" - | Field _ -> "Field" - | UnionCase _ -> "UnionCase" - | Class _ -> "Class" - | Delegate _ -> "Delegate" - | Constructor _ -> "Constructor" - | Event _ -> "Event" - | Property _ -> "Property" - | Function f -> + | SymbolUse.ActivePatternCase _ -> "ActivePatternCase" + | SymbolUse.Field _ -> "Field" + | SymbolUse.UnionCase _ -> "UnionCase" + | SymbolUse.Class _ -> "Class" + | SymbolUse.Delegate _ -> "Delegate" + | SymbolUse.Constructor _ -> "Constructor" + | SymbolUse.Event _ -> "Event" + | SymbolUse.Property _ -> "Property" + | SymbolUse.Function f -> if f.IsExtensionMember then "ExtensionMethod" elif f.IsMember then "Method" else "Field" - | Operator _ -> "Operator" - | ClosureOrNestedFunction _ -> "ClosureOrNestedFunction" - | Val _ -> "Val" - | Enum _ -> "Enum" - | Interface _ -> "Interface" - | Module _ -> "Module" - | Namespace _ -> "Namespace" - | Record _ -> "Record" - | Union _ -> "Union" - | ValueType _ -> "ValueType" + | SymbolUse.Operator _ -> "Operator" + | SymbolUse.ClosureOrNestedFunction _ -> "ClosureOrNestedFunction" + | SymbolUse.Val _ -> "Val" + | SymbolUse.Enum _ -> "Enum" + | SymbolUse.Interface _ -> "Interface" + | SymbolUse.Module _ -> "Module" + | SymbolUse.Namespace _ -> "Namespace" + | SymbolUse.Record _ -> "Record" + | SymbolUse.Union _ -> "Union" + | SymbolUse.ValueType _ -> "ValueType" | SymbolUse.Entity _ -> "Entity" | _ -> "Event" @@ -204,4 +204,4 @@ module Completion = |> List.map ParameterHinting.getTooltipInformation | _ -> return [] | _ -> return [] - }
\ No newline at end of file + } diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/Lexer.fs b/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/Lexer.fs index 9e42d8e719..6b9478609c 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/Lexer.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/Lexer.fs @@ -26,7 +26,7 @@ type SymbolLookupKind = | ByLongIdent | Simple -type internal DraftToken = +type DraftToken = { Kind: SymbolKind Token: FSharpTokenInfo RightColumn: int } @@ -69,7 +69,6 @@ module Lexer = // OPTIMIZE: if the new document has the current document as a prefix, // we can reuse lexing results and process only the added part. | _ -> - printfn "queryLexState: lexing current document" let lexStates = getLexStates defines source currentDocumentState := Some (lexStates, source, defines) lexStates @@ -119,7 +118,7 @@ module Lexer = // Statically resolved type parameters: we convert INFIX_AT_HAT_OP + IDENT tokens into single IDENT token, altering its LeftColumn // and FullMathedLength (for "^type" which is tokenized as (INFIX_AT_HAT_OP, left=2) + (IDENT, left=3, length=4) // we'll get (IDENT, left=2, length=5). - let internal fixTokens lineStr (tokens : FSharpTokenInfo list) = + let fixTokens lineStr (tokens : FSharpTokenInfo list) = tokens |> List.fold (fun (acc, lastToken) token -> match lastToken with @@ -165,7 +164,7 @@ module Lexer = yield tok yield! parseLine() | None, nstate -> state <- nstate ] - yield parseLine(), state ] + yield parseLine(), lineText ] let findTokenAt col (tokens:FSharpTokenInfo list) = let isTokenAtOffset col (t:FSharpTokenInfo) = col-1 >= t.LeftColumn && col-1 <= t.RightColumn @@ -195,18 +194,22 @@ module Lexer = // Try to find start column of the long identifiers // Assume that tokens are ordered in an decreasing order of start columns let rec tryFindStartColumn tokens = - match tokens with - | {Kind = Ident; Token = t1} :: {Kind = Operator; Token = t2} :: remainingTokens -> + match tokens with + | {Kind = SymbolKind.Other; Token = t1 } :: _ when t1.CharClass = FSharpTokenCharKind.Operator -> + Some t1.LeftColumn + | {Kind = SymbolKind.Other; Token = t1 } :: remainingTokens when t1.Tag = FSharpTokenTag.DOT -> + tryFindStartColumn remainingTokens + | {Kind = Ident; Token = t1} :: {Kind = SymbolKind.Other; Token = t2} :: remainingTokens -> if t2.Tag = FSharpTokenTag.DOT then tryFindStartColumn remainingTokens else Some t1.LeftColumn - | {Kind = Ident; Token = t} :: _ -> - Some t.LeftColumn - | {Kind = SymbolKind.Other; Token = t} :: _ when t.TokenName = "HASH" -> - Some t.LeftColumn - | _ :: _ | [] -> - None + | {Kind = Ident; Token = t} :: _ -> + Some t.LeftColumn + | {Kind = SymbolKind.Other; Token = t} :: _ when t.TokenName = "HASH" -> + Some t.LeftColumn + | _ :: _ | [] -> + None let decreasingTokens = match tokensUnderCursor |> List.sortBy (fun token -> - token.Token.LeftColumn) with // Skip the first dot if it is the start of the identifier diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/MonoDevelop.FSharp.Shared.fsproj b/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/MonoDevelop.FSharp.Shared.fsproj index 425b011be6..c3d1a9a7e0 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/MonoDevelop.FSharp.Shared.fsproj +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/MonoDevelop.FSharp.Shared.fsproj @@ -86,11 +86,6 @@ <Private>True</Private> <Paket>True</Paket> </Reference> - <Reference Include="FSharp.Compiler.Service.MSBuild.v12"> - <HintPath>..\packages\FSharp.Compiler.Service\lib\net45\FSharp.Compiler.Service.MSBuild.v12.dll</HintPath> - <Private>True</Private> - <Paket>True</Paket> - </Reference> </ItemGroup> </When> </Choose> diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/Parser.fs b/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/Parser.fs index 8524db3775..0bb2511e57 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/Parser.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Shared/Parser.fs @@ -26,7 +26,7 @@ module Parsing = match sym.Text with | "" -> [], "" | text -> - let res = text.Split '.' |> List.ofArray |> List.rev + let res = text.Split '.' |> List.ofArray |> List.filter (String.isEmpty >> not) |> List.rev if lineStr.[col - 1] = '.' then res |> List.rev, "" else match res with diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/FSharpUnitTestTextEditorExtensionTests.fs b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/FSharpUnitTestTextEditorExtensionTests.fs index 5711e64262..2238f46619 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/FSharpUnitTestTextEditorExtensionTests.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/FSharpUnitTestTextEditorExtensionTests.fs @@ -64,7 +64,7 @@ type Test() = t1.UnitTestIdentifier |> should equal "NUnit.Framework.Test.TestOne" t1.IsIgnored |> should equal false - t2.UnitTestIdentifier |> should equal "NUnit.Framework.Test.``Test Two``" + t2.UnitTestIdentifier |> should equal "NUnit.Framework.Test.Test Two" t2.IsIgnored |> should equal true | _ -> NUnit.Framework.Assert.Fail "invalid number of tests returned" @@ -121,7 +121,7 @@ module Test = t1.UnitTestIdentifier |> should equal "NUnit.Framework.Test+Test.TestOne" t1.IsIgnored |> should equal false - t2.UnitTestIdentifier |> should equal "NUnit.Framework.Test+Test.``Test Two``" + t2.UnitTestIdentifier |> should equal "NUnit.Framework.Test+Test.Test Two" t2.IsIgnored |> should equal true | _ -> NUnit.Framework.Assert.Fail "invalid number of tests returned" diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/HighlightUsagesTests.fs b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/HighlightUsagesTests.fs index 5eefabadf6..3425fe8e03 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/HighlightUsagesTests.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/HighlightUsagesTests.fs @@ -1,8 +1,8 @@ namespace MonoDevelopTests open NUnit.Framework open FsUnit -open MonoDevelop.FSharp open MonoDevelop.FSharp.MonoDevelop +open MonoDevelop.FSharp.Shared [<TestFixture>] type HighlightUsagesTests() = @@ -11,7 +11,6 @@ type HighlightUsagesTests() = let source = source.Replace("|", "") let doc = TestHelpers.createDoc source "" let line, col, lineStr = doc.Editor.GetLineInfoFromOffset offset - //doc.Ast match Parsing.findIdents col lineStr SymbolLookupKind.ByLongIdent with | None -> Assert.Fail "Could not find ident" diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/IndentationTrackerTests.fs b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/IndentationTrackerTests.fs index be5d42507e..fa1271e973 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/IndentationTrackerTests.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/IndentationTrackerTests.fs @@ -24,7 +24,7 @@ type IndentationTrackerTests() = let insertEnterAtSection (text:string) = let idx = text.IndexOf ('§') - let doc = TextDocument(text.Replace("§", "")) + let doc = new TextDocument(text.Replace("§", "")) use data = new TextEditorData (doc) data.Caret.Offset <- idx MiscActions.InsertNewLine(data) diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/MonoDevelop.FSharp.Tests.fsproj b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/MonoDevelop.FSharp.Tests.fsproj index 13b40d718d..31775a96dd 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/MonoDevelop.FSharp.Tests.fsproj +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/MonoDevelop.FSharp.Tests.fsproj @@ -263,11 +263,6 @@ <Private>True</Private> <Paket>True</Paket> </Reference> - <Reference Include="FSharp.Compiler.Service.MSBuild.v12"> - <HintPath>..\packages\FSharp.Compiler.Service\lib\net45\FSharp.Compiler.Service.MSBuild.v12.dll</HintPath> - <Private>True</Private> - <Paket>True</Paket> - </Reference> </ItemGroup> </When> </Choose> @@ -285,11 +280,6 @@ <Choose> <When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.6.1'"> <ItemGroup> - <Reference Include="Mono.Cecil"> - <HintPath>..\packages\Mono.Cecil\lib\net45\Mono.Cecil.dll</HintPath> - <Private>True</Private> - <Paket>True</Paket> - </Reference> <Reference Include="Mono.Cecil.Mdb"> <HintPath>..\packages\Mono.Cecil\lib\net45\Mono.Cecil.Mdb.dll</HintPath> <Private>True</Private> @@ -305,6 +295,11 @@ <Private>True</Private> <Paket>True</Paket> </Reference> + <Reference Include="Mono.Cecil"> + <HintPath>..\packages\Mono.Cecil\lib\net45\Mono.Cecil.dll</HintPath> + <Private>True</Private> + <Paket>True</Paket> + </Reference> </ItemGroup> </When> </Choose> diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/ParsingTests.fs b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/ParsingTests.fs index 8855bae8d5..5bb959cd5c 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/ParsingTests.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/ParsingTests.fs @@ -1,9 +1,7 @@ namespace MonoDevelopTests open NUnit.Framework open FsUnit -open MonoDevelop.FSharp -open ExtCore - +open MonoDevelop.FSharp.Shared [<TestFixture>] type ParsingTests() = diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/ProjectCracking.fs b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/ProjectCracking.fs index fc9a389ff5..1f11d73bc9 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/ProjectCracking.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/ProjectCracking.fs @@ -23,7 +23,8 @@ module ``Project Cracking`` = let! w = Services.ProjectService.ReadWorkspaceItem (monitor, FilePath(sln)) |> Async.AwaitTask let s = w :?> Solution - let fsproj = s.Items.[0] :?> DotNetProject + let fsproj = s.Items.[0] :?> FSharpProject + do! fsproj.GetReferences() let opts = languageService.GetProjectOptionsFromProjectFile fsproj return opts.Value.OtherOptions } diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/SyntaxHighlighting.fs b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/SyntaxHighlighting.fs index da1d6d24de..1a905c18e0 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/SyntaxHighlighting.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/SyntaxHighlighting.fs @@ -23,7 +23,7 @@ type SyntaxHighlighting() = use reader = new StreamReader(stream) let highlighting = Sublime3Format.ReadHighlighting(reader) highlighting.PrepareMatches() - editor.SyntaxHighlighting <- MonoDevelop.Ide.Editor.Highlighting.SyntaxHighlighting(highlighting, editor) + editor.SyntaxHighlighting <- new MonoDevelop.Ide.Editor.Highlighting.SyntaxHighlighting(highlighting, editor) editor let assertStyle (input:string, expectedStyle:string) = diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/TestHelpers.fs b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/TestHelpers.fs index 1a61b7e7a3..b6030dc0bc 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/TestHelpers.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/TestHelpers.fs @@ -29,7 +29,7 @@ module TestHelpers = async { try let checker = FSharpChecker.Create() - let! projOptions = checker.GetProjectOptionsFromScript(filename, source) + let! projOptions, _errors = checker.GetProjectOptionsFromScript(filename, source) let! parseResults, checkAnswer = checker.ParseAndCheckFileInProject(filename, 0, source , projOptions) // Construct new typed parse result if the task succeeded diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/TestTooltipProvider.fs b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/TestTooltipProvider.fs index 51c5253afc..4e620102de 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/TestTooltipProvider.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/TestTooltipProvider.fs @@ -4,7 +4,6 @@ open NUnit.Framework open FsUnit open MonoDevelop.FSharp.MonoDevelop open MonoDevelop.FSharp - [<TestFixture>] type TestTooltipProvider() = let stripHtml html = @@ -55,6 +54,13 @@ type TestTooltipProvider() = segment.EndOffset |> should equal 11 [<Test>] + member this.``Type annotation has correct segment``() = + let line, col, symbolUse, editor = getSymbol "let map (f : 'a$ -> 'b) = ()" + let segment = Symbols.getTextSegment editor symbolUse.Value col line + segment.Offset |> should equal 14 + segment.EndOffset |> should equal 15 + + [<Test>] member this.``Base method has correct segment``() = let source = """ diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpBinding.addin.xml b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpBinding.addin.xml index 1ef3aa9dfe..ec277d8ac2 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpBinding.addin.xml +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpBinding.addin.xml @@ -105,6 +105,11 @@ </Condition> </Extension> + <Extension path = "/MonoDevelop/ProjectModel/Gui/ItemOptionPanels/Build/General"> + <Condition id="ProjectTypeId" value="F#"> + <Panel id = "FSharpCompilerOptionsPanel" _label = "F#" class = "MonoDevelop.FSharp.FSharpProjectCompilerOptionsPanel"/> + </Condition> + </Extension> <Extension path="/MonoDevelop/Core/MimeTypes"> <MimeType id="text/x-fsharp" _description="F# Source File" icon="md-file-source" isText="true"> <File pattern="*.fs" /> diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpInteractivePad.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpInteractivePad.fs index 1e08ebea11..12ace3fd8a 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpInteractivePad.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpInteractivePad.fs @@ -189,6 +189,7 @@ type FSharpInteractivePad() = let setPrompt() = editor.InsertAtCaret ("\n") + editor.ScrollTo editor.CaretLocation addMarker promptIcon let fsiOutput t = diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpPathExtension.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpPathExtension.fs index d090476f1d..bdb4cfc4b7 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpPathExtension.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpPathExtension.fs @@ -50,13 +50,18 @@ type FSharpPathExtension() as x = |> Option.bind (Option.condition ownerProjects.Contains) |> Option.iter x.DocumentContext.AttachToProject) + let getSolutions() = + ownerProjects |> Seq.choose (fun p -> p.ParentSolution |> Option.ofNull) |> Seq.distinct + let untrackStartupProjectChanges () = - for sol in (ownerProjects |> Seq.map (fun p -> p.ParentSolution) |> Seq.distinct) do - sol.StartupItemChanged.RemoveHandler handleStartupProjectChanged + getSolutions() + |> Seq.choose (fun s -> s.StartupItemChanged |> Option.ofNull) + |> Seq.iter (fun e -> e.RemoveHandler handleStartupProjectChanged) let trackStartupProjectChanges() = - for sol in (ownerProjects |> Seq.map (fun p -> p.ParentSolution) |> Seq.distinct) do - sol.StartupItemChanged.AddHandler handleStartupProjectChanged + getSolutions() + |> Seq.choose (fun s -> s.StartupItemChanged |> Option.ofNull) + |> Seq.iter (fun e -> e.AddHandler handleStartupProjectChanged) let setOwnerProjects (projects) = untrackStartupProjectChanges () diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpProjectCompilerOptions.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpProjectCompilerOptions.fs new file mode 100644 index 0000000000..27d5c98f0a --- /dev/null +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpProjectCompilerOptions.fs @@ -0,0 +1,50 @@ +namespace MonoDevelop.FSharp + +open Gtk + +open MonoDevelop.Components +open MonoDevelop.Components.AtkCocoaHelper +open MonoDevelop.Core +open MonoDevelop.Ide.Gui.Dialogs +open MonoDevelop.Ide.Gui.OptionPanels +open MonoDevelop.Projects + +type FSharpProjectCompilerOptions(project:DotNetProject) as this = + inherit Gtk.Bin() + + let boxChild (control:obj) = + let child = (downcast control : Box.BoxChild) + child.Expand <- false + child.Fill <- false + + let combo = new DotNetCompileTargetSelector(CompileTarget = project.CompileTarget) + + do + Stetic.BinContainer.Attach (this) |> ignore + let label = new Label(GettextCatalog.GetString "Compile target:") + let hbox = new HBox(Spacing = 6) + hbox.Add label + hbox.Add combo + boxChild hbox.[label] + boxChild hbox.[combo] + this.Add hbox + this.ShowAll() + + combo.SetCommonAccessibilityAttributes ("CodeGeneration.CompileTarget", label, + GettextCatalog.GetString ("Select the compile target for the code generation")); + member this.CompileTarget = combo.CompileTarget + +type FSharpProjectCompilerOptionsPanel() = + inherit ItemOptionsPanel() + + let mutable widget:FSharpProjectCompilerOptions option = None + + override this.CreatePanelWidget() = + let options = new FSharpProjectCompilerOptions(this.ConfiguredProject :?> _) + widget <- Some options + Control.op_Implicit options + + override this.ApplyChanges() = + widget |> Option.iter(fun widget' -> + let project = this.ConfiguredProject :?> DotNetProject + project.CompileTarget <- widget'.CompileTarget) diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpSymbolHelper.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpSymbolHelper.fs index 62c02ee115..6fa8d5ed43 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpSymbolHelper.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpSymbolHelper.fs @@ -194,7 +194,10 @@ module SymbolUse = | _ -> None let inline private notCtorOrProp (symbol:FSharpMemberOrFunctionOrValue) = - not symbol.IsConstructor && not symbol.IsPropertyGetterMethod && not symbol.IsPropertySetterMethod + not symbol.IsConstructor && + not symbol.IsPropertyGetterMethod && + not symbol.IsPropertySetterMethod && + not (symbol.LogicalName = ".ctor") let (|Method|_|) (symbolUse:FSharpSymbolUse) = match symbolUse with diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpSyntaxMode.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpSyntaxMode.fs index 981bc71284..4722e62ee1 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpSyntaxMode.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpSyntaxMode.fs @@ -3,6 +3,7 @@ open System open System.Collections.Generic open System.Collections.Immutable +open MonoDevelop.FSharp.Shared open MonoDevelop.Ide open MonoDevelop.Ide.Editor open MonoDevelop.Ide.Editor.Highlighting diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTextEditorCompletion.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTextEditorCompletion.fs index 02938d3929..8c3573a1ab 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTextEditorCompletion.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTextEditorCompletion.fs @@ -12,6 +12,7 @@ open Microsoft.FSharp.Compiler.SourceCodeServices open MonoDevelop open MonoDevelop.Core open MonoDevelop.Core.Text +open MonoDevelop.FSharp.Shared open MonoDevelop.Ide open MonoDevelop.Ide.CodeCompletion open MonoDevelop.Ide.Editor @@ -192,28 +193,28 @@ module Completion = let symbolToIcon (symbolUse:FSharpSymbolUse) = match symbolUse with - | ActivePatternCase _ -> Stock.Enum - | Field _ -> Stock.Field - | UnionCase _ -> IconId("md-type") - | Class _ -> Stock.Class - | Delegate _ -> Stock.Delegate - | Constructor _ -> Stock.Method - | Event _ -> Stock.Event - | Property _ -> Stock.Property + | SymbolUse.ActivePatternCase _ -> Stock.Enum + | SymbolUse.Field _ -> Stock.Field + | SymbolUse.UnionCase _ -> IconId("md-type") + | SymbolUse.Class _ -> Stock.Class + | SymbolUse.Delegate _ -> Stock.Delegate + | SymbolUse.Constructor _ -> Stock.Method + | SymbolUse.Event _ -> Stock.Event + | SymbolUse.Property _ -> Stock.Property | Function f -> if f.IsExtensionMember then IconId("md-extensionmethod") elif f.IsMember then IconId("md-method") else IconId("md-fs-field") - | Operator _ -> IconId("md-fs-field") - | ClosureOrNestedFunction _ -> IconId("md-fs-field") - | Val _ -> Stock.Field - | Enum _ -> Stock.Enum - | Interface _ -> Stock.Interface - | Module _ -> IconId("md-module") - | Namespace _ -> Stock.NameSpace - | Record _ -> Stock.Class - | Union _ -> IconId("md-type") - | ValueType _ -> Stock.Struct + | SymbolUse.Operator _ -> IconId("md-fs-field") + | SymbolUse.ClosureOrNestedFunction _ -> IconId("md-fs-field") + | SymbolUse.Val _ -> Stock.Field + | SymbolUse.Enum _ -> Stock.Enum + | SymbolUse.Interface _ -> Stock.Interface + | SymbolUse.Module _ -> IconId("md-module") + | SymbolUse.Namespace _ -> Stock.NameSpace + | SymbolUse.Record _ -> Stock.Class + | SymbolUse.Union _ -> IconId("md-type") + | SymbolUse.ValueType _ -> Stock.Struct | SymbolUse.Entity _ -> IconId("md-type") | _ -> Stock.Event @@ -246,30 +247,30 @@ module Completion = let category = try match symbolUse with - | Constructor c -> + | SymbolUse.Constructor c -> c.EnclosingEntitySafe |> Option.map (fun ent -> let un = ent.UnAnnotate() un.DisplayName, un) - | Event ev -> + | SymbolUse.Event ev -> ev.EnclosingEntitySafe |> Option.map (fun ent -> let un = ent.UnAnnotate() un.DisplayName, un) - | Property pr -> + | SymbolUse.Property pr -> pr.EnclosingEntitySafe |> Option.map (fun ent -> let un = ent.UnAnnotate() un.DisplayName, un) - | ActivePatternCase ap -> + | SymbolUse.ActivePatternCase ap -> if ap.Group.Names.Count > 1 then ap.Group.EnclosingEntity |> Option.map (fun enclosing -> let un = enclosing.UnAnnotate() un.DisplayName, un) else None - | UnionCase uc -> + | SymbolUse.UnionCase uc -> if uc.UnionCaseFields.Count > 1 then let ent = uc.ReturnType.TypeDefinition.UnAnnotate() Some(ent.DisplayName, ent) else None - | Function f -> + | SymbolUse.Function f -> if f.IsExtensionMember then let real = f.LogicalEnclosingEntity.UnAnnotate() Some(real.DisplayName, real) @@ -277,25 +278,25 @@ module Completion = f.EnclosingEntitySafe |> Option.map (fun real -> let un = real.UnAnnotate() un.DisplayName, un) - | Operator o -> + | SymbolUse.Operator o -> o.EnclosingEntitySafe |> Option.map (fun ent -> let un = ent.UnAnnotate() un.DisplayName, un) - | Pattern p -> + | SymbolUse.Pattern p -> p.EnclosingEntitySafe |> Option.map (fun ent -> let un = ent.UnAnnotate() un.DisplayName, ent) - | Val v -> + | SymbolUse.Val v -> v.EnclosingEntitySafe |> Option.map (fun ent -> let un = ent.UnAnnotate() un.DisplayName, un) - | TypeAbbreviation ta -> + | SymbolUse.TypeAbbreviation ta -> //TODO: Check this is correct, I suspect we should return None here let ent = ta.UnAnnotate() Some (ent.DisplayName, ent) //The following have no logical parent to display //Theres no link to a parent type for a closure (FCS limitation) - | ClosureOrNestedFunction _cl -> None + | SymbolUse.ClosureOrNestedFunction _cl -> None //The F# compiler does not currently expose an Entitys parent, only children //| Class _ | Delegate _ | Enum _ | Interface _ | Module _ //| Namespace _ | Record _ | Union _ | ValueType _ -> None diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTokens.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTokens.fs index 41b38f97a4..78fdbf56db 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTokens.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTokens.fs @@ -1,9 +1,10 @@ namespace MonoDevelop.FSharp open Microsoft.FSharp.Compiler.SourceCodeServices open MonoDevelop +open MonoDevelop.Core +open MonoDevelop.FSharp.Shared open MonoDevelop.Ide.Editor open ExtCore.Control -open MonoDevelop.Core open System.IO module Tokens = diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTooltipProvider.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTooltipProvider.fs index 544bf1598a..5573c361a5 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTooltipProvider.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpTooltipProvider.fs @@ -9,6 +9,7 @@ open System.Threading.Tasks open MonoDevelop open MonoDevelop.Core open MonoDevelop.Components +open MonoDevelop.FSharp.Shared open MonoDevelop.Ide open MonoDevelop.Ide.CodeCompletion open MonoDevelop.Ide.Editor diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpUnitTestTextEditorExtension.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpUnitTestTextEditorExtension.fs index 8e5c8d8cd6..90dc82098b 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpUnitTestTextEditorExtension.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpUnitTestTextEditorExtension.fs @@ -61,7 +61,7 @@ module unitTestGatherer = | None _ -> MonoDevelop.Core.LoggingService.LogWarning(sprintf "F# GatherUnitTests: found a unit test method with no qualified name: %s" func.FullName) func.CompiledName - let methName = PrettyNaming.QuoteIdentifierIfNeeded func.CompiledName + let methName = func.CompiledName let isIgnored = func.Attributes |> Seq.exists (fun a -> hasAttribute a (fun attributeName m -> m.IgnoreTestMethodAttributeMarker = attributeName)) diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FakeSearchCategory.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FakeSearchCategory.fs index 791ab3c5f0..cbf4c03f77 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FakeSearchCategory.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FakeSearchCategory.fs @@ -1,127 +1,54 @@ namespace MonoDevelop.FSharp -open System open System.Diagnostics open System.IO open System.Text.RegularExpressions open System.Threading open System.Threading.Tasks -open ExtCore open MonoDevelop.Core open MonoDevelop.Core.Text -open MonoDevelop.Components open MonoDevelop.Components.MainToolbar open MonoDevelop.Ide open MonoDevelop.Projects - -type FakePad() = - inherit MonoDevelop.Ide.Gui.PadContent() - let view = new FSharpConsoleView() - - do view.InitialiseEvents() - - - member x.Run (baseDirectory, task, buildScript) = - let fsiProcess = - let startInfo = - new ProcessStartInfo - (FileName = buildScript, UseShellExecute = false, Arguments = task, - RedirectStandardError = true, CreateNoWindow = true, RedirectStandardOutput = true, - RedirectStandardInput = true, StandardErrorEncoding = Text.Encoding.UTF8, - StandardOutputEncoding = Text.Encoding.UTF8, - WorkingDirectory = baseDirectory) - view.WriteOutput(sprintf "FAKE task runner: Starting %s %s" buildScript task, false) - view.Clear() - - try - Process.Start(startInfo) - with e -> - LoggingService.LogDebug (sprintf "FAKE task runner %s" (e.ToString())) - reraise() - do - Event.merge fsiProcess.OutputDataReceived fsiProcess.ErrorDataReceived - |> Event.filter (fun de -> de.Data <> null) - |> Event.add (fun de -> Runtime.RunInMainThread(fun _ -> view.WriteOutput (de.Data + "\n", false)) |> ignore) - - fsiProcess.EnableRaisingEvents <- true - fsiProcess.BeginOutputReadLine() - fsiProcess.BeginErrorReadLine() - - override x.Control = Control.op_Implicit view - override x.Initialize(_container:MonoDevelop.Ide.Gui.IPadWindow) = - x.UpdateColors() - x.UpdateFont() - - member x.UpdateColors() = - match view.Child with - | :? Gtk.TextView as _v -> - //let colourStyles = Mono.TextEditor.Highlighting.SyntaxModeService.GetColorStyle(MonoDevelop.Ide.IdeApp.Preferences.ColorScheme.Value) - //let shouldMatch = PropertyService.Get ("FSharpBinding.MatchWithThemePropName", true) - //let themeTextColour = colourStyles.PlainText.Foreground |> cairoToGdk - //let themeBackColour = colourStyles.PlainText.Background |> cairoToGdk - - //if shouldMatch then - // v.ModifyText(Gtk.StateType.Normal, themeTextColour) - // v.ModifyBase(Gtk.StateType.Normal, themeBackColour) - //else - // let textColour = PropertyService.Get ("FSharpBinding.TextColorPropName", "#000000") |> ColorHelpers.strToColor - // let backColour = PropertyService.Get ("FSharpBinding.BaseColorPropName", "#FFFFFF") |> ColorHelpers.strToColor - // v.ModifyText(Gtk.StateType.Normal, textColour) - // v.ModifyBase(Gtk.StateType.Normal, backColour) - () - | _ -> () - - member x.UpdateFont() = - let fontName = MonoDevelop.Ide.Fonts.FontService.MonospaceFont.Family - let fontName = PropertyService.Get ("FSharpBinding.FsiFontName", fontName) - LoggingService.logDebug "FAKE task runner: Loading font '%s'" fontName - - let font = Pango.FontDescription.FromString(fontName) - view.SetFont(font) +open MonoDevelop.Core.Execution +open MonoDevelop.Ide.Gui type FakeSearchResult(solution: Solution, match', matchedString, rank, scriptPath) = inherit SearchResult(match', matchedString, rank) - static let fakePad = new FakePad() - - let addPad() = - IdeApp.Workbench.AddPad(fakePad, - "MonoDevelop.FSharp.FakePad", - "FAKE", - "Center Bottom", - IconId("md-command")) - override x.SearchResultType = - SearchResultType.Type + override x.SearchResultType = SearchResultType.Type override x.Description = sprintf "Runs the FAKE %s task in %s" matchedString solution.Name override x.PlainText = "FAKE " + matchedString - override x.Icon = - getImage "md-command" + override x.Icon = getImage "md-command" override x.CanActivate = true override x.Activate() = - let pad = IdeApp.Workbench.FindPad(fakePad) |> Option.ofNull - let pad = - match pad with - | Some pad -> Some pad - | None -> addPad() |> Option.ofNull + let monitor = IdeApp.Workbench.ProgressMonitors.GetRunProgressMonitor ("FAKE") + let processStartInfo = Runtime.ProcessService.CreateProcessStartInfo(scriptPath, matchedString, string solution.BaseDirectory, true) + let fakeProcess = Process.Start processStartInfo + + fakeProcess.EnableRaisingEvents <- true + fakeProcess.BeginOutputReadLine() + fakeProcess.BeginErrorReadLine() + fakeProcess.OutputDataReceived.Add(fun de -> monitor.Log.WriteLine de.Data) + fakeProcess.ErrorDataReceived.Add(fun de -> monitor.ErrorLog.WriteLine de.Data) + + let pad = IdeApp.Workbench.ProgressMonitors.GetPadForMonitor monitor + pad.BringToFront() - pad |> Option.iter (fun p -> - p.BringToFront() - let padContent = p.Content :?> FakePad - padContent.Run (string solution.BaseDirectory, matchedString, scriptPath)) + fakeProcess.Exited.Add(fun _ -> monitor.Dispose()) type FakeSearchCategory() = inherit SearchCategory("FAKE", sortOrder = SearchCategory.FirstCategory) override x.get_Tags() = [|"fake"|] - override x.IsValidTag _tag = - true + override x.IsValidTag _tag = true override x.GetResults(searchCallback, pattern, token) = diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/MonoDevelop.FSharp.fsproj b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/MonoDevelop.FSharp.fsproj index 73d522aa38..2846f69622 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/MonoDevelop.FSharp.fsproj +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/MonoDevelop.FSharp.fsproj @@ -62,10 +62,10 @@ </NuGetPackage> <NuGetPackage Include="System.ValueTuple"> <Name>System.ValueTuple</Name> - <Version>4.3.0</Version> + <Version>4.3.1</Version> </NuGetPackage> </ItemGroup> - <Copy SourceFiles="..\packages\%(NuGetPackage.Name)\%(NuGetPackage.Name).%(NuGetPackage.Version).nupkg" DestinationFolder="$(OutputPath)/Packages" /> + <Copy SourceFiles="..\packages\%(NuGetPackage.Name)\%(NuGetPackage.Name).%(NuGetPackage.Version).nupkg" DestinationFolder="$(OutputPath)/Packages" SkipUnchangedFiles="true" /> </Target> <Target Name="AfterBuild"> </Target> @@ -77,8 +77,6 @@ <ItemGroup> <Compile Include="Services\Extensions.fs" /> <Compile Include="Services\CompilerLocationUtils.fs" /> - <Compile Include="Services\Lexer.fs" /> - <Compile Include="Services\Parser.fs" /> <Compile Include="Services\OrderAssemblyReferences.fs" /> <Compile Include="Services\Parameters.fs" /> <Compile Include="Services\TooltipHelpers.fs" /> @@ -87,7 +85,6 @@ <Compile Include="Services\LanguageService.fs" /> <Compile Include="Services\MDLanguageService.fs" /> <Compile Include="Services\CompilerService.fs" /> - <Compile Include="Services\FSharpConsoleView.fs" /> <Compile Include="Services\InteractiveSession.fs" /> <Compile Include="Services\RoslynHelpers.fs" /> <Compile Include="FSharpParsedDocument.fs" /> @@ -128,6 +125,7 @@ <Compile Include="Properties\AddinInfo.fs" /> <Compile Include="HighlightUnusedCode.fs" /> <Compile Include="ScriptDebugging.fs" /> + <Compile Include="FSharpProjectCompilerOptions.fs" /> </ItemGroup> <ItemGroup> <Reference Include="pango-sharp" /> @@ -273,11 +271,6 @@ <Private>True</Private> <Paket>True</Paket> </Reference> - <Reference Include="FSharp.Compiler.Service.MSBuild.v12"> - <HintPath>..\packages\FSharp.Compiler.Service\lib\net45\FSharp.Compiler.Service.MSBuild.v12.dll</HintPath> - <Private>True</Private> - <Paket>True</Paket> - </Reference> </ItemGroup> </When> </Choose> @@ -295,11 +288,6 @@ <Choose> <When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.6.1'"> <ItemGroup> - <Reference Include="Mono.Cecil"> - <HintPath>..\packages\Mono.Cecil\lib\net45\Mono.Cecil.dll</HintPath> - <Private>True</Private> - <Paket>True</Paket> - </Reference> <Reference Include="Mono.Cecil.Mdb"> <HintPath>..\packages\Mono.Cecil\lib\net45\Mono.Cecil.Mdb.dll</HintPath> <Private>True</Private> @@ -326,6 +314,11 @@ <Private>True</Private> <Paket>True</Paket> </Reference> + <Reference Include="Mono.Cecil"> + <HintPath>..\packages\Mono.Cecil\lib\net45\Mono.Cecil.dll</HintPath> + <Private>True</Private> + <Paket>True</Paket> + </Reference> </ItemGroup> </When> </Choose> diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/ProjectSearchCategory.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/ProjectSearchCategory.fs index 317062e049..938cc33d20 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/ProjectSearchCategory.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/ProjectSearchCategory.fs @@ -77,7 +77,7 @@ module Search = /// constructors have a display name of ( .ctor ) use the enclosing entities display name let correctDisplayName (symbol:FSharpSymbolUse) = match symbol with - | Constructor c -> + | SymbolUse.Constructor c -> match c.EnclosingEntitySafe with | Some ent -> ent.DisplayName | _ -> LoggingService.LogError(sprintf "Constructor with no EnclosingEntity: %s" c.DisplayName) @@ -112,35 +112,35 @@ type SymbolSearchResult(match', matchedString, rank, symbol:FSharpSymbolUse) = override x.SearchResultType = match symbol with - | Record _ | Module _ | ValueType _ | Delegate _ | Union _ | Class _ - | Namespace _ | Interface _ | Enum _ | ActivePattern _ -> SearchResultType.Type + | SymbolUse.Record _ | SymbolUse.Module _ | SymbolUse.ValueType _ | SymbolUse.Delegate _ | SymbolUse.Union _ | SymbolUse.Class _ + | SymbolUse.Namespace _ | SymbolUse.Interface _ | SymbolUse.Enum _ | SymbolUse.ActivePattern _ -> SearchResultType.Type - | ActivePatternCase _ | Field _ | UnionCase _ | Property _ - | Event _ | Operator _ | Constructor _ | Function _ | Val _-> SearchResultType.Member + | SymbolUse.ActivePatternCase _ | SymbolUse.Field _ | SymbolUse.UnionCase _ | SymbolUse.Property _ + | SymbolUse.Event _ | SymbolUse.Operator _ | SymbolUse.Constructor _ | SymbolUse.Function _ | SymbolUse.Val _-> SearchResultType.Member | _ -> SearchResultType.Unknown override x.Description = let cat = match symbol with - | Record _ -> "record" - | Module _ -> "module" - | ValueType _ -> "struct" - | Delegate _ -> "delegate" - | Union _ -> "union" - | Class c -> if c.IsFSharp then "type" else "class" - | Namespace _ -> "namespace" - | Interface _ -> "interface" - | Enum _ -> "enum" - | ActivePattern _ -> "active pattern" - | Field _ -> "field" - | UnionCase _ -> "union case" - | Property _ -> "property" - | Event _ -> "event" - | Operator _ -> "operator" - | Constructor _ -> "constructor" - | Method _ -> "method" - | Function _ -> "function" - | Val _ -> "val" + | SymbolUse.Record _ -> "record" + | SymbolUse.Module _ -> "module" + | SymbolUse.ValueType _ -> "struct" + | SymbolUse.Delegate _ -> "delegate" + | SymbolUse.Union _ -> "union" + | SymbolUse.Class c -> if c.IsFSharp then "type" else "class" + | SymbolUse.Namespace _ -> "namespace" + | SymbolUse.Interface _ -> "interface" + | SymbolUse.Enum _ -> "enum" + | SymbolUse.ActivePattern _ -> "active pattern" + | SymbolUse.Field _ -> "field" + | SymbolUse.UnionCase _ -> "union case" + | SymbolUse.Property _ -> "property" + | SymbolUse.Event _ -> "event" + | SymbolUse.Operator _ -> "operator" + | SymbolUse.Constructor _ -> "constructor" + | SymbolUse.Method _ -> "method" + | SymbolUse.Function _ -> "function" + | SymbolUse.Val _ -> "val" | _ -> "symbol" sprintf "%s (file %s)" cat symbol.RangeAlternate.FileName @@ -149,27 +149,27 @@ type SymbolSearchResult(match', matchedString, rank, symbol:FSharpSymbolUse) = override x.File = symbol.RangeAlternate.FileName override x.Icon = match symbol with - | Record _ -> getImage "md-type" - | Module _ -> getImage "md-module" - | ValueType s -> s |> getImageFromAccessibility Stock.Struct.Name Stock.InternalStruct.Name Stock.PrivateStruct.Name - | Delegate d -> d |> getImageFromAccessibility Stock.Delegate.Name Stock.InternalDelegate.Name Stock.PrivateDelegate.Name - | Union _ -> getImage "md-type" - | Class c -> if c.IsFSharp then getImage "md-type" else c |> getImageFromAccessibility Stock.Class.Name Stock.InternalClass.Name Stock.PrivateClass.Name - | Namespace _ -> getImage Stock.NameSpace.Name - | Interface i -> i |> getImageFromAccessibility Stock.Interface.Name Stock.InternalInterface.Name Stock.PrivateInterface.Name - | Enum e -> e |> getImageFromAccessibility Stock.Enum.Name Stock.InternalEnum.Name Stock.PrivateEnum.Name - | ActivePattern _ -> getImage "md-type" - | Field f ->f |> getImageFromAccessibility Stock.Field.Name Stock.InternalField.Name Stock.PrivateField.Name - | UnionCase _ -> getImage "md-type" - | Property p -> p |> getImageFromAccessibility Stock.Property.Name Stock.InternalProperty.Name Stock.PrivateProperty.Name - | Event e -> e |> getImageFromAccessibility Stock.Event.Name Stock.InternalEvent.Name Stock.PrivateEvent.Name - | Operator _ -> getImage "md-fs-field" - | Constructor c -> c |> getImageFromAccessibility Stock.Method.Name Stock.InternalMethod.Name Stock.PrivateMethod.Name - | Function mfv -> + | SymbolUse.Record _ -> getImage "md-type" + | SymbolUse.Module _ -> getImage "md-module" + | SymbolUse.ValueType s -> s |> getImageFromAccessibility Stock.Struct.Name Stock.InternalStruct.Name Stock.PrivateStruct.Name + | SymbolUse.Delegate d -> d |> getImageFromAccessibility Stock.Delegate.Name Stock.InternalDelegate.Name Stock.PrivateDelegate.Name + | SymbolUse.Union _ -> getImage "md-type" + | SymbolUse.Class c -> if c.IsFSharp then getImage "md-type" else c |> getImageFromAccessibility Stock.Class.Name Stock.InternalClass.Name Stock.PrivateClass.Name + | SymbolUse.Namespace _ -> getImage Stock.NameSpace.Name + | SymbolUse.Interface i -> i |> getImageFromAccessibility Stock.Interface.Name Stock.InternalInterface.Name Stock.PrivateInterface.Name + | SymbolUse.Enum e -> e |> getImageFromAccessibility Stock.Enum.Name Stock.InternalEnum.Name Stock.PrivateEnum.Name + | SymbolUse.ActivePattern _ -> getImage "md-type" + | SymbolUse.Field f ->f |> getImageFromAccessibility Stock.Field.Name Stock.InternalField.Name Stock.PrivateField.Name + | SymbolUse.UnionCase _ -> getImage "md-type" + | SymbolUse.Property p -> p |> getImageFromAccessibility Stock.Property.Name Stock.InternalProperty.Name Stock.PrivateProperty.Name + | SymbolUse.Event e -> e |> getImageFromAccessibility Stock.Event.Name Stock.InternalEvent.Name Stock.PrivateEvent.Name + | SymbolUse.Operator _ -> getImage "md-fs-field" + | SymbolUse.Constructor c -> c |> getImageFromAccessibility Stock.Method.Name Stock.InternalMethod.Name Stock.PrivateMethod.Name + | SymbolUse.Function mfv -> if mfv.IsExtensionMember then mfv |> getImageFromAccessibility "md-extensionmethod" "md-internal-extensionmethod" "md-private-extensionmethod" elif mfv.IsMember then mfv |> getImageFromAccessibility Stock.Method.Name Stock.InternalMethod.Name Stock.PrivateMethod.Name else getImage "md-fs-field" - | Val _ -> getImage "md-fs-field" //NOTE: Maybe make this a normal field icon? + | SymbolUse.Val _ -> getImage "md-fs-field" //NOTE: Maybe make this a normal field icon? | _ -> getImage Stock.Event.Name override x.GetTooltipInformation(_token) = diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/ScriptDebugging.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/ScriptDebugging.fs index 38fd69e919..7818cd686d 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/ScriptDebugging.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/ScriptDebugging.fs @@ -35,7 +35,7 @@ type ScriptBuildTarget(scriptPath, consoleKind, source) = async { let filename = scriptPath |> string let checker = FSharpChecker.Create() - let! opts = checker.GetProjectOptionsFromScript(filename, source) + let! opts, _errors = checker.GetProjectOptionsFromScript(filename, source) let! _parseFileResults, checkFileResults = checker.ParseAndCheckFileInProject(filename, 0, source, opts) let checkResults = diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/CompilerArguments.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/CompilerArguments.fs index 641335a4ef..32680eeae2 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/CompilerArguments.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/CompilerArguments.fs @@ -88,16 +88,7 @@ module CompilerArguments = | Some asm -> [asm.Location] | None -> [] else - let package = reference.Package - package.Assemblies - |> Seq.choose (fun a -> match a.Name with - | "FSharp.Core" - | "mscorlib" -> None - | _ -> if package.IsGacPackage then - Some a.Name - else - Some a.Location) - |> List.ofSeq + [] | ReferenceType.Project -> let referencedProject = reference.Project :?> DotNetProject diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/FSharpConsoleView.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/FSharpConsoleView.fs deleted file mode 100644 index a27c9ccd15..0000000000 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/FSharpConsoleView.fs +++ /dev/null @@ -1,459 +0,0 @@ -namespace MonoDevelop.FSharp -open System -open System.Collections.Generic -open Gtk -open MonoDevelop.Core -open Microsoft.FSharp.Compiler.SourceCodeServices -open Mono.TextEditor.Highlighting -open MonoDevelop.Ide - -type TokeniserOutput = - | Token of FSharpTokenInfo * string | EndState of FSharpTokenizerLexState - static member PlainHash = Token({LeftColumn=0 - RightColumn=0 - ColorClass=FSharpTokenColorKind.PreprocessorKeyword - CharClass=FSharpTokenCharKind.Delimiter - FSharpTokenTriggerClass=FSharpTokenTriggerClass.None - Tag=0 - TokenName="#" - FullMatchedLength=1}, "#") - -[<RequireQualifiedAccess>] -type Prompt = Normal | Multiline | None - -type Tags = - | Freezer - | Keyword - | User - | String - | Comment - | Inactive - | Number - | Operator - | Preprocessor - | PlainText - -type FSharpConsoleView() as x = - inherit ScrolledWindow() - - let console = Event<_>() - let mutable scriptLines = "" - let commandHistoryPast = new Stack<string> () - let commandHistoryFuture = new Stack<string> () - let textView = new TextView (WrapMode = Gtk.WrapMode.Word) - let buffer = textView.Buffer - let inputBeginMark = buffer.CreateMark (null, buffer.EndIter, true) - - //let getTextTag (chunkStyle:ChunkStyle) = - // new TextTag (chunkStyle.Name) - // Foreground=ColorScheme.ColorToMarkup chunkStyle.Foreground) - - let mutable lastLineState = 0L //used as last lines state - let mutable tempState = 0L //used as the last stet for an in process line - let tags = Dictionary<_,_>() - - let getTokensForLine file defines (line:string) state = - // Get defined directives - let defines = defines |> Option.map (fun (s:string) -> s.Split([| ' '; ';'; ',' |], StringSplitOptions.RemoveEmptyEntries) |> List.ofSeq) - // Create source tokenizer - let sourceTok = FSharpSourceTokenizer(defaultArg defines ["INTERACTIVE";"EDITING"], file) - // Parse lines using the tokenizer - let tokenizer = sourceTok.CreateLineTokenizer(line) - let rec parseLine state = - [ match tokenizer.ScanToken(state) with - | Some(tok), nstate -> - let str = line.Substring(tok.LeftColumn, tok.RightColumn - tok.LeftColumn + 1) - yield Token(tok, str) - yield! parseLine nstate - | None, nstate -> - yield EndState nstate ] - parseLine state - - let getTokensFromLines file defines (lines:string[]) state = - [ for line in lines do - yield getTokensForLine file defines line state ] - - let inputBeingProcessed = ref false - let startInputProcessing() = - inputBeingProcessed := true - { new IDisposable with - member x.Dispose() = inputBeingProcessed := false } - - let applyToken (txt:string) (tag:TextTag) = - let mutable startIter = buffer.EndIter - buffer.InsertWithTags(&startIter, txt, [|tag|]) - - let eraseCurrentLine() = - let mutable start = x.InputLineBegin - let mutable end' = x.InputLineEnd - buffer.Delete (&start, &end') - - let (|Keyword|_|) t = - match t.ColorClass with FSharpTokenColorKind.Keyword -> Some(t) | _ -> None - - let (|Identifier|_|) t = - match t.ColorClass with FSharpTokenColorKind.Identifier -> Some(t) | _ -> None - - let (|UpperIdentifier|_|) t = - match t.ColorClass with FSharpTokenColorKind.UpperIdentifier -> Some(t) | _ -> None - - let (|Comment|_|) t = - match t.ColorClass with FSharpTokenColorKind.Comment -> Some(t) | _ -> None - - let (|String|_|) (t:FSharpTokenInfo) = - match t.ColorClass with - | FSharpTokenColorKind.String - | FSharpTokenColorKind.Text when not (t.CharClass = FSharpTokenCharKind.Delimiter || t.CharClass = FSharpTokenCharKind.Operator) -> Some(t) - | _ -> None - - let (|InactiveCode|_|) t = - match t.ColorClass with FSharpTokenColorKind.InactiveCode -> Some(t) | _ -> None - - let (|Number|_|) t = - match t.ColorClass with FSharpTokenColorKind.Number -> Some(t) | _ -> None - - let (|Operator|_|) t = - match t.ColorClass, t.CharClass with - | FSharpTokenColorKind.Operator, _ -> Some(t) - | _, FSharpTokenCharKind.Delimiter - | _, FSharpTokenCharKind.Operator -> Some(t) - | _ -> None - - let (|Preprocessor|_|) t = - match t.ColorClass with FSharpTokenColorKind.PreprocessorKeyword -> Some(t) | _ -> None - - let highlightLine (line:string) state = - let tokens = - if line.StartsWith("#") && line.Length > 1 && not (line.StartsWith("#r")) then - [ yield TokeniserOutput.PlainHash - yield! getTokensForLine None None line.[1..] state ] - else getTokensForLine None None line state - tokens |> - List.fold (fun state t -> - match t with - | Token( t,txt) -> - match t with - | Keyword _-> applyToken txt tags.[Keyword]; state - | Identifier _-> applyToken txt tags.[User]; state - | UpperIdentifier _-> applyToken txt tags.[User]; state - | Comment _-> applyToken txt tags.[Comment]; state - | String _-> applyToken txt tags.[String]; state - | InactiveCode _-> applyToken txt tags.[Inactive]; state - | Number _-> applyToken txt tags.[Number]; state - | Operator _-> applyToken txt tags.[Operator]; state - | Preprocessor _-> applyToken txt tags.[Preprocessor]; state - | _ -> applyToken txt tags.[PlainText]; state - | EndState state -> state) 0L - - let disposables = ResizeArray() - - let createDisposable f = - { new IDisposable with - member x.Dispose() = f()} - - let addDisposable = - disposables.Add - - //let updateColors() = - // let addTag (k:Tags) v = - // tags.Add(k,v) - // buffer.TagTable.Add v - - // let scheme = SyntaxModeService.GetColorStyle (IdeApp.Preferences.ColorScheme.Value) - // tags |> Seq.iter (fun (KeyValue(_k,v)) -> buffer.TagTable.Remove(v); v.Dispose()) - // tags.Clear() - // addTag Tags.Keyword (getTextTag scheme.KeywordTypes) - // addTag Tags.User (getTextTag scheme.UserTypes) - // addTag Tags.String (getTextTag scheme.String) - // addTag Tags.Comment (getTextTag scheme.CommentTags) - // addTag Tags.Inactive (getTextTag scheme.ExcludedCode) - // addTag Tags.Number (getTextTag scheme.Number) - // addTag Tags.Operator (getTextTag scheme.Punctuation) - // addTag Tags.Preprocessor (getTextTag scheme.Preprocessor) - // addTag Tags.PlainText (getTextTag scheme.PlainText) - // addTag Tags.Freezer (new TextTag ("Freezer", Editable = false)) - - //do updateColors() - // x.Add (textView) - // x.ShowAll () - - member x.InitialiseEvents() = - disposables.Add( - IdeApp.Preferences.ColorScheme.Changed.Subscribe - (fun _ (eventArgs:EventArgs) -> - //updateColors() - x.ShowAll())) - - let handleKeyPressDelegate = - let mainType = typeof<FSharpConsoleView> - let keyPress = mainType.GetMethod("HandleKeyPress") - Delegate.CreateDelegate(typeof<KeyPressEventHandler>, x, keyPress) :?> KeyPressEventHandler - - // let handleCopyDelegate = - // let mainType = typeof<FSharpConsoleView> - // let copy = mainType.GetMethod("HandleCopy") - // Delegate.CreateDelegate(typeof<EventHandler>, x, copy) :?> EventHandler - // textView.add_CopyClipboard(handleCopyDelegate) - - textView.Buffer.InsertText.Subscribe(x.TextInserted) - |> addDisposable - - textView.add_KeyPressEvent(handleKeyPressDelegate) - createDisposable (fun () -> textView.remove_KeyPressEvent(handleKeyPressDelegate)) - |> addDisposable - - textView.PopulatePopup.Subscribe(x.TextViewPopulatePopup) - |> addDisposable - - member x.TextInserted _ = - if not !inputBeingProcessed then - using (startInputProcessing()) - (fun _ -> - let line : string = x.InputLine - let cursorPosition = buffer.CursorPosition - eraseCurrentLine() - let lines = line.Split([|'\n'|], StringSplitOptions.None) - if lines.Length = 1 then tempState <- highlightLine line lastLineState - else - lines - |> Array.iteri - (fun i line -> - if i < lines.Length-1 then - lastLineState <- highlightLine line lastLineState - x.ProcessReturn() - else - tempState <- highlightLine line lastLineState) - buffer.PlaceCursor(buffer.GetIterAtOffset(cursorPosition))) - - [<GLib.ConnectBeforeAttribute>] - member x.HandleKeyPress(_o:obj, args) = - if (x.ProcessKeyPressEvent (args)) then - args.RetVal <- true - - //fired on context menu copy - [<GLib.ConnectBeforeAttribute>] - member x.HandleCopy(_o:obj, _e: EventArgs) = - () - - //fired on context menu paste - [<GLib.ConnectBeforeAttribute>] - member x.HandlePaste(_o:obj, _e:EventArgs) = - () - - member x.TextViewPopulatePopup _sender args = - let item = new MenuItem (Mono.Unix.Catalog.GetString ("Clear")) - let sep = new SeparatorMenuItem () - - item.Activated.Add (fun _ -> x.Clear ()) - item.Show () - sep.Show () - - args.Menu.Add (sep) - args.Menu.Add (item) - - member x.SetFont (font) = textView.ModifyFont (font) - member x.TextView = textView - member val PromptString = "> " with get, set - member val PromptMultiLineString = "- " with get, set - member val AutoIndent = false with get, set - - member x.ProcessReturn () = - // Bookkeeping - if (x.InputLine <> "") then - - // Everything but the last item (which was input), in the future stack needs to get put back into the past stack - while (commandHistoryFuture.Count > 1) do - commandHistoryPast.Push (commandHistoryFuture.Pop()) - // Clear the pesky junk input line - commandHistoryFuture.Clear() - - // Record our input line - commandHistoryPast.Push(x.InputLine) - if scriptLines = "" then scriptLines <- scriptLines + x.InputLine - else scriptLines <- scriptLines + "\n" + x.InputLine - - x.ProcessInput (x.InputLine) - lastLineState <- tempState - let prompt, newLine = - if x.InputLine.EndsWith(";;\n") then Prompt.None, true - else Prompt.Multiline, false - x.Prompt(newLine, prompt) - - member x.ProcessCommandHistoryUp () = - if commandHistoryPast.Count > 0 then - if commandHistoryFuture.Count = 0 then - commandHistoryFuture.Push (x.InputLine) - else - if commandHistoryPast.Count = 1 then () - else commandHistoryFuture.Push (commandHistoryPast.Pop ()) - x.InputLine <- commandHistoryPast.Peek () - - member x.ProcessCommandHistoryDown () = - if commandHistoryFuture.Count > 0 then - if commandHistoryFuture.Count = 1 then - x.InputLine <- commandHistoryFuture.Pop () - else - commandHistoryPast.Push (commandHistoryFuture.Pop ()) - x.InputLine <- commandHistoryPast.Peek () - - member x.InputLineBegin = buffer.GetIterAtMark(inputBeginMark) - member x.InputLineEnd = buffer.EndIter - member x.Cursor = buffer.GetIterAtMark (buffer.InsertMark) - - member x.ProcessKeyPressEvent ( args:KeyPressEventArgs) = - let returnCode = - // Short circuit to avoid getting moved back to the input line - // when paging up and down in the shell output - if args.Event.Key = Gdk.Key.Page_Up || args.Event.Key = Gdk.Key.Page_Down then false - else - - // Needed so people can copy and paste, but always end up typing in the prompt. - if x.Cursor.Compare(x.InputLineBegin) < 0 then - buffer.MoveMark (buffer.SelectionBound, x.InputLineEnd) - buffer.MoveMark (buffer.InsertMark, x.InputLineEnd) - - match (args.Event.Key) with - | Gdk.Key.KP_Enter | Gdk.Key.Return -> - x.ProcessReturn () - true - | Gdk.Key.KP_Up | Gdk.Key.Up -> - x.ProcessCommandHistoryUp () - true - | Gdk.Key.KP_Down | Gdk.Key.Down -> - x.ProcessCommandHistoryDown () - true - | Gdk.Key.KP_Left | Gdk.Key.Left -> - // On Mac, when using a small keyboard, Home is Command+Left - if Platform.IsMac && args.Event.State.HasFlag (Gdk.ModifierType.MetaMask) then - buffer.MoveMark (buffer.InsertMark, x.InputLineBegin) - - // Move the selection mark too, if shift isn't held - if not (args.Event.State.HasFlag (Gdk.ModifierType.ShiftMask)) then - buffer.MoveMark (buffer.SelectionBound, x.InputLineBegin) - true - else false - elif x.Cursor.Compare (x.InputLineBegin) <= 0 then true - else false - | Gdk.Key.KP_Right | Gdk.Key.Right -> - if x.Cursor.Compare (x.InputLineEnd) >= 0 then true - else false - | Gdk.Key.KP_Home | Gdk.Key.Home -> - buffer.MoveMark (buffer.InsertMark, x.InputLineBegin) - - // Move the selection mark too, if shift isn't held - if not (args.Event.State.HasFlag (Gdk.ModifierType.ShiftMask)) then - buffer.MoveMark (buffer.SelectionBound, x.InputLineBegin) - true - | Gdk.Key.a -> - if (args.Event.State.HasFlag (Gdk.ModifierType.ControlMask)) then - buffer.MoveMark (buffer.InsertMark, x.InputLineBegin) - - // Move the selection mark too, if shift isn't held - if not (args.Event.State.HasFlag (Gdk.ModifierType.ShiftMask)) then - buffer.MoveMark (buffer.SelectionBound, x.InputLineBegin) - true - else false - | Gdk.Key.BackSpace | Gdk.Key.Delete -> false - | _ -> - //do our syntax highlighting - using (startInputProcessing()) (fun _ -> - let nextKey = Gdk.Keyval.ToUnicode(args.Event.KeyValue) |> char |> string - buffer.InsertAtCursor(nextKey) - let cursorOffset = buffer.CursorPosition - let line = x.InputLine - eraseCurrentLine() - let lines = line.Split([|'\n'|], StringSplitOptions.None) - if lines.Length = 1 then tempState <- highlightLine line lastLineState - else - lines - |> Array.iteri - (fun i line -> - if i < lines.Length-1 then - lastLineState <- highlightLine line lastLineState - x.ProcessReturn() - else - tempState <- highlightLine line lastLineState) - buffer.PlaceCursor(buffer.GetIterAtOffset(cursorOffset))) - true - - returnCode - - // The current input line - member x.InputLine - with get() = buffer.GetText (x.InputLineBegin, x.InputLineEnd, false) - and set(v) = - using (startInputProcessing()) (fun _ -> - let mutable start = x.InputLineBegin - let mutable end' = x.InputLineEnd - buffer.Delete (&start, &end') - start <- x.InputLineBegin - tempState <- highlightLine v lastLineState) - - member x.ProcessInput (line:string) = - x.WriteOutput("\n", false) - console.Trigger(line) - - member x.WriteOutput (line:string, highlight) = - using (startInputProcessing()) (fun _ -> - if highlight then - let tokens = getTokensFromLines None None (line.Split([|'\n';'\r'|], StringSplitOptions.RemoveEmptyEntries)) 0L - tokens |> - List.iter - (List.iter (function - | Token( t,txt) -> - match t with - | Keyword _-> applyToken txt tags.[Keyword] - | Identifier _-> applyToken txt tags.[User] - | UpperIdentifier _-> applyToken txt tags.[User] - | Comment _-> applyToken txt tags.[Comment] - | String _-> applyToken txt tags.[String] - | InactiveCode _-> applyToken txt tags.[Inactive] - | Number _-> applyToken txt tags.[Number] - | Operator _-> applyToken txt tags.[Operator] - | Preprocessor _-> applyToken txt tags.[Preprocessor] - | _ -> applyToken txt tags.[PlainText] - | EndState _ -> - let mutable end' = buffer.EndIter - buffer.Insert (&end', "\n"))) - else - let mutable start = buffer.EndIter - buffer.Insert(&start, line) - - buffer.PlaceCursor (buffer.EndIter) - textView.ScrollMarkOnscreen (buffer.InsertMark)) - - member x.Prompt (newLine, prompt:Prompt) = - using (startInputProcessing()) (fun _ -> - let mutable end' = buffer.EndIter - - if newLine then buffer.Insert (&end', "\n") - - match prompt with - | Prompt.Normal -> buffer.Insert (&end', x.PromptString) - | Prompt.Multiline -> buffer.Insert (&end', x.PromptMultiLineString) - | Prompt.None -> () - - buffer.PlaceCursor (buffer.EndIter) - textView.ScrollMarkOnscreen (buffer.InsertMark) - - buffer.MoveMark (inputBeginMark, buffer.EndIter) - - // Freeze all the text except our input line - buffer.ApplyTag(tags.[Freezer], buffer.StartIter, x.InputLineBegin)) - - - member x.Clear () = - buffer.Text <- "" - scriptLines <- "" - x.Prompt (false, Prompt.Normal) - - member x.ClearHistory () = - commandHistoryFuture.Clear () - commandHistoryPast.Clear () - - [<CLIEvent>] - member x.ConsoleInput = console.Publish - - interface IDisposable with - member x.Dispose() = - disposables |> Seq.iter (fun d -> d.Dispose() ) diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/LanguageService.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/LanguageService.fs index e523d4940c..9d7c9e3755 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/LanguageService.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/LanguageService.fs @@ -11,6 +11,7 @@ open MonoDevelop.Core open MonoDevelop.Ide open MonoDevelop.Ide.Editor open MonoDevelop.Projects +open MonoDevelop.FSharp.Shared module Symbol = /// We always know the text of the identifier that resolved to symbol. @@ -52,7 +53,7 @@ type ParseAndCheckResults (infoOpt : FSharpCheckFileResults option, parseResults // Get items & generate output try let results = - Async.RunSynchronously (checkResults.GetDeclarationListInfo( parseResults, line, col, lineStr, longName, residue, fun (_,_) -> false), timeout = ServiceSettings.blockingTimeout ) + Async.RunSynchronously (checkResults.GetDeclarationListInfo( parseResults, line, col, lineStr, longName, residue, fun () -> []), timeout = ServiceSettings.blockingTimeout ) Some (results, residue) with :? TimeoutException -> None | None, _ -> None @@ -276,6 +277,12 @@ type LanguageService(dirtyNotify, _extraProjectInfo) as x = //cache 50 project infos, then start evicting the least recently used entries ref (ExtCore.Caching.LruCache.create 50u) + let optionsForDependentProject p = + async { + let! assemblies = x.GetReferencedAssembliesAsync p + return x.GetProjectCheckerOptions(p, [], assemblies) + } + member x.Checker = checker member x.ClearProjectInfoCache() = @@ -299,7 +306,7 @@ type LanguageService(dirtyNotify, _extraProjectInfo) as x = try let fileName = fixFileName(fileName) LoggingService.LogDebug ("LanguageService: GetScriptCheckerOptions: Creating for stand-alone file or script: {0}", fileName) - let opts = + let opts, _errors = Async.RunSynchronously (checker.GetProjectOptionsFromScript(fileName, source, fakeDateTimeRepresentingTimeLoaded projFilename), timeout = ServiceSettings.maximumTimeout) @@ -324,11 +331,24 @@ type LanguageService(dirtyNotify, _extraProjectInfo) as x = // opts.ProjectFileName opts.ProjectFileNames opts.ProjectOptions opts.IsIncompleteTypeCheckEnvironment opts.UseScriptResolutionRules) Some opts - member x.GetProjectOptionsFromProjectFile(project:DotNetProject, ?referencedAssemblies) = - let getReferencedAssemblies() = - retry { return (project.GetReferencedAssemblies(CompilerArguments.getConfig())).Result } + member x.GetProjectFromFileName projectFile = + IdeApp.Workspace.GetAllProjects() + |> Seq.tryFind (fun p -> p.FileName.FullPath.ToString() = projectFile) + |> Option.map(fun p -> p :?> DotNetProject) + + member x.GetReferencedAssembliesSynchronously (project:DotNetProject) = + retry { return (project.GetReferencedAssemblies(CompilerArguments.getConfig())).Result } - let referencedAssemblies = defaultArg referencedAssemblies (getReferencedAssemblies()) + member x.GetReferencedAssembliesAsync projectFile = + async { + let project = x.GetProjectFromFileName projectFile + match project with + | Some proj -> return! proj.GetReferencedAssemblies(CompilerArguments.getConfig()) |> Async.AwaitTask + | None -> return Seq.empty + } + + member x.GetProjectOptionsFromProjectFile(project:DotNetProject, ?referencedAssemblies) = + let referencedAssemblies = defaultArg referencedAssemblies (x.GetReferencedAssembliesSynchronously project) let config = match IdeApp.Workspace with | null -> ConfigurationSelector.Default @@ -364,7 +384,7 @@ type LanguageService(dirtyNotify, _extraProjectInfo) as x = entry /// Constructs options for the interactive checker for a project under the given configuration. - member x.GetProjectCheckerOptions(projFilename, ?properties) : FSharpProjectOptions option = + member x.GetProjectCheckerOptions(projFilename, ?properties, ?referencedAssemblies) : FSharpProjectOptions option = let properties = defaultArg properties ["Configuration", IdeApp.Workspace.ActiveConfigurationId] let key = (projFilename, properties) @@ -381,7 +401,9 @@ type LanguageService(dirtyNotify, _extraProjectInfo) as x = match project with | Some proj -> - let opts = x.GetProjectOptionsFromProjectFile (proj :?> DotNetProject) + let proj = proj :?> DotNetProject + let referencedAssemblies = defaultArg referencedAssemblies (x.GetReferencedAssembliesSynchronously proj) + let opts = x.GetProjectOptionsFromProjectFile (proj, referencedAssemblies) opts |> Option.bind(fun opts' -> projectInfoCache := cache.Add (key, opts') // Print contents of check option for debugging purposes @@ -489,10 +511,13 @@ type LanguageService(dirtyNotify, _extraProjectInfo) as x = member x.GetUsesOfSymbolInProject(projectFilename, file, source, symbol:FSharpSymbol, ?dependentProjects) = async { LoggingService.logDebug "LanguageService: GetUsesOfSymbolInProject: project:%s, currentFile:%s, symbol:%s" projectFilename file symbol.DisplayName - let sourceProjectOptions = x.GetCheckerOptions(file, projectFilename, source) - let dependentProjectsOptions = defaultArg dependentProjects [] |> List.map x.GetProjectCheckerOptions - let! allProjectResults = + + let! dependentProjectsOptions = + defaultArg dependentProjects [] + |> Async.List.map optionsForDependentProject + + let! allProjectResults = sourceProjectOptions :: dependentProjectsOptions |> List.choose id |> Async.List.map checker.ParseAndCheckProject @@ -503,7 +528,8 @@ type LanguageService(dirtyNotify, _extraProjectInfo) as x = |> Async.Parallel |> Async.map Array.concat - return allSymbolUses } + return allSymbolUses + } member x.MatchingBraces(filename, projectFilename, source) = let options = x.GetCheckerOptions(filename, projectFilename, source) @@ -551,7 +577,10 @@ type LanguageService(dirtyNotify, _extraProjectInfo) as x = async { LoggingService.logDebug "LanguageService: GetDerivedSymbolInProject: proj:%s, file:%s, symbol:%s" projectFilename file symbolAtCaret.DisplayName let sourceProjectOptions = x.GetCheckerOptions(file, projectFilename, source) - let dependentProjectsOptions = defaultArg dependentProjects [] |> List.map x.GetProjectCheckerOptions + + let! dependentProjectsOptions = + defaultArg dependentProjects [] + |> Async.List.map optionsForDependentProject let! allProjectResults = sourceProjectOptions :: dependentProjectsOptions diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/Lexer.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/Lexer.fs deleted file mode 100644 index 6eecd36e65..0000000000 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/Lexer.fs +++ /dev/null @@ -1,266 +0,0 @@ -namespace MonoDevelop.FSharp - -open System.Diagnostics -open Microsoft.FSharp.Compiler.SourceCodeServices -open MonoDevelop.Core - -type SymbolKind = - | Ident - | Operator - | GenericTypeParameter - | StaticallyResolvedTypeParameter - | ActivePattern - | Other - -type LexerSymbol = - { Kind: SymbolKind - Line: int - LeftColumn: int - RightColumn: int - Text: string } - member x.Range = x.Line, x.LeftColumn, x.Line, x.RightColumn - -[<RequireQualifiedAccess>] -type SymbolLookupKind = - | Fuzzy - | ByRightColumn - | ByLongIdent - | Simple - -type internal DraftToken = - { Kind: SymbolKind - Token: FSharpTokenInfo - RightColumn: int } - static member inline Create kind token = - { Kind = kind; Token = token; RightColumn = token.LeftColumn + token.FullMatchedLength - 1 } - -type TokenisedLine = TokenisedLine of tokens:FSharpTokenInfo list * stateAtEOL:int64 - -module Lexer = - /// Get the array of all lex states in current source - let internal getLexStates defines (source: string) = - [| - /// Iterate through the whole line to get the final lex state - let rec loop (lineTokenizer: FSharpLineTokenizer) lexState = - match lineTokenizer.ScanToken lexState with - | None, newLexState -> newLexState - | Some _, newLexState -> - loop lineTokenizer newLexState - - let sourceTokenizer = FSharpSourceTokenizer(defines, None) - let lines = String.getLines source - let mutable lexState = 0L - for line in lines do - yield lexState - let lineTokenizer = sourceTokenizer.CreateLineTokenizer line - lexState <- loop lineTokenizer lexState - |] - - /// Provide a default implementation where we cache lex states of the current document. - /// Assume that current document will be queried repeatedly - /// Note: The source and defines are equality checked whenever this function is used which - /// means that currentDocumentState is rebuilt whenever a different source or defines list is presented - let queryLexState = - let mutable currentDocumentState = ref None - fun source defines line -> - let lexStates = - match !currentDocumentState with - | Some (lexStates, s, d) when s = source && d = defines -> - lexStates - // OPTIMIZE: if the new document has the current document as a prefix, - // we can reuse lexing results and process only the added part. - | _ -> - LoggingService.LogDebug "queryLexState: lexing current document" - let lexStates = getLexStates defines source - currentDocumentState := Some (lexStates, source, defines) - lexStates - Debug.Assert(line >= 0 && line < Array.length lexStates, "Should have lex states for every line.") - lexStates.[line] - - let singleLineQueryLexState _ _ _ = 0L - - /// Return all tokens of current line - let tokenizeLine source (args: string[]) line lineStr queryLexState = - let defines = - args |> Seq.choose (fun s -> if s.StartsWith "--define:" then Some s.[9..] else None) - |> Seq.toList - let sourceTokenizer = FSharpSourceTokenizer(defines, None) - let lineTokenizer = sourceTokenizer.CreateLineTokenizer lineStr - let rec loop lexState acc = - match lineTokenizer.ScanToken lexState with - | Some tok, state -> loop state (tok :: acc) - | _ -> List.rev acc - loop (queryLexState source defines line) [] - - let inline isIdentifier t = t.CharClass = FSharpTokenCharKind.Identifier - let inline isOperator t = t.ColorClass = FSharpTokenColorKind.Operator - let inline internal (|GenericTypeParameterPrefix|StaticallyResolvedTypeParameterPrefix|ActivePattern|Other|) ((token: FSharpTokenInfo), (lineStr:string)) = - if token.Tag = FSharpTokenTag.QUOTE then GenericTypeParameterPrefix - elif token.Tag = FSharpTokenTag.INFIX_AT_HAT_OP then - // The lexer return INFIX_AT_HAT_OP token for both "^" and "@" symbols. - // We have to check the char itself to distinguish one from another. - if token.FullMatchedLength = 1 && lineStr.[token.LeftColumn] = '^' then - StaticallyResolvedTypeParameterPrefix - else Other - elif token.Tag = FSharpTokenTag.LPAREN then - if token.FullMatchedLength = 1 && - lineStr.Length > token.LeftColumn+1 && - lineStr.[token.LeftColumn+1] = '|' then - ActivePattern - else Other - else Other - - // Operators: Filter out overlapped operators (>>= operator is tokenized as three distinct tokens: GREATER, GREATER, EQUALS. - // Each of them has FullMatchedLength = 3. So, we take the first GREATER and skip the other two). - // - // Generic type parameters: we convert QUOTE + IDENT tokens into single IDENT token, altering its LeftColumn - // and FullMathedLength (for "'type" which is tokenized as (QUOTE, left=2) + (IDENT, left=3, length=4) - // we'll get (IDENT, left=2, length=5). - // - // Statically resolved type parameters: we convert INFIX_AT_HAT_OP + IDENT tokens into single IDENT token, altering its LeftColumn - // and FullMathedLength (for "^type" which is tokenized as (INFIX_AT_HAT_OP, left=2) + (IDENT, left=3, length=4) - // we'll get (IDENT, left=2, length=5). - let internal fixTokens lineStr (tokens : FSharpTokenInfo list) = - tokens - |> List.fold (fun (acc, lastToken) token -> - match lastToken with - | Some t when token.LeftColumn <= t.RightColumn -> - acc, lastToken - | Some ( {Kind = SymbolKind.ActivePattern} as lastToken) when token.Tag = FSharpTokenTag.BAR || token.Tag = FSharpTokenTag.IDENT || token.Tag = FSharpTokenTag.UNDERSCORE -> - let mergedToken = - {lastToken.Token with Tag = FSharpTokenTag.IDENT - RightColumn = token.RightColumn - FullMatchedLength = lastToken.Token.FullMatchedLength + token.FullMatchedLength } - - acc, Some { lastToken with Token = mergedToken; RightColumn = lastToken.RightColumn + token.FullMatchedLength } - | _ -> - match token, lineStr with - | GenericTypeParameterPrefix -> acc, Some (DraftToken.Create GenericTypeParameter token) - | StaticallyResolvedTypeParameterPrefix -> acc, Some (DraftToken.Create StaticallyResolvedTypeParameter token) - | ActivePattern -> acc, Some (DraftToken.Create ActivePattern token) - | Other -> - let draftToken = - match lastToken with - | Some { Kind = GenericTypeParameter | StaticallyResolvedTypeParameter as kind } when isIdentifier token -> - DraftToken.Create kind { token with LeftColumn = token.LeftColumn - 1 - FullMatchedLength = token.FullMatchedLength + 1 } - | Some ( { Kind = SymbolKind.ActivePattern } as ap) when token.Tag = FSharpTokenTag.RPAREN -> - DraftToken.Create SymbolKind.Ident ap.Token - | _ -> - let kind = if isOperator token then Operator elif isIdentifier token then Ident else Other - DraftToken.Create kind token - draftToken :: acc, Some draftToken - ) ([], None) - |> fst - - - let getTokensWithInitialState state lines filename defines = - [ let mutable state = state - let sourceTok = FSharpSourceTokenizer(defines, filename) - for lineText in lines do - let tokenizer = sourceTok.CreateLineTokenizer(lineText) - let rec parseLine() = - [ match tokenizer.ScanToken(state) with - | Some(tok), nstate -> - state <- nstate - yield tok - yield! parseLine() - | None, nstate -> state <- nstate ] - yield parseLine(), lineText ] - - let findTokenAt col (tokens:FSharpTokenInfo list) = - let isTokenAtOffset col (t:FSharpTokenInfo) = col-1 >= t.LeftColumn && col-1 <= t.RightColumn - tokens |> List.tryFindBack (isTokenAtOffset col) - - let isNonTipToken token = - token.ColorClass = FSharpTokenColorKind.Comment || token.ColorClass = FSharpTokenColorKind.String || - (*token.ColorClass = FSharpTokenColorKind.Text ||*) token.ColorClass = FSharpTokenColorKind.InactiveCode - - // Returns symbol at a given position. - let getSymbolFromTokens (tokens: FSharpTokenInfo list) line col (lineStr: string) lookupKind: LexerSymbol option = - let tokens = fixTokens lineStr tokens - - // One or two tokens that in touch with the cursor (for "let x|(g) = ()" the tokens will be "x" and "(") - let tokensUnderCursor = - match lookupKind with - | SymbolLookupKind.Simple | SymbolLookupKind.Fuzzy -> - tokens |> List.filter (fun x -> x.Token.LeftColumn <= col && x.RightColumn + 1 >= col) - | SymbolLookupKind.ByRightColumn -> - tokens |> List.filter (fun x -> x.RightColumn = col) - | SymbolLookupKind.ByLongIdent -> - tokens |> List.filter (fun x -> x.Token.LeftColumn <= col) - - //printfn "Filtered tokens: %+A" tokensUnderCursor - match lookupKind with - | SymbolLookupKind.ByLongIdent -> - // Try to find start column of the long identifiers - // Assume that tokens are ordered in an decreasing order of start columns - let rec tryFindStartColumn tokens = - match tokens with - | {Kind = Ident; Token = t1} :: {Kind = Operator; Token = t2} :: remainingTokens -> - if t2.Tag = FSharpTokenTag.DOT then - tryFindStartColumn remainingTokens - else - Some t1.LeftColumn - | {Kind = Ident; Token = t} :: _ -> - Some t.LeftColumn - | {Kind = SymbolKind.Other; Token = t} :: _ when t.TokenName = "HASH" -> - Some t.LeftColumn - | _ :: _ | [] -> - None - let decreasingTokens = - match tokensUnderCursor |> List.sortBy (fun token -> - token.Token.LeftColumn) with - // Skip the first dot if it is the start of the identifier - | {Kind = Operator; Token = t} :: remainingTokens when t.Tag = FSharpTokenTag.DOT -> - remainingTokens - | newTokens -> newTokens - - match decreasingTokens with - | [] -> None - | [only] when only.Token.TokenName = "HASH" -> - Some - { Kind = SymbolKind.Other - Line = line - LeftColumn = only.Token.LeftColumn - RightColumn = only.Token.RightColumn - Text = lineStr } - | first :: _ -> - tryFindStartColumn decreasingTokens - |> Option.map (fun leftCol -> - { Kind = Ident - Line = line - LeftColumn = leftCol - RightColumn = first.RightColumn + 1 - Text = lineStr.[leftCol..first.RightColumn] }) - | SymbolLookupKind.Fuzzy - | SymbolLookupKind.ByRightColumn -> - // Select IDENT token. If failed, select OPERATOR token. - tokensUnderCursor - |> List.tryFind (fun { DraftToken.Kind = k } -> - match k with - | Ident | GenericTypeParameter | StaticallyResolvedTypeParameter -> true - | _ -> false) - |> Option.orTry (fun _ -> tokensUnderCursor |> List.tryFind (fun { DraftToken.Kind = k } -> k = Operator)) - |> Option.map (fun token -> - { Kind = token.Kind - Line = line - LeftColumn = token.Token.LeftColumn - RightColumn = token.RightColumn + 1 - Text = lineStr.Substring(token.Token.LeftColumn, token.Token.FullMatchedLength) }) - | SymbolLookupKind.Simple -> - tokensUnderCursor - |> List.tryLast - |> Option.map (fun token -> - { Kind = token.Kind - Line = line - LeftColumn = token.Token.LeftColumn - RightColumn = token.RightColumn + 1 - Text = lineStr.Substring(token.Token.LeftColumn, token.Token.FullMatchedLength) }) - - let getSymbol source line col lineStr lookupKind (args: string[]) queryLexState = - let tokens = tokenizeLine source args line lineStr queryLexState - try - getSymbolFromTokens tokens line col lineStr lookupKind - with e -> - LoggingService.LogInfo (sprintf "Getting lex symbols failed with %O" e) - None
\ No newline at end of file diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/MDLanguageService.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/MDLanguageService.fs index 50624f0832..a2317a4506 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/MDLanguageService.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/MDLanguageService.fs @@ -133,46 +133,33 @@ module MDLanguageServiceImpl = /// Various utilities for working with F# language service module internal ServiceUtils = - let map = - [ 0x0000, "md-class" - 0x0003, "md-enum" - 0x00012, "md-struct" - 0x00018, "md-struct" (* value type *) - 0x0002, "md-delegate" - 0x0008, "md-interface" - 0x000e, "md-module" (* module *) - 0x000f, "md-name-space" - 0x000c, "md-method"; - 0x000d, "md-method" (* method2 ? *) - 0x00011, "md-property" - 0x0005, "md-event" - 0x0007, "md-field" (* fieldblue ? *) - 0x0020, "md-field" (* fieldyellow ? *) - 0x0001, "md-field" (* const *) - 0x0004, "md-field" (* enummember *) - 0x0006, "md-exception" (* exception *) - 0x0009, "md-text-file-icon" (* TextLine *) - 0x000a, "md-regular-file" (* Script *) - 0x000b, "Script" (* Script2 *) - 0x0010, "md-tip-of-the-day" (* Formula *); - 0x00013, "md-class" (* Template *) - 0x00014, "md-class" (* Typedef *) - 0x00015, "md-type" (* Type *) - 0x00016, "md-type" (* Union *) - 0x00017, "md-field" (* Variable *) - 0x00019, "md-class" (* Intrinsic *) - 0x0001f, "md-breakpint" (* error *) - 0x00021, "md-misc-files" (* Misc1 *) - 0x0022, "md-misc-files" (* Misc2 *) - 0x00023, "md-misc-files" (* Misc3 *) ] |> Map.ofSeq - /// Translates icon code that we get from F# language service into a MonoDevelop icon let getIcon (navItem: FSharpNavigationDeclarationItem) = - match navItem.Kind with - | NamespaceDecl -> "md-name-space" - | _ -> match map.TryFind (navItem.Glyph / 6), map.TryFind (navItem.Glyph % 6) with - | Some(s), _ -> s // Is the second number good for anything? - | _, _ -> "md-breakpoint" + match navItem.Kind with + | NamespaceDecl -> "md-name-space" + | _ -> + match navItem.Glyph with + | FSharpGlyph.Class -> "md-class" + | FSharpGlyph.Enum -> "md-enum" + | FSharpGlyph.Struct -> "md-struct" + | FSharpGlyph.ExtensionMethod -> "md-struct" + | FSharpGlyph.Delegate -> "md-delegate" + | FSharpGlyph.Interface -> "md-interface" + | FSharpGlyph.Module -> "md-module" + | FSharpGlyph.NameSpace -> "md-name-space" + | FSharpGlyph.Method -> "md-method"; + | FSharpGlyph.OverridenMethod -> "md-method"; + | FSharpGlyph.Property -> "md-property" + | FSharpGlyph.Event -> "md-event" + | FSharpGlyph.Constant -> "md-field" + | FSharpGlyph.EnumMember -> "md-field" + | FSharpGlyph.Exception -> "md-exception" + | FSharpGlyph.Typedef -> "md-class" + | FSharpGlyph.Type -> "md-type" + | FSharpGlyph.Union -> "md-type" + | FSharpGlyph.Variable -> "md-field" + | FSharpGlyph.Field -> "md-field" + | FSharpGlyph.Error -> "md-breakpint" module internal KeywordList = let modifiers = @@ -270,4 +257,4 @@ Used in match expressions""" "<@", "Delimits a typed code quotation." "@>", "Delimits a typed code quotation." "<@@", "Delimits a untyped code quotation." - "@@>", "Delimits a untyped code quotation."]
\ No newline at end of file + "@@>", "Delimits a untyped code quotation."] diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/Parser.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/Parser.fs deleted file mode 100644 index d771dcc991..0000000000 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/Parser.fs +++ /dev/null @@ -1,36 +0,0 @@ -namespace MonoDevelop.FSharp - -open System - -// -------------------------------------------------------------------------------------- -/// Parsing utilities for IntelliSense (e.g. parse identifier on the left-hand side -/// of the current cursor location etc.) -module Parsing = - let inline private tryGetLexerSymbolIslands sym = - match sym.Text with "" -> None | _ -> Some (sym.RightColumn, sym.Text.Split '.' |> Array.toList) - - // Parsing - find the identifier around the current location - // (we look for full identifier in the backward direction, but only - // for a short identifier forward - this means that when you hover - // 'B' in 'A.B.C', you will get intellisense for 'A.B' module) - let findIdents col lineStr lookupType = - if lineStr = "" then None - else - Lexer.getSymbol lineStr 0 col lineStr lookupType [||] Lexer.singleLineQueryLexState - |> Option.bind tryGetLexerSymbolIslands - - let findLongIdentsAndResidue (col, lineStr:string) = - let lineStr = lineStr.Substring(0, col) - - match Lexer.getSymbol lineStr 0 col lineStr SymbolLookupKind.ByLongIdent [||] Lexer.singleLineQueryLexState with - | Some sym -> - match sym.Text with - | "" -> [], "" - | text -> - let res = text.Split '.' |> List.ofArray |> List.rev - if lineStr.[col - 1] = '.' then res |> List.rev, "" - else - match res with - | head :: tail -> tail |> List.rev, head - | [] -> [], "" - | _ -> [], "" diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpi.Service/MonoDevelop.FSharpInteractive.Service.fsproj b/main/external/fsharpbinding/MonoDevelop.FSharpi.Service/MonoDevelop.FSharpInteractive.Service.fsproj index cfda38b231..5393a539ea 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpi.Service/MonoDevelop.FSharpInteractive.Service.fsproj +++ b/main/external/fsharpbinding/MonoDevelop.FSharpi.Service/MonoDevelop.FSharpInteractive.Service.fsproj @@ -58,6 +58,7 @@ <ProjectReference Include="..\MonoDevelop.FSharp.Shared\MonoDevelop.FSharp.Shared.fsproj"> <Project>{AF5FEAD5-B50E-4F07-A274-32F23D5C504D}</Project> <Name>MonoDevelop.FSharp.Shared</Name> + <Private>false</Private> </ProjectReference> </ItemGroup> <ItemGroup> @@ -88,7 +89,7 @@ <ItemGroup> <Reference Include="ExtCore"> <HintPath>..\packages\ExtCore\lib\net45\ExtCore.dll</HintPath> - <Private>True</Private> + <Private>False</Private> <Paket>True</Paket> </Reference> </ItemGroup> @@ -99,12 +100,7 @@ <ItemGroup> <Reference Include="FSharp.Compiler.Service"> <HintPath>..\packages\FSharp.Compiler.Service\lib\net45\FSharp.Compiler.Service.dll</HintPath> - <Private>True</Private> - <Paket>True</Paket> - </Reference> - <Reference Include="FSharp.Compiler.Service.MSBuild.v12"> - <HintPath>..\packages\FSharp.Compiler.Service\lib\net45\FSharp.Compiler.Service.MSBuild.v12.dll</HintPath> - <Private>True</Private> + <Private>False</Private> <Paket>True</Paket> </Reference> </ItemGroup> diff --git a/main/external/fsharpbinding/paket.dependencies b/main/external/fsharpbinding/paket.dependencies index f114e340b1..0b42409733 100644 --- a/main/external/fsharpbinding/paket.dependencies +++ b/main/external/fsharpbinding/paket.dependencies @@ -2,9 +2,9 @@ framework: net461 source https://nuget.org/api/v2/ nuget ExtCore framework: >= net40 -nuget FSharp.Compiler.Service = 11.0.10 -nuget FSharp.Core = 4.1.0.2 -nuget System.ValueTuple = 4.3.0 +nuget FSharp.Compiler.Service +nuget FSharp.Core +nuget System.ValueTuple nuget Fantomas framework: >= net45 nuget FSharp.Compiler.CodeDom 0.9.2 framework: >= net40 nuget Mono.Cecil framework: >= net40 diff --git a/main/external/fsharpbinding/paket.lock b/main/external/fsharpbinding/paket.lock index af1ae03513..87d45973b1 100644 --- a/main/external/fsharpbinding/paket.lock +++ b/main/external/fsharpbinding/paket.lock @@ -6,15 +6,15 @@ NUGET Fantomas (2.6.1) FSharp.Compiler.Service (>= 11.0.4) FSharp.Compiler.CodeDom (0.9.2) - FSharp.Compiler.Service (11.0.10) - System.Collections.Immutable (>= 1.2) + FSharp.Compiler.Service (13.0.0) + System.Collections.Immutable (>= 1.3.1) System.Reflection.Metadata (>= 1.4.2) FSharp.Core (4.1.0.2) System.ValueTuple (>= 4.3) Mono.Cecil (0.9.6.4) Newtonsoft.Json (10.0.1) - StrongNamer (0.0.3) + StrongNamer (0.0.6) System.Collections.Immutable (1.3.1) System.Reflection.Metadata (1.4.2) System.Collections.Immutable (>= 1.3.1) - System.ValueTuple (4.3) + System.ValueTuple (4.3.1) diff --git a/main/external/xwt b/main/external/xwt -Subproject ed38bed205a19fbc90dd129a9ded7c6694589b3 +Subproject e15875277c731151ac0cd9e5c5796662b38efa7 diff --git a/main/src/addins/AspNet/Templates/MvcCommon/_Layout.cshtml b/main/src/addins/AspNet/Templates/MvcCommon/_Layout.cshtml index 547f680145..2843df700f 100644 --- a/main/src/addins/AspNet/Templates/MvcCommon/_Layout.cshtml +++ b/main/src/addins/AspNet/Templates/MvcCommon/_Layout.cshtml @@ -2,6 +2,7 @@ <html>
<head>
<title>@ViewBag.Title</title>
+ <meta charset="utf-8" />
</head>
<body>
@RenderBody()
diff --git a/main/src/addins/CSharpBinding/CSharpBinding.csproj b/main/src/addins/CSharpBinding/CSharpBinding.csproj index cf8543b3a4..2a2746c11d 100644 --- a/main/src/addins/CSharpBinding/CSharpBinding.csproj +++ b/main/src/addins/CSharpBinding/CSharpBinding.csproj @@ -168,7 +168,7 @@ <Private>False</Private> </Reference> <Reference Include="System.ValueTuple"> - <HintPath>..\..\..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath> + <HintPath>..\..\..\packages\System.ValueTuple.4.3.1\lib\netstandard1.0\System.ValueTuple.dll</HintPath> <Private>False</Private> </Reference> </ItemGroup> diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/RoslynCodeCompletionFactory.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/RoslynCodeCompletionFactory.cs index 4cd34d87c6..6104167644 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/RoslynCodeCompletionFactory.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/RoslynCodeCompletionFactory.cs @@ -112,8 +112,7 @@ namespace MonoDevelop.CSharp.Completion bool runCompletionCompletionCommand = false; var method = Symbol as IMethodSymbol; - bool addParens = IdeApp.Preferences.AddParenthesesAfterCompletion; - bool addOpeningOnly = IdeApp.Preferences.AddOpeningOnly; + bool addParens = DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket; var Editor = ext.Editor; var Policy = ext.FormattingPolicy; string insertionText = this.CompletionText; @@ -127,11 +126,7 @@ namespace MonoDevelop.CSharp.Completion var keys = new [] { SpecialKey.Return, SpecialKey.Tab, SpecialKey.Space }; if (keys.Contains (descriptor.SpecialKey) || descriptor.KeyChar == ' ') { - if (addOpeningOnly) { - insertionText += addSpace ? " (|" : "(|"; - } else { - insertionText += addSpace ? " (|)" : "(|)"; - } + insertionText += addSpace ? " (|)" : "(|)"; } ka |= KeyActions.Ignore; } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/RoslynSymbolCompletionData.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/RoslynSymbolCompletionData.cs index 37ed523e58..b1c19494f9 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/RoslynSymbolCompletionData.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/RoslynSymbolCompletionData.cs @@ -185,7 +185,7 @@ namespace MonoDevelop.CSharp.Completion replaceLength = partialWordLength; } int endOffset = Math.Min (window.StartOffset + replaceLength, window.CompletionWidget.TextLength); - if (descriptor.KeyChar == '(' && IdeApp.Preferences.AddParenthesesAfterCompletion) { + if (descriptor.KeyChar == '(' && DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket) { endOffset++; if (DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket) endOffset++; @@ -201,8 +201,7 @@ namespace MonoDevelop.CSharp.Completion bool runCompletionCompletionCommand = false; var method = Symbol as IMethodSymbol; - bool addParens = IdeApp.Preferences.AddParenthesesAfterCompletion; - bool addOpeningOnly = IdeApp.Preferences.AddOpeningOnly; + bool addParens = DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket; var Editor = ext.Editor; var Policy = ext.FormattingPolicy; var ctx = window.CodeCompletionContext; @@ -231,66 +230,56 @@ namespace MonoDevelop.CSharp.Completion var keys = new [] { SpecialKey.Return, SpecialKey.Tab, SpecialKey.Space }; if (keys.Contains (descriptor.SpecialKey) || descriptor.KeyChar == '.' || descriptor.KeyChar == '(') { if (HasAnyOverloadWithParameters (method)) { - if (addOpeningOnly) { - insertionText += RequireGenerics (method) ? "<|" : (addSpace ? " (|" : "(|"); + if (descriptor.KeyChar == '.') { + if (RequireGenerics (method)) { + insertionText += addSpace ? "<> ()" : "<>()"; + } else { + insertionText += addSpace ? " ()" : "()"; + } skipChars = 0; } else { - if (descriptor.KeyChar == '.') { + if (insertSemicolon) { if (RequireGenerics (method)) { - insertionText += addSpace ? "<> ()" : "<>()"; + insertionText += addSpace ? "<|> ();" : "<|>();"; + skipChars = addSpace ? 5 : 4; } else { - insertionText += addSpace ? " ()" : "()"; + insertionText += addSpace ? " (|);" : "(|);"; + skipChars = 2; } - skipChars = 0; } else { - if (insertSemicolon) { - if (RequireGenerics (method)) { - insertionText += addSpace ? "<|> ();" : "<|>();"; - skipChars = addSpace ? 5 : 4; - } else { - insertionText += addSpace ? " (|);" : "(|);"; - skipChars = 2; - } + if (RequireGenerics (method)) { + insertionText += addSpace ? "<|> ()" : "<|>()"; + skipChars = addSpace ? 4 : 3; } else { - if (RequireGenerics (method)) { - insertionText += addSpace ? "<|> ()" : "<|>()"; - skipChars = addSpace ? 4 : 3; - } else { - insertionText += addSpace ? " (|)" : "(|)"; - skipChars = 1; - } + insertionText += addSpace ? " (|)" : "(|)"; + skipChars = 1; } } } runParameterCompletionCommand = true; } else { - if (addOpeningOnly) { - insertionText += RequireGenerics (method) ? "<|" : (addSpace ? " (|" : "(|"); + if (descriptor.KeyChar == '.') { + if (RequireGenerics (method)) { + insertionText += addSpace ? "<> ()" : "<>()"; + } else { + insertionText += addSpace ? " ()" : "()"; + } skipChars = 0; } else { - if (descriptor.KeyChar == '.') { + if (insertSemicolon) { if (RequireGenerics (method)) { - insertionText += addSpace ? "<> ()" : "<>()"; + insertionText += addSpace ? "<|> ();" : "<|>();"; } else { - insertionText += addSpace ? " ()" : "()"; + insertionText += addSpace ? " ();|" : "();|"; } - skipChars = 0; - } else { - if (insertSemicolon) { - if (RequireGenerics (method)) { - insertionText += addSpace ? "<|> ();" : "<|>();"; - } else { - insertionText += addSpace ? " ();|" : "();|"; - } + } else { + if (RequireGenerics (method)) { + insertionText += addSpace ? "<|> ()" : "<|>()"; } else { - if (RequireGenerics (method)) { - insertionText += addSpace ? "<|> ()" : "<|>()"; - } else { - insertionText += addSpace ? " ()|" : "()|"; - } - + insertionText += addSpace ? " ()|" : "()|"; } + } } } @@ -303,7 +292,7 @@ namespace MonoDevelop.CSharp.Completion } if ((DisplayFlags & DisplayFlags.NamedArgument) == DisplayFlags.NamedArgument && - IdeApp.Preferences.AddParenthesesAfterCompletion && + DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket && (descriptor.SpecialKey == SpecialKey.Tab || descriptor.SpecialKey == SpecialKey.Return || descriptor.SpecialKey == SpecialKey.Space)) { diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/RoslynRecommendationsCompletionContextHandler.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/RoslynRecommendationsCompletionContextHandler.cs index b176c2dba1..ba91548b2f 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/RoslynRecommendationsCompletionContextHandler.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/RoslynRecommendationsCompletionContextHandler.cs @@ -105,7 +105,11 @@ namespace ICSharpCode.NRefactory6.CSharp.Completion if (isInAttribute) { var type = (ITypeSymbol)symbol; if (type.IsAttribute ()) { - var v = type.Name.Substring (0, type.Name.Length - "Attribute".Length); + const string attributeSuffix = "Attribute"; + var v = type.Name.EndsWith (attributeSuffix, StringComparison.Ordinal) + ? type.Name.Substring (0, type.Name.Length - attributeSuffix.Length) + : type.Name; + var needsEscaping = SyntaxFacts.GetKeywordKind(v) != SyntaxKind.None; needsEscaping = needsEscaping || (isInQuery && SyntaxFacts.IsQueryContextualKeyword(SyntaxFacts.GetContextualKeywordKind(v))); if (!needsEscaping) { diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CodeGenerationPanel.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CodeGenerationPanel.cs index a651062891..ded7b3db7d 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CodeGenerationPanel.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CodeGenerationPanel.cs @@ -58,6 +58,7 @@ namespace MonoDevelop.CSharp.Project void SetupAccessibility () { + label81.Accessible.Role = Atk.Role.Filler; generateOverflowChecksCheckButton.SetCommonAccessibilityAttributes ("CompilerOptions.OverflowChecks", "", GettextCatalog.GetString ("Check this to enable overflow checking")); enableOptimizationCheckButton.SetCommonAccessibilityAttributes ("CompilerOptions.Optimizations", "", diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CompilerOptionsPanelWidget.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CompilerOptionsPanelWidget.cs index f2f6370aa1..e7c6da4235 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CompilerOptionsPanelWidget.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Project/CompilerOptionsPanelWidget.cs @@ -58,16 +58,7 @@ namespace MonoDevelop.CSharp.Project CSharpCompilerParameters compilerParameters = (CSharpCompilerParameters) configuration.CompilationParameters; var csproject = (CSharpProject)project; - ListStore store = new ListStore (typeof (string));
- store.AppendValues (GettextCatalog.GetString ("Executable"));
- store.AppendValues (GettextCatalog.GetString ("Library")); - store.AppendValues (GettextCatalog.GetString ("Executable with GUI"));
- store.AppendValues (GettextCatalog.GetString ("Module"));
- compileTargetCombo.Model = store;
- CellRendererText cr = new CellRendererText ();
- compileTargetCombo.PackStart (cr, true);
- compileTargetCombo.AddAttribute (cr, "text", 0);
- compileTargetCombo.Active = (int) configuration.CompileTarget;
+ compileTargetCombo.CompileTarget = configuration.CompileTarget;
compileTargetCombo.Changed += new EventHandler (OnTargetChanged); if (project.IsLibraryBasedProjectType) { @@ -131,6 +122,7 @@ namespace MonoDevelop.CSharp.Project void SetupAccessibility () { + label76.Accessible.Role = Atk.Role.Filler; compileTargetCombo.SetCommonAccessibilityAttributes ("CodeGeneration.CompileTarget", label86, GettextCatalog.GetString ("Select the compile target for the code generation")); @@ -178,7 +170,6 @@ namespace MonoDevelop.CSharp.Project public void Store (ItemConfigurationCollection<ItemConfiguration> configs) { int codePage; - var compileTarget = (CompileTarget) compileTargetCombo.Active; var langVersion = LanguageVersion.Default; TreeIter iter; @@ -207,7 +198,7 @@ namespace MonoDevelop.CSharp.Project } else codePage = 0; - project.CompileTarget = compileTarget; + project.CompileTarget = compileTargetCombo.CompileTarget; var csproject = (CSharpProject)project; @@ -233,7 +224,7 @@ namespace MonoDevelop.CSharp.Project void UpdateTarget ()
{
- if ((CompileTarget) compileTargetCombo.Active == CompileTarget.Library) {
+ if (compileTargetCombo.CompileTarget == CompileTarget.Library) {
iconEntry.Sensitive = false;
} else {
iconEntry.Sensitive = true;
diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/CSharpFindReferencesProvider.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/CSharpFindReferencesProvider.cs index 0e455c79cc..3d4ad63add 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/CSharpFindReferencesProvider.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/CSharpFindReferencesProvider.cs @@ -48,7 +48,7 @@ namespace MonoDevelop.CSharp.Refactoring { public static LookupResult Failure = new LookupResult (); - public bool Success { get; private set; } + public bool Success { get; private set; } public ISymbol Symbol { get; private set; } public Solution Solution { get; private set; } public MonoDevelop.Projects.Project MonoDevelopProject { get; internal set; } @@ -71,8 +71,8 @@ namespace MonoDevelop.CSharp.Refactoring { if (string.IsNullOrEmpty (documentationCommentId)) return LookupResult.Failure; - bool searchNs = documentationCommentId[0] == 'N'; - bool searchType = documentationCommentId[0] == 'T'; + bool searchNs = documentationCommentId [0] == 'N'; + bool searchType = documentationCommentId [0] == 'T'; int reminderIndex = 2; var comp = await prj.GetCompilationAsync (token).ConfigureAwait (false); return await Task.Run (() => { @@ -101,7 +101,7 @@ namespace MonoDevelop.CSharp.Refactoring foreach (var member in type.GetMembers ()) { if (token.IsCancellationRequested) return LookupResult.Failure; -
+ if (member.GetDocumentationCommentId () == documentationCommentId) {
return new LookupResult (member, prj.Solution, comp);
}
@@ -163,14 +163,14 @@ namespace MonoDevelop.CSharp.Refactoring foreach (var subType in current.GetTypeMembers ()) { if (token.IsCancellationRequested) return null; - - var child = LookupType (documentationCommentId, idx + 1, subType, token); + + var child = LookupType (documentationCommentId, idx + 1, subType, token); if (child != null) { return child; } } return current; - + } return null; } @@ -182,10 +182,10 @@ namespace MonoDevelop.CSharp.Refactoring foreach (var subNamespace in current.GetNamespaceMembers ()) { if (token.IsCancellationRequested) return null; - + if (exact) { if (subNamespace.Name.Length == documentationCommentId.Length - reminder && - string.CompareOrdinal (documentationCommentId, reminder, subNamespace.Name, 0, subNamespace.Name.Length) == 0) + string.CompareOrdinal (documentationCommentId, reminder, subNamespace.Name, 0, subNamespace.Name.Length) == 0) return subNamespace; } else { if (subNamespace.Name.Length < documentationCommentId.Length - reminder - 1 && @@ -206,9 +206,9 @@ namespace MonoDevelop.CSharp.Refactoring var result = new List<SearchResult> (); var antiDuplicatesSet = new HashSet<SearchResult> (new SearchResultComparer ()); var lookup = await TryLookupSymbol (documentationCommentId, hintProject, token); - if (lookup == null || !lookup.Success) + 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> (); @@ -282,41 +282,50 @@ namespace MonoDevelop.CSharp.Refactoring 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 sym in SymbolFinder.FindSimilarSymbols (curSymbol, lookup.Compilation)) { - foreach (var simSym in await GatherSymbols (sym, lookup.Solution, token)) { - 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; - } - - var sr = new SearchResult (new FileProvider (fileName), offset, loc.Location.SourceSpan.Length); - if (antiDuplicatesSet.Add (sr)) { - result.Add (sr); - } - } + if (lookup.Symbol.Kind == SymbolKind.Method) { + foreach (var curSymbol in lookup.Symbol.ContainingType.GetMembers ().Where (m => m.Kind == lookup.Symbol.Kind && m.Name == lookup.Symbol.Name)) { + foreach (var sym in SymbolFinder.FindSimilarSymbols (curSymbol, lookup.Compilation)) { + foreach (var simSym in await GatherSymbols (sym, lookup.Solution, token)) { + await FindSymbolReferencesAsync (antiDuplicatesSet, result, lookup, workspace, simSym); } } } + } else { + await FindSymbolReferencesAsync (antiDuplicatesSet, result, lookup, workspace, lookup.Symbol); } return (IEnumerable<SearchResult>)result; }); } + + static async Task FindSymbolReferencesAsync (HashSet<SearchResult> antiDuplicatesSet, List<SearchResult> result, LookupResult lookup, MonoDevelopWorkspace workspace, ISymbol simSym) + { + 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; + } + + 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/CSharpBinding/gtk-gui/MonoDevelop.CSharp.Project.CompilerOptionsPanelWidget.cs b/main/src/addins/CSharpBinding/gtk-gui/MonoDevelop.CSharp.Project.CompilerOptionsPanelWidget.cs index 9c54345a54..07dd324940 100644 --- a/main/src/addins/CSharpBinding/gtk-gui/MonoDevelop.CSharp.Project.CompilerOptionsPanelWidget.cs +++ b/main/src/addins/CSharpBinding/gtk-gui/MonoDevelop.CSharp.Project.CompilerOptionsPanelWidget.cs @@ -20,7 +20,7 @@ namespace MonoDevelop.CSharp.Project private global::Gtk.HBox hbox57; - private global::Gtk.ComboBox compileTargetCombo; + private MonoDevelop.Ide.Gui.OptionPanels.DotNetCompileTargetSelector compileTargetCombo; private global::MonoDevelop.Components.FileEntry iconEntry; @@ -112,7 +112,7 @@ namespace MonoDevelop.CSharp.Project this.hbox57 = new global::Gtk.HBox (); this.hbox57.Name = "hbox57"; // Container child hbox57.Gtk.Box+BoxChild - this.compileTargetCombo = new global::Gtk.ComboBox (); + this.compileTargetCombo = new MonoDevelop.Ide.Gui.OptionPanels.DotNetCompileTargetSelector(); this.compileTargetCombo.Name = "compileTargetCombo"; this.hbox57.Add (this.compileTargetCombo); global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.hbox57 [this.compileTargetCombo])); diff --git a/main/src/addins/CSharpBinding/gtk-gui/gui.stetic b/main/src/addins/CSharpBinding/gtk-gui/gui.stetic index 5f3d55580e..09142aa1e5 100644 --- a/main/src/addins/CSharpBinding/gtk-gui/gui.stetic +++ b/main/src/addins/CSharpBinding/gtk-gui/gui.stetic @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <stetic-interface> <configuration> <images-root-path>..</images-root-path> @@ -589,7 +589,7 @@ None</property> <widget class="Gtk.HBox" id="hbox57"> <property name="MemberName" /> <child> - <widget class="Gtk.ComboBox" id="compileTargetCombo"> + <widget class="MonoDevelop.Ide.Gui.OptionPanels.DotNetCompileTargetSelector" id="compileTargetCombo"> <property name="MemberName" /> <property name="IsTextCombo">False</property> <property name="Items" /> @@ -1674,4 +1674,4 @@ None</property> </widget> </child> </widget> -</stetic-interface>
\ No newline at end of file +</stetic-interface> diff --git a/main/src/addins/CSharpBinding/packages.config b/main/src/addins/CSharpBinding/packages.config index 8c56e0c54c..9958f16fbb 100644 --- a/main/src/addins/CSharpBinding/packages.config +++ b/main/src/addins/CSharpBinding/packages.config @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="System.ValueTuple" version="4.3.0" targetFramework="net461" /> + <package id="System.ValueTuple" version="4.3.1" targetFramework="net461" /> </packages>
\ No newline at end of file diff --git a/main/src/addins/MacPlatform/MacPlatform.cs b/main/src/addins/MacPlatform/MacPlatform.cs index 3f8f857cb7..42b47fc36b 100644 --- a/main/src/addins/MacPlatform/MacPlatform.cs +++ b/main/src/addins/MacPlatform/MacPlatform.cs @@ -174,7 +174,8 @@ namespace MonoDevelop.MacIntegration var keyboardMode = NSUserDefaults.StandardUserDefaults.IntForKey ("AppleKeyboardUIMode"); // 0 - Text boxes and lists only // 2 - All controls - if (keyboardMode == 2) { + // 3 - All controls + keyboard access + if (keyboardMode != 0) { Gtk.Rc.ParseString ("style \"default\" { engine \"xamarin\" { focusstyle = 2 } }"); Gtk.Rc.ParseString ("style \"radio-or-check-box\" { engine \"xamarin\" { focusstyle = 2 } } "); } diff --git a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.csproj b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.csproj index cca9a4aa83..0db8172cb0 100644 --- a/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.csproj +++ b/main/src/addins/MonoDevelop.AspNetCore/MonoDevelop.AspNetCore.csproj @@ -175,6 +175,6 @@ <Version>$(TemplatesVersion)</Version> </NuGetPackage> </ItemGroup> - <Copy SourceFiles="..\..\..\packages\%(NuGetPackage.Identity).%(NuGetPackage.Version)\%(NuGetPackage.Identity).%(NuGetPackage.Version).nupkg" DestinationFolder="$(OutputPath)\Templates" /> + <Copy SourceFiles="..\..\..\packages\%(NuGetPackage.Identity).%(NuGetPackage.Version)\%(NuGetPackage.Identity).%(NuGetPackage.Version).nupkg" DestinationFolder="$(OutputPath)\Templates" SkipUnchangedFiles="true" /> </Target> </Project>
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.csproj b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.csproj index 5379281ee3..51fdd1a28c 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.csproj +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.csproj @@ -201,6 +201,7 @@ <Compile Include="gtk-gui\MonoDevelop.Debugger.DebugApplicationDialog.cs" /> <Compile Include="MonoDevelop.Debugger\DebugApplicationDialog.cs" /> <Compile Include="MonoDevelop.Debugger\Styles.cs" /> + <Compile Include="MonoDevelop.Debugger\ProcessAttacher.cs" /> </ItemGroup> <ItemGroup> <EmbeddedResource Include="MonoDevelop.Debugger.addin.xml"> diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/AttachToProcessDialog.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/AttachToProcessDialog.cs index 0b95d4c645..e77429f1ef 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/AttachToProcessDialog.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/AttachToProcessDialog.cs @@ -32,35 +32,36 @@ using MonoDevelop.Components; using Mono.Debugging.Client; using MonoDevelop.Ide.Gui; using System.Threading; +using System.Linq; +using MonoDevelop.Projects; +using MonoDevelop.Core.Execution; +using MonoDevelop.Ide; namespace MonoDevelop.Debugger { public partial class AttachToProcessDialog : Gtk.Dialog { - List<DebuggerEngine> currentDebEngines; - Dictionary<long, List<DebuggerEngine>> procEngines; - List<ProcessInfo> procs; + List<DebuggerEngine> debugEngines = new List<DebuggerEngine> (); + DebuggerEngine selectedEngine; + ProcessInfo [] procs; Gtk.ListStore store; TreeViewState state; - bool closed; + ProcessAttacher processAttacher; + CancellationTokenSource refreshLoopTokenSource = new CancellationTokenSource (); - public AttachToProcessDialog() + public AttachToProcessDialog () { - this.Build(); + this.Build (); - store = new Gtk.ListStore (typeof(ProcessInfo), typeof(string), typeof(string)); + store = new Gtk.ListStore (typeof (ProcessInfo), typeof (string), typeof (string), typeof (string)); tree.Model = store; tree.AppendColumn ("PID", new Gtk.CellRendererText (), "text", 1); - tree.AppendColumn (GettextCatalog.GetString ("Process Name"), new Gtk.CellRendererText (), "text", 2); + tree.AppendColumn (GettextCatalog.GetString ("Name"), new Gtk.CellRendererText (), "text", 2); + tree.AppendColumn (GettextCatalog.GetString ("Description"), new Gtk.CellRendererText (), "text", 3); tree.RowActivated += OnRowActivated; state = new TreeViewState (tree, 1); - var refreshThread = new Thread (new ThreadStart (Refresh)); - refreshThread.IsBackground = true; - refreshThread.Start (); - - comboDebs.Sensitive = false; buttonOk.Sensitive = false; tree.Selection.UnselectAll (); tree.Selection.Changed += OnSelectionChanged; @@ -68,41 +69,90 @@ namespace MonoDevelop.Debugger Gtk.TreeIter it; if (store.GetIterFirst (out it)) tree.Selection.SelectIter (it); + + //Logic below tries to CreateExecutionCommand which is used to determine default debug engine + var startupConfig = IdeApp.ProjectOperations.CurrentSelectedSolution?.StartupConfiguration as SingleItemSolutionRunConfiguration; + ExecutionCommand executionCommand = null; + if (startupConfig?.Item is DotNetProject dnp) { + var config = dnp.GetConfiguration (IdeApp.Workspace.ActiveConfiguration) as DotNetProjectConfiguration; + var runProjectConfiguration = startupConfig.RunConfiguration as ProjectRunConfiguration ?? dnp.GetDefaultRunConfiguration () as ProjectRunConfiguration; + if (config != null) { + executionCommand = dnp.CreateExecutionCommand (IdeApp.Workspace.ActiveConfiguration, config, runProjectConfiguration); + } + } + DebuggerEngine defaultEngine = null; + foreach (DebuggerEngine de in DebuggingService.GetDebuggerEngines ()) { + if ((de.SupportedFeatures & DebuggerFeatures.Attaching) == 0) + continue; + if (executionCommand != null && de.CanDebugCommand (executionCommand)) + defaultEngine = de; + debugEngines.Add (de); + comboDebs.AppendText (de.Name); + } + if (!debugEngines.Any ()) + return; + if (defaultEngine == null) + defaultEngine = debugEngines.First (); + comboDebs.Active = debugEngines.IndexOf (defaultEngine); + ChangeEngine (defaultEngine); + comboDebs.Changed += delegate { + ChangeEngine (debugEngines [comboDebs.Active]); + }; + } + + private void ChangeEngine (DebuggerEngine newEngine) + { + if (selectedEngine == newEngine) + return; + selectedEngine = newEngine; + + refreshLoopTokenSource.Cancel (); + refreshLoopTokenSource = new CancellationTokenSource (); + + if (processAttacher != null) { + processAttacher.AttachableProcessesChanged -= ProcessAttacher_AttachableProcessesChanged; + processAttacher.Dispose (); + } + + processAttacher = selectedEngine.GetProcessAttacher (); + if (processAttacher != null) { + processAttacher.AttachableProcessesChanged += ProcessAttacher_AttachableProcessesChanged; + this.procs = processAttacher.GetAttachableProcesses (); + Runtime.RunInMainThread (new Action (FillList)).Ignore (); + } else { + var refreshThread = new Thread (new ParameterizedThreadStart (Refresh)); + refreshThread.IsBackground = true; + refreshThread.Start (refreshLoopTokenSource.Token); + } + } + + void ProcessAttacher_AttachableProcessesChanged (Debugger.ProcessAttacher sender) + { + this.procs = sender.GetAttachableProcesses (); + Runtime.RunInMainThread (new Action (FillList)).Ignore (); } public override void Destroy () { - closed = true; + if (processAttacher != null) { + processAttacher.AttachableProcessesChanged -= ProcessAttacher_AttachableProcessesChanged; + processAttacher.Dispose (); + } + refreshLoopTokenSource.Cancel (); base.Destroy (); } - void Refresh () + void Refresh (object tokenObject) { - while (!closed) { - var procEngines = new Dictionary<long, List<DebuggerEngine>> (); - var procs = new List<ProcessInfo> (); - - foreach (DebuggerEngine de in DebuggingService.GetDebuggerEngines ()) { - if ((de.SupportedFeatures & DebuggerFeatures.Attaching) == 0) - continue; - try { - var infos = de.GetAttachableProcesses (); - foreach (ProcessInfo pi in infos) { - List<DebuggerEngine> engs; - if (!procEngines.TryGetValue (pi.Id, out engs)) { - engs = new List<DebuggerEngine> (); - procEngines [pi.Id] = engs; - procs.Add (pi); - } - engs.Add (de); - } - } catch (Exception ex) { - LoggingService.LogError ("Could not get attachable processes.", ex); - } + var token = (CancellationToken)tokenObject; + var engine = selectedEngine; + while (!token.IsCancellationRequested) { + try { + this.procs = engine.GetAttachableProcesses (); + } catch (Exception ex) { + LoggingService.LogError ("Could not get attachable processes.", ex); } - this.procEngines = procEngines; - this.procs = procs; - Runtime.RunInMainThread (new Action(FillList)).Ignore (); + Runtime.RunInMainThread (new Action (FillList)).Ignore (); Thread.Sleep (3000); } } @@ -113,13 +163,21 @@ namespace MonoDevelop.Debugger tree.Model = null; store.Clear (); string filter = entryFilter.Text; + bool anyPidSet = false; + bool anyDescriptionSet = false; foreach (ProcessInfo pi in procs) { - if (filter.Length == 0 || pi.Id.ToString().Contains (filter) || pi.Name.Contains (filter)) - store.AppendValues (pi, pi.Id.ToString (), pi.Name); + if (pi.Id != 0) + anyPidSet = true; + if (pi.Description != null) + anyDescriptionSet = true; + if (filter.Length == 0 || (pi.Id != 0 && pi.Id.ToString ().Contains (filter)) || pi.Name.Contains (filter) || (pi.Description?.Contains (filter) ?? false)) + store.AppendValues (pi, pi.Id.ToString (), pi.Name, pi.Description); } + tree.Columns [0].Visible = anyPidSet; + tree.Columns [2].Visible = anyDescriptionSet; tree.Model = store; state.Load (); - + tree.ColumnsAutosize (); if (tree.Selection.CountSelectedRows () == 0) { Gtk.TreeIter it; if (store.GetIterFirst (out it)) @@ -129,21 +187,10 @@ namespace MonoDevelop.Debugger void OnSelectionChanged (object s, EventArgs args) { - ((Gtk.ListStore)comboDebs.Model).Clear (); - Gtk.TreeIter iter; if (tree.Selection.GetSelected (out iter)) { - ProcessInfo pi = (ProcessInfo) store.GetValue (iter, 0); - currentDebEngines = procEngines [pi.Id]; - foreach (DebuggerEngine de in currentDebEngines) { - comboDebs.AppendText (de.Name); - } - comboDebs.Sensitive = true; - buttonOk.Sensitive = currentDebEngines.Count > 0; - comboDebs.Active = 0; - } - else { - comboDebs.Sensitive = false; + buttonOk.Sensitive = true; + } else { buttonOk.Sensitive = false; } } @@ -162,13 +209,13 @@ namespace MonoDevelop.Debugger get { Gtk.TreeIter iter; tree.Selection.GetSelected (out iter); - return (ProcessInfo) store.GetValue (iter, 0); + return (ProcessInfo)store.GetValue (iter, 0); } } public DebuggerEngine SelectedDebugger { get { - return currentDebEngines [comboDebs.Active]; + return selectedEngine; } } } diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/BreakpointPropertiesDialog.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/BreakpointPropertiesDialog.cs index dca6dac7f8..8727d98594 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/BreakpointPropertiesDialog.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/BreakpointPropertiesDialog.cs @@ -54,7 +54,7 @@ namespace MonoDevelop.Debugger Catchpoint } - sealed class BreakpointPropertiesDialog : Dialog + sealed class BreakpointPropertiesDialog : Xwt.Dialog { // For button sensitivity. DialogButton buttonOk; @@ -121,6 +121,7 @@ namespace MonoDevelop.Debugger Task.Run (LoadExceptionList); Initialize (); SetInitialData (); + SetAccessibility (); SetLayout (); if (be == null) { switch (breakpointType) { @@ -649,18 +650,108 @@ namespace MonoDevelop.Debugger return be; } + void SetAccessibility () + { + var accessible = breakpointActionPause.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.Pause"; + accessible.Description = GettextCatalog.GetString ("Cause the program to pause when the breakpoint is hit"); + + accessible = breakpointActionPrint.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.Print"; + accessible.Description = GettextCatalog.GetString ("Cause the program to print a message and continue when the breakpoint is hit"); + + accessible = entryPrintExpression.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.PrintExpression"; + accessible.Label = GettextCatalog.GetString ("Breakpoint Expression"); + accessible.Description = GettextCatalog.GetString ("Enter the expression you wish to have printed to the console. Place simple C# expressions within {} to interpolate them."); + + accessible = warningPrintExpression.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.WarningPrintExpression"; + accessible.Description = GettextCatalog.GetString ("There is a warning for the print expression"); + + accessible = stopOnFunction.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.StopOnFunction"; + accessible.Description = GettextCatalog.GetString ("Execute the action when a function is entered"); + + accessible = entryFunctionName.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.FunctionName"; + accessible.Label = GettextCatalog.GetString ("Breakpoint Function"); + accessible.Description = GettextCatalog.GetString ("Enter the name of the breakpoint function"); + + accessible = warningFunction.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.WarningFunction"; + accessible.Description = GettextCatalog.GetString ("There is a warning for the function name"); + + accessible = stopOnException.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.StopOnException"; + accessible.Description = GettextCatalog.GetString ("Execute the action when an exception is thrown"); + + accessible = entryExceptionType.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.ExceptionType"; + accessible.Label = GettextCatalog.GetString ("Breakpoint Exception"); + accessible.Description = GettextCatalog.GetString ("Enter the type of the breakpoint exception"); + + accessible = warningException.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.WarningException"; + accessible.Description = GettextCatalog.GetString ("There is a warning for the exception type"); + + accessible = checkIncludeSubclass.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.IncludeSubclasses"; + accessible.Description = GettextCatalog.GetString ("Select whether to also break on exception subclasses"); + + accessible = stopOnLocation.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.StopOnLocation"; + accessible.Description = GettextCatalog.GetString ("Execute the action when the program reaches a location in a file"); + + accessible = entryLocationFile.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.FileLocation"; + accessible.Label = GettextCatalog.GetString ("Breakpoint Location"); + accessible.Description = GettextCatalog.GetString ("Enter the file and line number of the breakpoint location"); + + accessible = warningLocation.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.WarningLocation"; + accessible.Description = GettextCatalog.GetString ("There is a warning for the breakpoint location"); + + accessible = ignoreHitType.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.HitType"; + accessible.Label = GettextCatalog.GetString ("Breakpoint Hit Count Type"); + accessible.Description = GettextCatalog.GetString ("Select a hit count condition for this breakpoint"); + + accessible = ignoreHitCount.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.HitCount"; + accessible.Label = GettextCatalog.GetString ("Hit Count"); + accessible.Description = GettextCatalog.GetString ("Enter the hit count required for the condition"); + + accessible = conditionalHitType.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.ConditionalHit"; + accessible.Label = GettextCatalog.GetString ("Conditional Breakpoint Hit Type"); + accessible.Description = GettextCatalog.GetString ("Select an extra condition for this breakpoint"); + + accessible = entryConditionalExpression.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.ConditionEntry"; + accessible.Label = GettextCatalog.GetString ("Conditional Breakpoint Expression"); + accessible.Description = GettextCatalog.GetString ("Enter a C# boolean expression to act as a condition for this breakpoint. The scope of the expression is local to the breakpoint"); + + accessible = warningCondition.Accessible; + accessible.Identifier = "BreakpointPropertiesDialog.WarningCondition"; + accessible.Description = GettextCatalog.GetString ("There is a warning for the condition expression"); + } + void SetLayout () { var vbox = new VBox (); + vbox.Accessible.Role = Xwt.Accessibility.Role.Filler; vbox.MinWidth = 450; - vbox.PackStart (new Label (GettextCatalog.GetString ("Breakpoint Action")) { + var actionLabel = new Label (GettextCatalog.GetString ("Breakpoint Action")) { Font = vbox.Font.WithWeight (FontWeight.Bold) - }); + }; + vbox.PackStart (actionLabel); var breakpointActionGroup = new VBox { MarginLeft = 12 }; + breakpointActionGroup.Accessible.Role = Xwt.Accessibility.Role.Filler; breakpointActionGroup.PackStart (breakpointActionPause); breakpointActionGroup.PackStart (breakpointActionPrint); @@ -669,7 +760,13 @@ namespace MonoDevelop.Debugger MarginLeft = 18 }; + printExpressionGroup.Accessible.Role = Xwt.Accessibility.Role.Filler; + printExpressionGroup.PackStart (entryPrintExpression, true); + + // We'll ignore this label because the content of the label is included in the accessibility Help text of the + // entryPrintExpression widget + warningPrintExpression.Accessible.Role = Xwt.Accessibility.Role.Filler; printExpressionGroup.PackStart (warningPrintExpression); breakpointActionGroup.PackStart (printExpressionGroup); @@ -677,13 +774,15 @@ namespace MonoDevelop.Debugger vbox.PackStart (breakpointActionGroup); - vbox.PackStart (new Label (GettextCatalog.GetString ("When to Take Action")) { + var whenLabel = new Label (GettextCatalog.GetString ("When to Take Action")) { Font = vbox.Font.WithWeight (FontWeight.Bold) - }); + }; + vbox.PackStart (whenLabel); var whenToTakeActionRadioGroup = new VBox { MarginLeft = 12 }; + whenToTakeActionRadioGroup.Accessible.Role = Xwt.Accessibility.Role.Filler; // Function group { @@ -700,6 +799,8 @@ namespace MonoDevelop.Debugger whenToTakeActionRadioGroup.PackStart (stopOnException); hboxException = new HBox (); + hboxException.Accessible.Role = Xwt.Accessibility.Role.Filler; + hboxException.PackStart (entryExceptionType, true); hboxException.PackEnd (warningException); @@ -720,23 +821,31 @@ namespace MonoDevelop.Debugger } vbox.PackStart (whenToTakeActionRadioGroup); - vbox.PackStart (new Label (GettextCatalog.GetString ("Advanced Conditions")) { + var advancedLabel = new Label (GettextCatalog.GetString ("Advanced Conditions")) { Font = vbox.Font.WithWeight (FontWeight.Bold) - }); + }; + vbox.PackStart (advancedLabel); var vboxAdvancedConditions = new VBox { MarginLeft = 30 }; + vboxAdvancedConditions.Accessible.Role = Xwt.Accessibility.Role.Filler; + var hboxHitCount = new HBox (); + hboxHitCount.Accessible.Role = Xwt.Accessibility.Role.Filler; hboxHitCount.PackStart (ignoreHitType, true); hboxHitCount.PackStart (ignoreHitCount); vboxAdvancedConditions.PackStart (hboxHitCount); vboxAdvancedConditions.PackStart (conditionalHitType); hboxCondition = new HBox (); + hboxCondition.Accessible.Role = Xwt.Accessibility.Role.Filler; + hboxCondition.PackStart (entryConditionalExpression, true); hboxCondition.PackStart (warningCondition); vboxAdvancedConditions.PackStart (hboxCondition); + + conditionalExpressionTip.Accessible.Role = Xwt.Accessibility.Role.Filler; vboxAdvancedConditions.PackEnd (conditionalExpressionTip); vbox.PackStart (vboxAdvancedConditions); diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggerEngine.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggerEngine.cs index 605a3c3906..b07b3952c6 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggerEngine.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggerEngine.cs @@ -94,7 +94,14 @@ namespace MonoDevelop.Debugger LoadEngine (); return engine.CreateDebuggerStartInfo (cmd); } - + + public ProcessAttacher GetProcessAttacher () + { + LoadEngine (); + + return engine?.GetProcessAttacher (); + } + public ProcessInfo[] GetAttachableProcesses () { LoadEngine (); diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggerEngineBackend.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggerEngineBackend.cs index be5e10e002..caa5139161 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggerEngineBackend.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggerEngineBackend.cs @@ -50,6 +50,20 @@ namespace MonoDevelop.Debugger return new ProcessInfo[0]; } + /// <summary> + /// <see cref="GetProcessAttacher"/> has two advantages over <see cref="GetAttachableProcesses"/>: + /// 1) it gives debugger engine ability to update processes list as soon as it discovers new processes via <see cref="ProcessAttacher.AttachableProcessesChanged"/> + /// 2) it gives debugger engine lifetime information via <see cref="ProcessAttacher.Dispose"/>, so debugger engine can clean resources used to look for processes e.g. loop thread, sockets... + /// </summary> + /// <remarks> + /// If this method returns valid <see cref="ProcessAttacher"/>, <see cref="GetAttachableProcesses"/> won't be called. + /// </remarks> + /// <returns>The process attacher.</returns> + public virtual ProcessAttacher GetProcessAttacher () + { + return null; + } + public abstract DebuggerSession CreateSession (); } diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs index 27e6da652c..1d3692426e 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs @@ -254,11 +254,11 @@ namespace MonoDevelop.Debugger return GetSetConverter<T> (val) != null; } - public static void ShowValueVisualizer (ObjectValue val) + public static bool ShowValueVisualizer (ObjectValue val) { using (var dlg = new ValueVisualizerDialog ()) { dlg.Show (val); - MessageService.ShowCustomDialog (dlg); + return MessageService.ShowCustomDialog (dlg) == (int)Gtk.ResponseType.Ok; } } diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs index 4bfec4d843..3d28974ddd 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs @@ -79,6 +79,7 @@ namespace MonoDevelop.Debugger readonly ValueCellRenderer crtValue; readonly CellRendererText crtType; readonly CellRendererRoundedButton crpButton; + readonly CellRendererImage evaluateStatusCell; readonly CellRendererImage crpPin; readonly CellRendererImage crpLiveUpdate; readonly CellRendererImage crpViewer; @@ -343,7 +344,7 @@ namespace MonoDevelop.Debugger valueCol = new TreeViewColumn (); valueCol.Title = GettextCatalog.GetString ("Value"); - var evaluateStatusCell = new CellRendererImage (); + evaluateStatusCell = new CellRendererImage (); valueCol.PackStart (evaluateStatusCell, false); valueCol.AddAttribute (evaluateStatusCell, "visible", EvaluateStatusIconVisibleColumn); valueCol.AddAttribute (evaluateStatusCell, "image", EvaluateStatusIconColumn); @@ -1125,7 +1126,7 @@ namespace MonoDevelop.Debugger RegisterValue (val, iter); } - void SetValues (TreeIter parent, TreeIter it, string name, ObjectValue val) + void SetValues (TreeIter parent, TreeIter it, string name, ObjectValue val, bool updateJustValue = false) { string strval; bool canEdit; @@ -1209,10 +1210,13 @@ namespace MonoDevelop.Debugger strval = strval.Replace ("\r\n", " ").Replace ("\n", " "); + store.SetValue (it, ValueColumn, strval); + if (updateJustValue) + return; + bool hasChildren = val.HasChildren; string icon = GetIcon (val.Flags); store.SetValue (it, NameColumn, name); - store.SetValue (it, ValueColumn, strval); store.SetValue (it, TypeColumn, val.TypeName); store.SetValue (it, ObjectColumn, val); store.SetValue (it, NameEditableColumn, !hasParent && AllowAdding); @@ -1509,8 +1513,35 @@ namespace MonoDevelop.Debugger store.SetValue (it, NameColorColumn, newColor); store.SetValue (it, ValueColorColumn, newColor); + UpdateParentValue (it); } - + + private void UpdateParentValue (TreeIter it) + { + if (store.IterParent (out var parentIter, it)) { + if (store.GetValue (parentIter, ObjectColumn) is ObjectValue parentVal) { + parentVal.Refresh (); + nodes [parentVal] = new TreeRowReference (store, store.GetPath (parentIter)); + if (parentVal.IsEvaluating) + parentVal.ValueChanged += UpdateObjectValue; + else + UpdateObjectValue (parentVal, null); + } + } + } + + private void UpdateObjectValue (object sender, EventArgs e) + { + Runtime.RunInMainThread (() => { + var val = (ObjectValue)sender; + val.ValueChanged -= UpdateObjectValue; + if (!FindValue (val, out var it)) + return; + nodes.Remove (val); + SetValues (TreeIter.Zero, it, null, val, true); + }); + } + void OnEditingCancelled (object s, EventArgs args) { OnEndEditing (); @@ -1855,12 +1886,17 @@ namespace MonoDevelop.Debugger CellRenderer cr; TreePath path; bool closePreviewWindow = true; + bool clickProcessed = false; TreeIter it; if (CanQueryDebugger && evnt.Button == 1 && GetCellAtPos ((int)evnt.X, (int)evnt.Y, out path, out col, out cr) && store.GetIter (out it, path)) { if (cr == crpViewer) { + clickProcessed = true; var val = (ObjectValue)store.GetValue (it, ObjectColumn); - DebuggingService.ShowValueVisualizer (val); + if (DebuggingService.ShowValueVisualizer (val)) { + UpdateParentValue (it); + RefreshRow (it); + } } else if (cr == crtExp && !PreviewWindowManager.IsVisible && ValidObjectForPreviewIcon (it)) { var val = (ObjectValue)store.GetValue (it, ObjectColumn); startPreviewCaret = GetCellRendererArea (path, col, cr); @@ -1880,6 +1916,7 @@ namespace MonoDevelop.Debugger startPreviewCaret.Y += (int)Vadjustment.Value; if (startPreviewCaret.X < evnt.X && startPreviewCaret.X + 16 > evnt.X) { + clickProcessed = true; if (CompactView) { SetPreviewButtonIcon (PreviewButtonIcons.Active, it); } else { @@ -1899,6 +1936,7 @@ namespace MonoDevelop.Debugger var url = crtValue.Text.Trim ('"', '{', '}'); Uri uri; if (url != null && Uri.TryCreate (url, UriKind.Absolute, out uri) && (uri.Scheme == "http" || uri.Scheme == "https")) { + clickProcessed = true; DesktopService.ShowUrl (url); } } @@ -1909,14 +1947,17 @@ namespace MonoDevelop.Debugger base.OnButtonPressEvent (evnt);//Select row, so base.OnButtonPressEvent below starts editing } else if (!editing) { if (cr == crpButton) { + clickProcessed = true; HandleValueButton (it); } else if (cr == crpPin) { + clickProcessed = true; TreeIter pi; if (PinnedWatch != null && !store.IterParent (out pi, it)) RemovePinnedWatch (it); else CreatePinnedWatch (it); } else if (cr == crpLiveUpdate) { + clickProcessed = true; TreeIter pi; if (PinnedWatch != null && !store.IterParent (out pi, it)) { DebuggingService.SetLiveUpdateMode (PinnedWatch, !PinnedWatch.LiveUpdate); @@ -1933,6 +1974,9 @@ namespace MonoDevelop.Debugger PreviewWindowManager.DestroyWindow (); } + if (clickProcessed) + return true; + //HACK: show context menu in release event instead of show event to work around gtk bug if (evnt.TriggersContextMenu ()) { // ShowPopup (evnt); @@ -2148,7 +2192,21 @@ namespace MonoDevelop.Debugger foreach (CellRenderer cr in col.CellRenderers) { int xo, w; col.CellGetPosition (cr, out xo, out w); - if (cr.Visible && x >= xo && x < xo + w) { + var visible = cr.Visible; + if (cr == crpViewer) { + if (store.GetIter (out var it, path)) { + visible = (bool)store.GetValue (it, ViewerButtonVisibleColumn); + } + } else if (cr == evaluateStatusCell) { + if (store.GetIter (out var it, path)) { + visible = (bool)store.GetValue (it, EvaluateStatusIconVisibleColumn); + } + } else if (cr == crpButton) { + if (store.GetIter (out var it, path)) { + visible = (bool)store.GetValue (it, ValueButtonVisibleColumn); + } + } + if (visible && x >= xo && x < xo + w) { cellRenderer = cr; return true; } diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ProcessAttacher.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ProcessAttacher.cs new file mode 100644 index 0000000000..9e0eee0805 --- /dev/null +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ProcessAttacher.cs @@ -0,0 +1,46 @@ +// +// ProcessAttacher.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.Debugging.Client; + +namespace MonoDevelop.Debugger +{ + public delegate void AttachableProcessesChangedDelegate (ProcessAttacher sender); + + public abstract class ProcessAttacher : IDisposable + { + public abstract ProcessInfo [] GetAttachableProcesses (); + + public event AttachableProcessesChangedDelegate AttachableProcessesChanged; + + protected void OnAttachableProcessesChanged () + { + AttachableProcessesChanged (this); + } + + public abstract void Dispose (); + } +} diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DotNetCoreProjectNodeBuilderExtension.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DotNetCoreProjectNodeBuilderExtension.cs index 29776e99a2..4a7d199a40 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DotNetCoreProjectNodeBuilderExtension.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.NodeBuilders/DotNetCoreProjectNodeBuilderExtension.cs @@ -51,18 +51,10 @@ namespace MonoDevelop.DotNetCore.NodeBuilders if (dotNetCoreProject.HasSdk && !dotNetCoreProject.IsDotNetCoreSdkInstalled ()) { nodeInfo.StatusSeverity = TaskSeverity.Error; - nodeInfo.StatusMessage = GetMessage (dotNetCoreProject); + nodeInfo.StatusMessage = dotNetCoreProject.GetDotNetCoreSdkRequiredMessage (); } } - string GetMessage (DotNetCoreProjectExtension dotNetCoreProject) - { - if (dotNetCoreProject.IsUnsupportedDotNetCoreSdkInstalled ()) - return GettextCatalog.GetString ("The .NET Core SDK installed is not supported. Please install a more recent version. {0}", DotNetCoreNotInstalledDialog.DotNetCoreDownloadUrl); - - return GettextCatalog.GetString (".NET Core SDK is not installed. This is required to build .NET Core projects. {0}", DotNetCoreNotInstalledDialog.DotNetCoreDownloadUrl); - } - public override Type CommandHandlerType { get { return typeof (DotNetCoreProjectNodeCommandHandler); } } diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests.csproj b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests.csproj index 60b973988b..3ab9e574d5 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests.csproj +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests.csproj @@ -40,6 +40,7 @@ <Compile Include="MonoDevelop.DotNetCore.Tests\DotNetCoreProjectTests.cs" /> <Compile Include="MonoDevelop.DotNetCore.Tests\DotNetCoreMSBuildProjectTests.cs" /> <Compile Include="MonoDevelop.DotNetCore.Tests\DotNetCoreVersionTests.cs" /> + <Compile Include="MonoDevelop.DotNetCore.Tests\DotNetCoreSdkTests.cs" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\..\..\..\external\guiunit\src\framework\GuiUnit_NET_4_5.csproj"> diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreSdkTests.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreSdkTests.cs new file mode 100644 index 0000000000..f54ccb7fcb --- /dev/null +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreSdkTests.cs @@ -0,0 +1,73 @@ +// +// DotNetCoreSdkTests.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.Core.Assemblies;
+using NUnit.Framework; +using System.Linq; + +namespace MonoDevelop.DotNetCore.Tests +{ + [TestFixture] + class DotNetCoreSdkTests + { + /// <summary> + /// Checks that a project's target framework is supported based on the install .NET Core SDKs. + /// Also takes into account if Mono includes the .NET Core v1 SDKs + /// </summary> + [TestCase (".NETCoreApp", "1.0", new [] { "1.0.4" }, false, true)] + [TestCase (".NETCoreApp", "1.1", new [] { "1.0.4" }, false, true)] // .NET Core sdk 1.0 supports 1.1 projects. + [TestCase (".NETStandard" ,"1.0", new [] { "1.0.4" }, false, true)] + [TestCase (".NETCoreApp", "1.0", new [] { "1.0.4" }, true, true)] // Mono has .NET Core sdks. + [TestCase (".NETCoreApp", "1.1", new string [0], true, true)] // Mono has .NET Core sdks. + [TestCase (".NETStandard", "1.0", new string [0], true, true)] // Mono has .NET Core sdks. + [TestCase (".NETCoreApp", "2.0", new [] { "1.0.4" }, false, false)] + [TestCase (".NETStandard", "2.0", new [] { "1.0.4" }, false, false)] + [TestCase (".NETCoreApp", "2.0", new [] { "1.0.4", "2.0.0" }, false, true)] + [TestCase (".NETStandard", "2.0", new [] { "1.0.4", "2.0.0" }, false, true)] + [TestCase (".NETCoreApp", "2.0", new [] { "2.0.0-preview2-006497" }, false, true)] // Allow preview versions. + [TestCase (".NETStandard", "2.0", new [] { "2.0.0-preview2-006497" }, false, true)] // Allow preview versions. + [TestCase (".NETFramework", "2.0", new [] { "2.0.0" }, false, false)] // Only .NETCoreApp and .NETStandard are supported. + [TestCase (".NETCoreApp", "1.1", new [] { "2.0.0" }, false, true)] // v2.0 SDK can compile v1 projects + [TestCase (".NETStandard", "1.6", new [] { "2.0.0" }, false, true)] // v2.0 SDK can compile v1 projects + public void IsSupportedTargetFramework ( + string frameworkIdentifier, + string frameworkVersion, + string[] installedSdkVersions, + bool msbuildSdksInstalled, // True if Mono has the .NET Core sdks. + bool expected) + { + string framework = $"{frameworkIdentifier},Version=v{frameworkVersion}"; + var targetFrameworkMoniker = TargetFrameworkMoniker.Parse (framework); + var versions = installedSdkVersions.Select (version => DotNetCoreVersion.Parse (version)) + .OrderByDescending (version => version) + .ToArray (); + + bool actual = DotNetCoreSdk.IsSupported (targetFrameworkMoniker, versions, msbuildSdksInstalled); + + Assert.AreEqual (expected, actual); + } + } +} diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.csproj b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.csproj index c2be14c75e..94374bf34c 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.csproj +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.csproj @@ -425,6 +425,6 @@ <Version>$(TemplatesVersion)</Version> </NuGetPackage> </ItemGroup> - <Copy SourceFiles="..\..\..\packages\%(NuGetPackage.Identity).%(NuGetPackage.Version)\%(NuGetPackage.Identity).%(NuGetPackage.Version).nupkg" DestinationFolder="$(OutputPath)\Templates" /> + <Copy SourceFiles="..\..\..\packages\%(NuGetPackage.Identity).%(NuGetPackage.Version)\%(NuGetPackage.Identity).%(NuGetPackage.Version).nupkg" DestinationFolder="$(OutputPath)\Templates" SkipUnchangedFiles="true" /> </Target> </Project> diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreNotInstalledDialog.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreNotInstalledDialog.cs index 8e2ac57499..8a0fd189c6 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreNotInstalledDialog.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreNotInstalledDialog.cs @@ -34,9 +34,15 @@ namespace MonoDevelop.DotNetCore class DotNetCoreNotInstalledDialog : IDisposable { public static readonly string DotNetCoreDownloadUrl = "https://aka.ms/vs/mac/install-netcore"; + public static readonly string DotNetCore20DownloadUrl = "https://aka.ms/vs/mac/install-netcore2"; + + static readonly string defaultMessage = GettextCatalog.GetString (".NET Core SDK is not installed. This is required to build and run .NET Core projects."); + static readonly string unsupportedMessage = GettextCatalog.GetString ("The .NET Core SDK installed is not supported. Please install a more recent version."); + static readonly string dotNetCore20Message = GettextCatalog.GetString (".NET Core 2.0 SDK is not installed. This is required to build and run .NET Core 2.0 projects."); GenericMessage message; AlertButton downloadButton; + string downloadUrl = DotNetCoreDownloadUrl; public DotNetCoreNotInstalledDialog () { @@ -46,7 +52,7 @@ namespace MonoDevelop.DotNetCore void Build () { message = new GenericMessage { - Text = GettextCatalog.GetString (".NET Core SDK is not installed. This is required to build and run .NET Core projects."), + Text = defaultMessage, DefaultButton = 1, Icon = Stock.Information }; @@ -61,7 +67,7 @@ namespace MonoDevelop.DotNetCore void AlertButtonClicked (object sender, AlertButtonEventArgs e) { if (e.Button == downloadButton) - DesktopService.ShowUrl (DotNetCoreDownloadUrl); + DesktopService.ShowUrl (downloadUrl); } public void Dispose () @@ -71,6 +77,13 @@ namespace MonoDevelop.DotNetCore public void Show () { + if (IsUnsupportedVersion) + Message = unsupportedMessage; + else if (RequiresDotNetCore20) { + Message = dotNetCore20Message; + downloadUrl = DotNetCore20DownloadUrl; + } + MessageService.GenericAlert (message); } @@ -78,5 +91,8 @@ namespace MonoDevelop.DotNetCore get { return message.Text; } set { message.Text = value; } } + + public bool IsUnsupportedVersion { get; set; } + public bool RequiresDotNetCore20 { get; set; } } } diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs index 6647df387e..2c6dd51f55 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs @@ -228,8 +228,8 @@ namespace MonoDevelop.DotNetCore Project.ParentSolution.ExtendedProperties [ShownDotNetCoreSdkInstalledExtendedPropertyName] = "true"; using (var dialog = new DotNetCoreNotInstalledDialog ()) { - if (unsupportedSdkVersion) - dialog.Message = GettextCatalog.GetString ("The .NET Core SDK installed is not supported. Please install a more recent version."); + dialog.IsUnsupportedVersion = unsupportedSdkVersion; + dialog.RequiresDotNetCore20 = Project.TargetFramework.IsNetStandard20OrNetCore20 (); dialog.Show (); } }); @@ -361,13 +361,23 @@ namespace MonoDevelop.DotNetCore BuildResult CreateDotNetCoreSdkRequiredBuildResult (bool isUnsupportedVersion) { - return CreateBuildError (GetDotNetCoreSdkRequiredBuildErrorMessage (isUnsupportedVersion)); + bool requiresDotNetCoreSdk20 = Project.TargetFramework.IsNetStandard20OrNetCore20 (); + return CreateBuildError (GetDotNetCoreSdkRequiredBuildErrorMessage (isUnsupportedVersion, requiresDotNetCoreSdk20)); } - static string GetDotNetCoreSdkRequiredBuildErrorMessage (bool isUnsupportedVersion) + internal string GetDotNetCoreSdkRequiredMessage () + { + return GetDotNetCoreSdkRequiredBuildErrorMessage ( + IsUnsupportedDotNetCoreSdkInstalled (), + Project.TargetFramework.IsNetStandard20OrNetCore20 ()); + } + + static string GetDotNetCoreSdkRequiredBuildErrorMessage (bool isUnsupportedVersion, bool requiresDotNetCoreSdk20) { if (isUnsupportedVersion) return GettextCatalog.GetString ("The .NET Core SDK installed is not supported. Please install a more recent version. {0}", DotNetCoreNotInstalledDialog.DotNetCoreDownloadUrl); + else if (requiresDotNetCoreSdk20) + return GettextCatalog.GetString (".NET Core 2.0 SDK is not installed. This is required to build .NET Core 2.0 projects. {0}", DotNetCoreNotInstalledDialog.DotNetCore20DownloadUrl); return GettextCatalog.GetString (".NET Core SDK is not installed. This is required to build .NET Core projects. {0}", DotNetCoreNotInstalledDialog.DotNetCoreDownloadUrl); } @@ -475,7 +485,9 @@ namespace MonoDevelop.DotNetCore public bool IsDotNetCoreSdkInstalled () { - return DotNetCoreSdk.IsInstalled || MSBuildSdks.Installed; + if (DotNetCoreSdk.IsInstalled || MSBuildSdks.Installed) + return DotNetCoreSdk.IsSupported (Project.TargetFramework); + return false; } public bool IsUnsupportedDotNetCoreSdkInstalled () diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectReloadMonitor.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectReloadMonitor.cs index 1e875529c0..637d0a6f84 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectReloadMonitor.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectReloadMonitor.cs @@ -76,7 +76,7 @@ namespace MonoDevelop.DotNetCore void OnDotNetCoreProjectReloaded (ProjectReloadedEventArgs e) { DotNetCoreProjectBuilderMaintainer.OnProjectReload (e); - RestorePackagesInProjectHandler.Run (e.NewProject.DotNetProject); + RestorePackagesInProjectHandler.Run (e.NewProject.DotNetProject, restoreTransitiveProjectReferences: true); } async void FileChanged (object sender, FileEventArgs e) diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreSdk.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreSdk.cs index b6530aa427..1eaaf19fc1 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreSdk.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreSdk.cs @@ -27,6 +27,7 @@ using System; using System.Linq; using MonoDevelop.Core; +using MonoDevelop.Core.Assemblies; namespace MonoDevelop.DotNetCore { @@ -67,6 +68,55 @@ namespace MonoDevelop.DotNetCore } /// <summary> + /// Checks that the target framework (e.g. .NETCoreApp1.1 or .NETStandard2.0) is supported + /// by the installed SDKs. Takes into account Mono having .NET Core v1 SDKs installed. + /// </summary> + internal static bool IsSupported (TargetFramework framework) + { + return IsSupported (framework.Id, Versions, MSBuildSdks.Installed); + } + + /// <summary> + /// Used by unit tests. + /// </summary> + internal static bool IsSupported ( + TargetFrameworkMoniker projectFramework, + DotNetCoreVersion[] versions, + bool msbuildSdksInstalled) + { + if (!projectFramework.IsNetStandardOrNetCoreApp ()) + return false; + + var projectFrameworkVersion = Version.Parse (projectFramework.Version); + + if (versions.Any (sdkVersion => IsSupported (projectFrameworkVersion, sdkVersion))) + return true; + + // .NET Core 1.x is supported by the MSBuild .NET Core SDKs if they are installed with Mono. + if (projectFrameworkVersion.Major == 1) + return msbuildSdksInstalled; + + return false; + } + + /// <summary> + /// Project framework version is considered supported if the major version of the + /// .NET Core SDK is greater or equal to the major version of the project framework. + /// The fact that a .NET Core SDK is a preview version is ignored in this check. + /// + /// .NET Core SDK 1.0.4 supports .NET Core 1.0 and 1.1 + /// .NET Core SDK 1.0.4 supports .NET Standard 1.0 to 1.6 + /// .NET Core SDK 2.0 supports 1.0, 1.1 and 2.0 + /// .NET Core SDK 2.0 supports .NET Standard 1.0 to 1.6 and 2.0 + /// .NET Core SDK 2.1 supports 1.0, 1.1 and 2.0 + /// .NET Core SDK 2.1 supports .NET Standard 1.0 to 1.6 and 2.0 + /// </summary> + static bool IsSupported (Version projectFrameworkVersion, DotNetCoreVersion sdkVersion) + { + return sdkVersion.Major >= projectFrameworkVersion.Major; + } + + /// <summary> /// This is a workaround to allow F# .NET Core 2.0 projects to be evaluated properly and compile /// without any errors. The better solution would be to ship the new Microsoft.FSharp.NetSdk.props /// and .targets files with Mono so this workaround can be removed. Setting the FSharpPropsShim diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs index 8520f8c928..1a68219abf 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs @@ -33,7 +33,7 @@ namespace MonoDevelop.DotNetCore { public static bool IsNetStandard (this TargetFramework framework) { - return framework.Id.Identifier == ".NETStandard"; + return framework.Id.IsNetStandard (); } public static bool IsNetStandard20 (this TargetFramework framework) @@ -64,7 +64,7 @@ namespace MonoDevelop.DotNetCore public static bool IsNetCoreApp (this TargetFramework framework) { - return framework.Id.Identifier == ".NETCoreApp"; + return framework.Id.IsNetCoreApp (); } public static bool IsNetCoreApp20 (this TargetFramework framework) @@ -84,6 +84,11 @@ namespace MonoDevelop.DotNetCore return framework.Id.IsNetFramework (); } + public static bool IsNetStandard20OrNetCore20 (this TargetFramework framework) + { + return framework.IsNetStandard20 () || framework.IsNetCoreApp (); + } + public static string GetDisplayName (this TargetFramework framework) { if (framework.IsNetCoreApp ()) diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkMonikerExtensions.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkMonikerExtensions.cs index 3cd0bdd459..c49a937ebe 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkMonikerExtensions.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkMonikerExtensions.cs @@ -61,5 +61,20 @@ namespace MonoDevelop.DotNetCore { return framework.Identifier == ".NETFramework"; } + + public static bool IsNetCoreApp (this TargetFrameworkMoniker framework) + { + return framework.Identifier == ".NETCoreApp"; + } + + public static bool IsNetStandard (this TargetFrameworkMoniker framework) + { + return framework.Identifier == ".NETStandard"; + } + + public static bool IsNetStandardOrNetCoreApp (this TargetFrameworkMoniker framework) + { + return framework.IsNetStandard () || framework.IsNetCoreApp (); + } } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/RestorePackagesInProjectHandler.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/RestorePackagesInProjectHandler.cs index aca0efb247..fbeb69dffa 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/RestorePackagesInProjectHandler.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Commands/RestorePackagesInProjectHandler.cs @@ -43,25 +43,34 @@ namespace MonoDevelop.PackageManagement.Commands info.Enabled = SelectedDotNetProjectHasPackages (); } - public static void Run (DotNetProject project) + public static void Run (DotNetProject project)
+ {
+ Run (project, false);
+ }
+
+ public static void Run (DotNetProject project, bool restoreTransitiveProjectReferences) { try {
ProgressMonitorStatusMessage message = ProgressMonitorStatusMessageFactory.CreateRestoringPackagesInProjectMessage ();
- IPackageAction action = CreateRestorePackagesAction (project); + IPackageAction action = CreateRestorePackagesAction (project, restoreTransitiveProjectReferences); PackageManagementServices.BackgroundPackageActionRunner.Run (message, action);
} catch (Exception ex) {
ShowStatusBarError (ex);
}
}
- static IPackageAction CreateRestorePackagesAction (DotNetProject project) + static IPackageAction CreateRestorePackagesAction (DotNetProject project, bool restoreTransitiveProjectReferences) {
var solutionManager = PackageManagementServices.Workspace.GetSolutionManager (project.ParentSolution);
var nugetProject = solutionManager.GetNuGetProject (new DotNetProjectProxy (project));
var buildIntegratedProject = nugetProject as BuildIntegratedNuGetProject;
if (buildIntegratedProject != null) {
- return new RestoreNuGetPackagesInNuGetIntegratedProject (project, buildIntegratedProject, solutionManager);
+ return new RestoreNuGetPackagesInNuGetIntegratedProject (
+ project,
+ buildIntegratedProject,
+ solutionManager,
+ restoreTransitiveProjectReferences);
}
var nugetAwareProject = project as INuGetAwareProject;
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/AddPackagesDialog.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/AddPackagesDialog.cs index f4609d9f98..d6e867e140 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/AddPackagesDialog.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/AddPackagesDialog.cs @@ -320,7 +320,9 @@ namespace MonoDevelop.PackageManagement void ShowPackageInformation (PackageSearchResultViewModel packageViewModel)
{
- this.packageNameLabel.Markup = packageViewModel.GetNameMarkup ();
+ // Use the package id and not the package title to prevent a pango crash if the title
+ // contains Chinese characters.
+ this.packageNameLabel.Markup = packageViewModel.GetIdMarkup ();
this.packageAuthor.Text = packageViewModel.Author;
this.packagePublishedDate.Text = packageViewModel.GetLastPublishedDisplayText ();
this.packageDownloads.Text = packageViewModel.GetDownloadCountDisplayText ();
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/PackageCellView.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/PackageCellView.cs index 765fa46a29..8da11df3c0 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/PackageCellView.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/PackageCellView.cs @@ -98,9 +98,11 @@ namespace MonoDevelop.PackageManagement }
// Package Id.
+ // Use the package id and not the package title to prevent a pango crash if the title
+ // contains Chinese characters.
var packageIdTextLayout = new TextLayout ();
packageIdTextLayout.Font = packageIdTextLayout.Font.WithSize (packageIdFontSize);
- packageIdTextLayout.Markup = packageViewModel.GetNameMarkup ();
+ packageIdTextLayout.Markup = packageViewModel.GetIdMarkup ();
packageIdTextLayout.Trimming = TextTrimming.WordElipsis;
Size packageIdTextSize = packageIdTextLayout.GetSize ();
packageIdTextLayout.Width = packageIdWidth;
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeMonoDevelopBuildIntegratedRestorer.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeMonoDevelopBuildIntegratedRestorer.cs new file mode 100644 index 0000000000..c60ab67a26 --- /dev/null +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeMonoDevelopBuildIntegratedRestorer.cs @@ -0,0 +1,58 @@ +// +// FakeMonoDevelopBuildIntegratedRestorer.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.Threading; +using System.Threading.Tasks; +using NuGet.ProjectManagement.Projects; + +namespace MonoDevelop.PackageManagement.Tests.Helpers +{ + class FakeMonoDevelopBuildIntegratedRestorer : IMonoDevelopBuildIntegratedRestorer + { + public bool LockFileChanged { get; set; } + + public BuildIntegratedNuGetProject ProjectRestored; + + public Task RestorePackages ( + BuildIntegratedNuGetProject project, + CancellationToken cancellationToken) + { + ProjectRestored = project; + return Task.FromResult (0); + } + + public List<BuildIntegratedNuGetProject> ProjectsRestored = new List<BuildIntegratedNuGetProject> (); + + public Task RestorePackages ( + IEnumerable<BuildIntegratedNuGetProject> projects, + CancellationToken cancellationToken) + { + ProjectsRestored.AddRange (projects); + return Task.FromResult (0); + } + } +} diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetProject.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetProject.cs index b2a0de2557..4b9eaae8f3 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetProject.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetProject.cs @@ -107,7 +107,7 @@ namespace MonoDevelop.PackageManagement.Tests.Helpers return Task.FromResult (0); } - public void NotifyProjectReferencesChanged () + public void NotifyProjectReferencesChanged (bool includeTransitiveProjectReferences) { } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeSolutionManager.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeSolutionManager.cs index 0cf7e37214..b88ace6581 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeSolutionManager.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeSolutionManager.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using MonoDevelop.Projects; using NuGet.Configuration; using NuGet.PackageManagement; using NuGet.ProjectManagement; @@ -113,14 +114,20 @@ namespace MonoDevelop.PackageManagement.Tests.Helpers throw new NotImplementedException (); } - public Dictionary<IDotNetProject, FakeNuGetProject> NuGetProjects = new Dictionary<IDotNetProject, FakeNuGetProject> (); + public Dictionary<IDotNetProject, NuGetProject> NuGetProjects = new Dictionary<IDotNetProject, NuGetProject> (); + public Dictionary<DotNetProject, NuGetProject> NuGetProjectsUsingDotNetProjects = new Dictionary<DotNetProject, NuGetProject> (); public NuGetProject GetNuGetProject (IDotNetProject project) { - FakeNuGetProject nugetProject = null; + NuGetProject nugetProject = null; if (NuGetProjects.TryGetValue (project, out nugetProject)) return nugetProject; + if (project.DotNetProject != null) { + if (NuGetProjectsUsingDotNetProjects.TryGetValue (project.DotNetProject, out nugetProject)) + return nugetProject; + } + return new FakeNuGetProject (project); } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableDotNetCoreNuGetProject.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableDotNetCoreNuGetProject.cs index 6380f38036..3ccbecf181 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableDotNetCoreNuGetProject.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableDotNetCoreNuGetProject.cs @@ -34,6 +34,7 @@ namespace MonoDevelop.PackageManagement.Tests.Helpers public TestableDotNetCoreNuGetProject (DotNetProject project) : base (project, new [] { "netcoreapp1.0" }) { + BuildIntegratedRestorer = new FakeMonoDevelopBuildIntegratedRestorer (); } public bool IsSaved { get; set; } @@ -43,5 +44,14 @@ namespace MonoDevelop.PackageManagement.Tests.Helpers IsSaved = true; return Task.FromResult (0); } + + public FakeMonoDevelopBuildIntegratedRestorer BuildIntegratedRestorer; + public Solution SolutionUsedToCreateBuildIntegratedRestorer; + + protected override IMonoDevelopBuildIntegratedRestorer CreateBuildIntegratedRestorer (Solution solution) + { + SolutionUsedToCreateBuildIntegratedRestorer = solution; + return BuildIntegratedRestorer; + } } } 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 6f3cee0b9a..8f1f0ec86b 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 @@ -201,6 +201,8 @@ <Compile Include="MonoDevelop.PackageManagement.Tests.Helpers\TestableUninstallNuGetPackagesAction.cs" /> <Compile Include="MonoDevelop.PackageManagement.Tests\PackageReferenceNuGetProjectTests.cs" /> <Compile Include="MonoDevelop.PackageManagement.Tests.Helpers\TestablePackageReferenceNuGetProject.cs" /> + <Compile Include="MonoDevelop.PackageManagement.Tests.Helpers\FakeMonoDevelopBuildIntegratedRestorer.cs" /> + <Compile Include="MonoDevelop.PackageManagement.Tests\RestoreNuGetPackagesInNuGetIntegratedProjectTests.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 e9148330f5..69135e9943 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 @@ -30,6 +30,7 @@ using System.Threading.Tasks; using MonoDevelop.PackageManagement.Tests.Helpers; using MonoDevelop.Projects; using NUnit.Framework; +using NuGet.PackageManagement; using NuGet.Packaging.Core; using NuGet.ProjectManagement; using NuGet.ProjectModel; @@ -44,14 +45,24 @@ namespace MonoDevelop.PackageManagement.Tests TestableDotNetCoreNuGetProject project; FakeNuGetProjectContext context; DependencyGraphCacheContext dependencyGraphCacheContext; + FakeMonoDevelopBuildIntegratedRestorer buildIntegratedRestorer; void CreateNuGetProject (string projectName = "MyProject", string fileName = @"d:\projects\MyProject\MyProject.csproj") { context = new FakeNuGetProjectContext (); - dotNetProject = new DummyDotNetProject (); - dotNetProject.Name = projectName; - dotNetProject.FileName = fileName.ToNativePath (); + dotNetProject = CreateDotNetCoreProject (projectName, fileName); + var solution = new Solution (); + solution.RootFolder.AddItem (dotNetProject); project = new TestableDotNetCoreNuGetProject (dotNetProject); + buildIntegratedRestorer = project.BuildIntegratedRestorer; + } + + static DummyDotNetProject CreateDotNetCoreProject (string projectName = "MyProject", string fileName = @"d:\projects\MyProject\MyProject.csproj") + { + var project = new DummyDotNetProject (); + project.Name = projectName; + project.FileName = fileName.ToNativePath (); + return project; } void AddDotNetProjectPackageReference (string packageId, string version) @@ -86,6 +97,12 @@ namespace MonoDevelop.PackageManagement.Tests return specs.Single (); } + void OnAfterExecuteActions (string packageId, string version, NuGetProjectActionType actionType) + { + var action = new FakeNuGetProjectAction (packageId, version, actionType); + project.OnAfterExecuteActions (new [] { action }); + } + [Test] public async Task GetInstalledPackagesAsync_OnePackageReference_ReturnsOnePackageReference () { @@ -255,5 +272,233 @@ namespace MonoDevelop.PackageManagement.Tests Assert.IsTrue (packageReference.IsFloating ()); Assert.AreEqual ("2.6.0-*", packageReference.AllowedVersions.Float.ToString ()); } + + [Test] + public async Task PostProcessAsync_ProjectAssetsFile_NotifyChangeInAssetsFile () + { + CreateNuGetProject (); + AddDotNetProjectPackageReference ("NUnit", "2.6.0"); + dotNetProject.BaseIntermediateOutputPath = @"d:\projects\MyProject\obj".ToNativePath (); + string fileNameChanged = null; + PackageManagementServices.PackageManagementEvents.FileChanged += (sender, e) => { + fileNameChanged = e.Single ().FileName; + }; + + await project.PostProcessAsync (context, CancellationToken.None); + + string expectedFileNameChanged = @"d:\projects\MyProject\obj\project.assets.json".ToNativePath (); + Assert.AreEqual (expectedFileNameChanged, fileNameChanged); + } + + [Test] + public async Task PostProcessAsync_References_NotifyReferencesChangedEventFired () + { + CreateNuGetProject (); + AddDotNetProjectPackageReference ("NUnit", "2.6.0"); + string modifiedHint = null; + dotNetProject.Modified += (sender, e) => { + modifiedHint = e.Single ().Hint; + }; + + await project.PostProcessAsync (context, CancellationToken.None); + + Assert.AreEqual ("References", modifiedHint); + } + + [Test] + public async Task PostProcessAsync_RestoreRunLockFileNotChanged_NotifyReferencesChangedEventFired () + { + CreateNuGetProject (); + AddDotNetProjectPackageReference ("NUnit", "2.6.0"); + string modifiedHint = null; + dotNetProject.Modified += (sender, e) => { + modifiedHint = e.Single ().Hint; + }; + OnAfterExecuteActions ("NUnit", "2.6.3", NuGetProjectActionType.Install); + + await project.PostProcessAsync (context, CancellationToken.None); + + Assert.IsNotNull (dotNetProject.ParentSolution); + Assert.AreEqual (dotNetProject.ParentSolution, project.SolutionUsedToCreateBuildIntegratedRestorer); + Assert.AreEqual (project, buildIntegratedRestorer.ProjectRestored); + Assert.AreEqual ("References", modifiedHint); + } + + [Test] + public async Task PostProcessAsync_RestoreRunLockFileNotChanged_NotifyChangeInAssetsFile () + { + CreateNuGetProject (); + AddDotNetProjectPackageReference ("NUnit", "2.6.0"); + dotNetProject.BaseIntermediateOutputPath = @"d:\projects\MyProject\obj".ToNativePath (); + string fileNameChanged = null; + PackageManagementServices.PackageManagementEvents.FileChanged += (sender, e) => { + fileNameChanged = e.Single ().FileName; + }; + OnAfterExecuteActions ("NUnit", "2.6.3", NuGetProjectActionType.Install); + + await project.PostProcessAsync (context, CancellationToken.None); + + string expectedFileNameChanged = @"d:\projects\MyProject\obj\project.assets.json".ToNativePath (); + Assert.AreEqual (expectedFileNameChanged, fileNameChanged); + Assert.AreEqual (project, buildIntegratedRestorer.ProjectRestored); + } + + /// <summary> + /// Build restorer would trigger the notification itself. + /// </summary> + [Test] + public async Task PostProcessAsync_RestoreRunLockFileChanged_NotifyReferencesChangedEventNotFired () + { + CreateNuGetProject (); + AddDotNetProjectPackageReference ("NUnit", "2.6.0"); + string modifiedHint = null; + dotNetProject.Modified += (sender, e) => { + modifiedHint = e.Single ().Hint; + }; + buildIntegratedRestorer.LockFileChanged = true; + OnAfterExecuteActions ("NUnit", "2.6.3", NuGetProjectActionType.Install); + + await project.PostProcessAsync (context, CancellationToken.None); + + Assert.AreEqual (project, buildIntegratedRestorer.ProjectRestored); + Assert.IsNull (modifiedHint); + } + + /// <summary> + /// Build restorer would trigger the notification itself. + /// </summary> + [Test] + public async Task PostProcessAsync_RestoreRunLockFileChanged_NotifyChangeInAssetsFileIsNotMade () + { + CreateNuGetProject (); + AddDotNetProjectPackageReference ("NUnit", "2.6.0"); + dotNetProject.BaseIntermediateOutputPath = @"d:\projects\MyProject\obj".ToNativePath (); + string fileNameChanged = null; + PackageManagementServices.PackageManagementEvents.FileChanged += (sender, e) => { + fileNameChanged = e.Single ().FileName; + }; + buildIntegratedRestorer.LockFileChanged = true; + OnAfterExecuteActions ("NUnit", "2.6.3", NuGetProjectActionType.Install); + + await project.PostProcessAsync (context, CancellationToken.None); + + Assert.IsNull (fileNameChanged); + Assert.AreEqual (project, buildIntegratedRestorer.ProjectRestored); + } + + [Test] + public void NotifyProjectReferencesChanged_References_NotifyReferencesChangedEventFired () + { + CreateNuGetProject (); + string modifiedHint = null; + dotNetProject.Modified += (sender, e) => { + modifiedHint = e.Single ().Hint; + }; + + project.NotifyProjectReferencesChanged (false); + + Assert.AreEqual ("References", modifiedHint); + } + + /// <summary> + /// Assembly references are transitive for .NET Core projects so any .NET Core project + /// that references the project having a NuGet package being installed needs to refresh + /// references for the other projects not just itself. + /// </summary> + [Test] + public async Task PostProcessAsync_DotNetCoreProjectReferencesThisProject_NotifyReferencesChangedEventFiredForBothProjects () + { + CreateNuGetProject (); + AddDotNetProjectPackageReference ("NUnit", "2.6.0"); + var dotNetProjectWithProjectReference = CreateDotNetCoreProject ("MyProject2", @"d:\projects\MyProject2\MyProject2.csproj"); + dotNetProject.ParentSolution.RootFolder.AddItem (dotNetProjectWithProjectReference); + var projectReference = ProjectReference.CreateProjectReference (dotNetProject); + dotNetProjectWithProjectReference.References.Add (projectReference); + string modifiedHintMainProject = null; + dotNetProject.Modified += (sender, e) => { + modifiedHintMainProject = e.Single ().Hint; + }; + string modifiedHintProjectWithReference = null; + dotNetProjectWithProjectReference.Modified += (sender, e) => { + modifiedHintProjectWithReference = e.Single ().Hint; + }; + + await project.PostProcessAsync (context, CancellationToken.None); + + Assert.AreEqual ("References", modifiedHintMainProject); + Assert.AreEqual ("References", modifiedHintProjectWithReference); + } + + [Test] + public async Task PostProcessAsync_DotNetCoreProjectReferencesThisProjectLockFileNotChanged_NotifyReferencesChangedEventFiredForBothProjects () + { + CreateNuGetProject (); + AddDotNetProjectPackageReference ("NUnit", "2.6.0"); + var dotNetProjectWithProjectReference = CreateDotNetCoreProject ("MyProject2", @"d:\projects\MyProject2\MyProject2.csproj"); + dotNetProject.ParentSolution.RootFolder.AddItem (dotNetProjectWithProjectReference); + var projectReference = ProjectReference.CreateProjectReference (dotNetProject); + dotNetProjectWithProjectReference.References.Add (projectReference); + string modifiedHintMainProject = null; + dotNetProject.Modified += (sender, e) => { + modifiedHintMainProject = e.Single ().Hint; + }; + string modifiedHintProjectWithReference = null; + dotNetProjectWithProjectReference.Modified += (sender, e) => { + modifiedHintProjectWithReference = e.Single ().Hint; + }; + OnAfterExecuteActions ("NUnit", "2.6.3", NuGetProjectActionType.Install); + + await project.PostProcessAsync (context, CancellationToken.None); + + Assert.AreEqual (project, buildIntegratedRestorer.ProjectRestored); + Assert.AreEqual ("References", modifiedHintMainProject); + Assert.AreEqual ("References", modifiedHintProjectWithReference); + } + + [Test] + public void NotifyProjectReferencesChanged_IncludeTransitiveReferences_NotifyReferencesChangedEventFiredForAllProjects () + { + CreateNuGetProject (); + var dotNetProjectWithProjectReference = CreateDotNetCoreProject ("MyProject2", @"d:\projects\MyProject2\MyProject2.csproj"); + dotNetProject.ParentSolution.RootFolder.AddItem (dotNetProjectWithProjectReference); + var projectReference = ProjectReference.CreateProjectReference (dotNetProject); + dotNetProjectWithProjectReference.References.Add (projectReference); + string modifiedHintMainProject = null; + dotNetProject.Modified += (sender, e) => { + modifiedHintMainProject = e.Single ().Hint; + }; + string modifiedHintProjectWithReference = null; + dotNetProjectWithProjectReference.Modified += (sender, e) => { + modifiedHintProjectWithReference = e.Single ().Hint; + }; + + project.NotifyProjectReferencesChanged (true); + + Assert.AreEqual ("References", modifiedHintMainProject); + Assert.AreEqual ("References", modifiedHintProjectWithReference); + } + + [Test] + public void NotifyProjectReferencesChanged_DoNotIncludeTransitiveReferences_NotifyReferencesChangedEventFiredForMainProjectOnly () + { + CreateNuGetProject (); + var dotNetProjectWithProjectReference = CreateDotNetCoreProject ("MyProject2", @"d:\projects\MyProject2\MyProject2.csproj"); + dotNetProject.ParentSolution.RootFolder.AddItem (dotNetProjectWithProjectReference); + var projectReference = ProjectReference.CreateProjectReference (dotNetProject); + dotNetProjectWithProjectReference.References.Add (projectReference); + string modifiedHintMainProject = null; + dotNetProject.Modified += (sender, e) => { + modifiedHintMainProject = e.Single ().Hint; + }; + string modifiedHintProjectWithReference = null; + dotNetProjectWithProjectReference.Modified += (sender, e) => { + modifiedHintProjectWithReference = e.Single ().Hint; + }; + + project.NotifyProjectReferencesChanged (false); + + Assert.AreEqual ("References", modifiedHintMainProject); + Assert.IsNull (modifiedHintProjectWithReference); + } } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetProjectExtensionsTests.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetProjectExtensionsTests.cs index c92c7b099b..303c4f39d5 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetProjectExtensionsTests.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetProjectExtensionsTests.cs @@ -25,8 +25,9 @@ // THE SOFTWARE.
using System.Collections.Generic;
-using MonoDevelop.PackageManagement;
+using System.Linq;
using MonoDevelop.PackageManagement.Tests.Helpers;
+using MonoDevelop.Projects;
using NUnit.Framework;
namespace MonoDevelop.PackageManagement.Tests
@@ -56,6 +57,20 @@ namespace MonoDevelop.PackageManagement.Tests existingFiles.Add (fileName.ToNativePath ());
}
+ static DummyDotNetProject CreateDotNetCoreProject (string projectName = "MyProject", string fileName = @"d:\projects\MyProject\MyProject.csproj")
+ {
+ var project = new DummyDotNetProject ();
+ project.Name = projectName;
+ project.FileName = fileName.ToNativePath ();
+ return project;
+ } + + void AddParentSolution (DotNetProject dotNetProject) + { + var solution = new Solution (); + solution.RootFolder.AddItem (dotNetProject); + }
+
[Test]
public void GetPackagesConfigFilePath_ProjectPackagesConfigFileDoesNotExist_ReturnsDefaultPackagesConfigFile ()
{
@@ -162,6 +177,213 @@ namespace MonoDevelop.PackageManagement.Tests Assert.IsTrue (result);
}
+
+ [Test]
+ public void DotNetCoreNotifyReferencesChanged_NoProjectReferencesAllProjects_NotifyReferencesChangedForProject ()
+ {
+ var dotNetProject = CreateDotNetCoreProject ();
+ AddParentSolution (dotNetProject); + string modifiedHint = null;
+ dotNetProject.Modified += (sender, e) => {
+ modifiedHint = e.First ().Hint;
+ };
+
+ dotNetProject.DotNetCoreNotifyReferencesChanged (transitiveOnly: false);
+
+ Assert.AreEqual ("References", modifiedHint);
+ }
+
+ [Test]
+ public void DotNetCoreNotifyReferencesChanged_NoProjectReferencesTransitiveProjectReferencesOnly_NotifyReferencesChangedNotFiredForProject ()
+ {
+ var dotNetProject = CreateDotNetCoreProject ();
+ AddParentSolution (dotNetProject); + string modifiedHint = null;
+ dotNetProject.Modified += (sender, e) => {
+ modifiedHint = e.First ().Hint;
+ };
+
+ dotNetProject.DotNetCoreNotifyReferencesChanged (transitiveOnly: true);
+
+ Assert.IsNull (modifiedHint);
+ } + + [Test] + public void DotNetCoreNotifyReferencesChanged_OneProjectReferencesProject_NotifyReferencesChangedForAllProjects () + { + var dotNetProject = CreateDotNetCoreProject (); + AddParentSolution (dotNetProject); + var referencingProject = CreateDotNetCoreProject (); + dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject); + referencingProject.References.Add (ProjectReference.CreateProjectReference (dotNetProject)); + string modifiedHint = null; + dotNetProject.Modified += (sender, e) => { + modifiedHint = e.First ().Hint; + }; + string modifiedHintForReferencingProject = null; + referencingProject.Modified += (sender, e) => { + modifiedHintForReferencingProject = e.First ().Hint; + }; + + dotNetProject.DotNetCoreNotifyReferencesChanged (); + + Assert.AreEqual ("References", modifiedHint); + Assert.AreEqual ("References", modifiedHintForReferencingProject); + } + + [Test] + public void DotNetCoreNotifyReferencesChanged_OneProjectReferencesProjectWithReferencedOutputAssemblyFalse_NotifyReferencesChangedNotFiredForReferencingProject () + { + var dotNetProject = CreateDotNetCoreProject (); + AddParentSolution (dotNetProject); + var referencingProject = CreateDotNetCoreProject (); + dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject); + var projectReference = ProjectReference.CreateProjectReference (dotNetProject); + projectReference.ReferenceOutputAssembly = false; + referencingProject.References.Add (projectReference); + string modifiedHintForReferencingProject = null; + referencingProject.Modified += (sender, e) => { + modifiedHintForReferencingProject = e.First ().Hint; + }; + + dotNetProject.DotNetCoreNotifyReferencesChanged (true); + + Assert.IsNull (modifiedHintForReferencingProject); + } + + [Test] + public void DotNetCoreNotifyReferencesChanged_TwoOneProjectReferencesModifiedProject_NotifyReferencesChangedForAllProjects () + { + var dotNetProject = CreateDotNetCoreProject (); + AddParentSolution (dotNetProject); + var referencingProject1 = CreateDotNetCoreProject (); + dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject1); + referencingProject1.References.Add (ProjectReference.CreateProjectReference (dotNetProject)); + var referencingProject2 = CreateDotNetCoreProject (); + dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject2); + referencingProject2.References.Add (ProjectReference.CreateProjectReference (dotNetProject)); + string modifiedHint = null; + dotNetProject.Modified += (sender, e) => { + modifiedHint = e.First ().Hint; + }; + string modifiedHintForReferencingProject1 = null; + referencingProject1.Modified += (sender, e) => { + modifiedHintForReferencingProject1 = e.First ().Hint; + }; + string modifiedHintForReferencingProject2 = null; + referencingProject2.Modified += (sender, e) => { + modifiedHintForReferencingProject2 = e.First ().Hint; + }; + + dotNetProject.DotNetCoreNotifyReferencesChanged (); + + Assert.AreEqual ("References", modifiedHint); + Assert.AreEqual ("References", modifiedHintForReferencingProject1); + Assert.AreEqual ("References", modifiedHintForReferencingProject2); + } + + [Test] + public void DotNetCoreNotifyReferencesChanged_TwoProjectReferencesChainToModifiedProject_NotifyReferencesChangedForAllProjects () + { + var dotNetProject = CreateDotNetCoreProject (); + AddParentSolution (dotNetProject); + var referencingProject1 = CreateDotNetCoreProject (); + dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject1); + referencingProject1.References.Add (ProjectReference.CreateProjectReference (dotNetProject)); + var referencingProject2 = CreateDotNetCoreProject (); + dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject2); + referencingProject2.References.Add (ProjectReference.CreateProjectReference (referencingProject1)); + string modifiedHint = null; + dotNetProject.Modified += (sender, e) => { + modifiedHint = e.First ().Hint; + }; + string modifiedHintForReferencingProject1 = null; + referencingProject1.Modified += (sender, e) => { + modifiedHintForReferencingProject1 = e.First ().Hint; + }; + string modifiedHintForReferencingProject2 = null; + referencingProject2.Modified += (sender, e) => { + modifiedHintForReferencingProject2 = e.First ().Hint; + }; + + dotNetProject.DotNetCoreNotifyReferencesChanged (); + + Assert.AreEqual ("References", modifiedHint); + Assert.AreEqual ("References", modifiedHintForReferencingProject1); + Assert.AreEqual ("References", modifiedHintForReferencingProject2); + } + + /// <summary> + /// Same as above but the projects are added to the solution in a different order. + /// </summary> + [Test] + public void DotNetCoreNotifyReferencesChanged_TwoProjectReferencesChainToModifiedProject_NotifyReferencesChangedForAllProjects2 () + { + var dotNetProject = CreateDotNetCoreProject (); + AddParentSolution (dotNetProject); + var referencingProject1 = CreateDotNetCoreProject (); + var referencingProject2 = CreateDotNetCoreProject (); + dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject2); + dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject1); + referencingProject1.References.Add (ProjectReference.CreateProjectReference (dotNetProject)); + referencingProject2.References.Add (ProjectReference.CreateProjectReference (referencingProject1)); + string modifiedHint = null; + dotNetProject.Modified += (sender, e) => { + modifiedHint = e.First ().Hint; + }; + string modifiedHintForReferencingProject1 = null; + referencingProject1.Modified += (sender, e) => { + modifiedHintForReferencingProject1 = e.First ().Hint; + }; + string modifiedHintForReferencingProject2 = null; + referencingProject2.Modified += (sender, e) => { + modifiedHintForReferencingProject2 = e.First ().Hint; + }; + + dotNetProject.DotNetCoreNotifyReferencesChanged (); + + Assert.AreEqual ("References", modifiedHint); + Assert.AreEqual ("References", modifiedHintForReferencingProject1); + Assert.AreEqual ("References", modifiedHintForReferencingProject2); + }
+
+ [Test]
+ public void GetReferencingProjects_ThreeProjectsOneProjectReferencesModifiedProject_OneProjectReturned ()
+ {
+ var dotNetProject = CreateDotNetCoreProject ();
+ AddParentSolution (dotNetProject);
+ var referencedProject = CreateDotNetCoreProject ();
+ dotNetProject.ParentSolution.RootFolder.AddItem (referencedProject);
+ referencedProject.References.Add (ProjectReference.CreateProjectReference (dotNetProject));
+ var otherProject = CreateDotNetCoreProject ();
+ dotNetProject.ParentSolution.RootFolder.AddItem (otherProject);
+
+ var projects = dotNetProject.GetReferencingProjects ().ToList ();
+
+ Assert.AreEqual (1, projects.Count);
+ Assert.AreEqual (projects[0], referencedProject);
+ }
+
+ [Test]
+ public void GetReferencingProjects_TwoProjectReferencesChainToModifiedProject_NotifyReferencesChangedForAllProjects ()
+ {
+ var dotNetProject = CreateDotNetCoreProject ();
+ AddParentSolution (dotNetProject);
+ var referencingProject1 = CreateDotNetCoreProject ();
+ dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject1);
+ referencingProject1.References.Add (ProjectReference.CreateProjectReference (dotNetProject));
+ var referencingProject2 = CreateDotNetCoreProject ();
+ dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject2);
+ referencingProject2.References.Add (ProjectReference.CreateProjectReference (referencingProject1));
+ var otherProject = CreateDotNetCoreProject ();
+ dotNetProject.ParentSolution.RootFolder.AddItem (otherProject);
+
+ var projects = dotNetProject.GetReferencingProjects ().ToList ();
+
+ Assert.AreEqual (2, projects.Count);
+ Assert.That (projects, Contains.Item (referencingProject1));
+ Assert.That (projects, Contains.Item (referencingProject2));
+ }
}
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/RestoreNuGetPackagesInNuGetIntegratedProjectTests.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/RestoreNuGetPackagesInNuGetIntegratedProjectTests.cs new file mode 100644 index 0000000000..bf48dc9bdd --- /dev/null +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/RestoreNuGetPackagesInNuGetIntegratedProjectTests.cs @@ -0,0 +1,151 @@ +// +// RestoreNuGetPackagesInNuGetIntegratedProjectTests.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.PackageManagement.Tests.Helpers; +using MonoDevelop.Projects; +using NUnit.Framework; +namespace MonoDevelop.PackageManagement.Tests +{ + [TestFixture] + class RestoreNuGetPackagesInNuGetIntegratedProjectTests + { + RestoreNuGetPackagesInNuGetIntegratedProject action; + FakeSolutionManager solutionManager; + FakeSolution fakeSolution; + DotNetProject dotNetProject; + FakeDotNetProject fakeDotNetProject; + TestableDotNetCoreNuGetProject nugetProject; + FakeMonoDevelopBuildIntegratedRestorer buildIntegratedRestorer; + + void CreateProject () + { + solutionManager = new FakeSolutionManager (); + fakeSolution = new FakeSolution (); + CreateNuGetProject (); + fakeDotNetProject = new FakeDotNetProject (dotNetProject.FileName); + fakeDotNetProject.ParentSolution = fakeSolution; + fakeDotNetProject.DotNetProject = dotNetProject; + fakeSolution.Projects.Add (fakeDotNetProject); + } + + void CreateAction (bool restoreTransitiveProjectReferences = false) + { + action = new RestoreNuGetPackagesInNuGetIntegratedProject ( + fakeDotNetProject, + nugetProject, + solutionManager, + buildIntegratedRestorer, + restoreTransitiveProjectReferences); + } + + void CreateNuGetProject (string projectName = "MyProject", string fileName = @"d:\projects\MyProject\MyProject.csproj") + { + dotNetProject = CreateDotNetCoreProject (projectName, fileName); + var solution = new Solution (); + solution.RootFolder.AddItem (dotNetProject); + nugetProject = new TestableDotNetCoreNuGetProject (dotNetProject); + buildIntegratedRestorer = nugetProject.BuildIntegratedRestorer; + } + + TestableDotNetCoreNuGetProject CreateNuGetProject (DotNetProject project) + { + var dotNetProjectProxy = new FakeDotNetProject (); + dotNetProjectProxy.DotNetProject = project; + fakeSolution.Projects.Add (dotNetProjectProxy); + + var dotNetCoreNuGetProject = new TestableDotNetCoreNuGetProject (project); + dotNetCoreNuGetProject.BuildIntegratedRestorer = null; + + solutionManager.NuGetProjectsUsingDotNetProjects.Add (project, dotNetCoreNuGetProject); + + return dotNetCoreNuGetProject; + } + + static DummyDotNetProject CreateDotNetCoreProject (string projectName = "MyProject", string fileName = @"d:\projects\MyProject\MyProject.csproj") + { + var project = new DummyDotNetProject (); + project.Name = projectName; + project.FileName = fileName.ToNativePath (); + return project; + } + + [Test] + public void Execute_BuildIntegratedRestorer_PackagesRestoredForProject () + { + CreateProject (); + CreateAction (); + + action.Execute (); + + Assert.AreEqual (nugetProject, buildIntegratedRestorer.ProjectRestored); + } + + [Test] + public void Execute_Events_PackagesRestoredEventFired () + { + CreateProject (); + CreateAction (); + bool packagesRestoredEventFired = false; + PackageManagementServices.PackageManagementEvents.PackagesRestored += (sender, e) => { + packagesRestoredEventFired = true; + }; + + action.Execute (); + + Assert.IsTrue (packagesRestoredEventFired); + } + + [Test] + public void Execute_ReferenceStatus_IsRefreshed () + { + CreateProject (); + CreateAction (); + + action.Execute (); + + Assert.IsTrue (fakeDotNetProject.IsReferenceStatusRefreshed); + } + + [Test] + public void IncludeTransitiveProjectReferences_ThreeProjectsOneReferencedAnother_TwoProjectsRestored () + { + CreateProject (); + var referencingProject = CreateDotNetCoreProject (); + dotNetProject.ParentSolution.RootFolder.AddItem (referencingProject); + referencingProject.References.Add (ProjectReference.CreateProjectReference (dotNetProject)); + var otherProject = CreateDotNetCoreProject (); + dotNetProject.ParentSolution.RootFolder.AddItem (otherProject); + var referencingNuGetProject = CreateNuGetProject (referencingProject); + CreateAction (true); + + action.Execute (); + + Assert.AreEqual (2, buildIntegratedRestorer.ProjectsRestored.Count); + Assert.AreEqual (buildIntegratedRestorer.ProjectsRestored[0], nugetProject); + Assert.AreEqual (buildIntegratedRestorer.ProjectsRestored[1], referencingNuGetProject); + } + } +} diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.addin.xml b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.addin.xml index 3b548d5dcf..e870fa461b 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.addin.xml +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.addin.xml @@ -113,7 +113,7 @@ <Extension path="/MonoDevelop/Ide/GlobalOptionsDialog">
<Section id="NuGetPackageManagement" _label="NuGet" insertafter="VersionControl">
- <Section id="General" _label="General" fill="true" class="MonoDevelop.PackageManagement.Gui.PackageManagementOptionsPanel" icon="md-prefs-package" />
+ <Section id="NuGetGeneral" _label="General" fill="true" class="MonoDevelop.PackageManagement.Gui.PackageManagementOptionsPanel" icon="md-prefs-package" />
<Section id="PackageSources" _label="Sources" fill="true" class="MonoDevelop.PackageManagement.Gui.PackageSourcesOptionsPanel" icon="md-prefs-package-source" />
</Section>
</Extension>
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj index ecc1b8ec8f..42514317d9 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj @@ -402,6 +402,7 @@ <Compile Include="MonoDevelop.PackageManagement\PackageActionType.cs" /> <Compile Include="MonoDevelop.PackageManagement\PendingPackageActionsHandler.cs" /> <Compile Include="MonoDevelop.PackageManagement\MonoDevelopMSBuildNuGetProject.cs" /> + <Compile Include="MonoDevelop.PackageManagement\IMonoDevelopBuildIntegratedRestorer.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 d4cdbb10fa..bd1900e7ec 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetCoreNuGetProject.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetCoreNuGetProject.cs @@ -270,7 +270,7 @@ namespace MonoDevelop.PackageManagement } Runtime.RunInMainThread (() => { - DotNetProject.NotifyModified ("References"); + DotNetProject.DotNetCoreNotifyReferencesChanged (); }); packageManagementEvents.OnFileChanged (project.GetNuGetAssetsFilePath ()); @@ -281,8 +281,7 @@ namespace MonoDevelop.PackageManagement async Task RestorePackages (INuGetProjectContext nuGetProjectContext, CancellationToken token) { var packageRestorer = await Runtime.RunInMainThread (() => { - var solutionManager = PackageManagementServices.Workspace.GetSolutionManager (project.ParentSolution); - return new MonoDevelopBuildIntegratedRestorer (solutionManager); + return CreateBuildIntegratedRestorer (project.ParentSolution); }); var restoreTask = packageRestorer.RestorePackages (this, token); @@ -293,7 +292,7 @@ namespace MonoDevelop.PackageManagement if (!packageRestorer.LockFileChanged) { // Need to refresh the references since the restore did not. await Runtime.RunInMainThread (() => { - DotNetProject.NotifyModified ("References"); + DotNetProject.DotNetCoreNotifyReferencesChanged (); packageManagementEvents.OnFileChanged (project.GetNuGetAssetsFilePath ()); }); } @@ -301,6 +300,12 @@ namespace MonoDevelop.PackageManagement await base.PostProcessAsync (nuGetProjectContext, token); } + protected virtual IMonoDevelopBuildIntegratedRestorer CreateBuildIntegratedRestorer (Solution solution) + { + var solutionManager = PackageManagementServices.Workspace.GetSolutionManager (project.ParentSolution); + return new MonoDevelopBuildIntegratedRestorer (solutionManager); + } + public void OnBeforeUninstall (IEnumerable<NuGetProjectAction> actions) { } @@ -310,12 +315,16 @@ namespace MonoDevelop.PackageManagement restoreRequired = actions.Any (action => action.NuGetProjectActionType == NuGetProjectActionType.Install); } - public void NotifyProjectReferencesChanged () + public void NotifyProjectReferencesChanged (bool includeTransitiveProjectReferences) { Runtime.AssertMainThread (); DotNetProject.RefreshProjectBuilder (); - DotNetProject.NotifyModified ("References"); + + if (includeTransitiveProjectReferences) + DotNetProject.DotNetCoreNotifyReferencesChanged (); + else + DotNetProject.NotifyModified ("References"); } /// <summary> diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs index fb79aee86b..4d230bb4e3 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetProjectExtensions.cs @@ -216,5 +216,97 @@ namespace MonoDevelop.PackageManagement return File.Exists (propsFileName) &&
File.Exists (targetsFileName);
}
+
+ /// <summary>
+ /// If a NuGet package is installed into a .NET Core project then all .NET Core projects that
+ /// reference this project need to have their reference information updated. This allows the
+ /// assemblies from the NuGet package to be made available to the other projects since .NET
+ /// Core projects support transitive references. This method calls NotifyModified for each
+ /// project that references it, as well as for the project itself, passing the hint 'References'
+ /// which will cause the type system to refresh its reference information, which will be taken
+ /// from MSBuild.
+ ///
+ /// All projects that reference .NET Core projects will have their references refreshed. If a
+ /// .NET Framework project (non SDK), has PackageReferences and references a .NET Standard project
+ /// (SDK project) then NuGet dependencies from the .NET Standard project are available to the
+ /// .NET Framework project transitively without needing the NuGet package to be installed into
+ /// the .NET Framework project. So refreshing the references of any project that references a
+ /// .NET Core project will ensure assemblies from NuGet packages are available after installing
+ /// a new NuGet package into the referenced project.
+ /// </summary>
+ /// <param name="project">.NET Core project</param>
+ /// <param name="transitiveOnly">If false then the project passed will also have its
+ /// references refreshed. Otherwise only the projects that reference the project will
+ /// have their references refreshed.</param>
+ public static void DotNetCoreNotifyReferencesChanged (this DotNetProject project, bool transitiveOnly = false)
+ {
+ if (!transitiveOnly)
+ project.NotifyModified ("References");
+
+ foreach (var referencingProject in project.GetReferencingProjects ()) {
+ referencingProject.NotifyModified ("References");
+ }
+ }
+
+ /// <summary>
+ /// Returns all projects that directly or indirectly referencing the specified project.
+ /// </summary>
+ public static IEnumerable<DotNetProject> GetReferencingProjects (this DotNetProject project)
+ {
+ var projects = new List<DotNetProject> ();
+ var traversedProjects = new Dictionary<string, bool> (StringComparer.OrdinalIgnoreCase);
+ traversedProjects.Add (project.ItemId, true);
+
+ foreach (var currentProject in project.ParentSolution.GetAllDotNetProjects ()) {
+ if (!traversedProjects.ContainsKey (currentProject.ItemId))
+ GetReferencingProjects (project, currentProject, traversedProjects, projects);
+ }
+
+ return projects;
+ }
+
+ static bool GetReferencingProjects (
+ DotNetProject mainProject,
+ DotNetProject project,
+ Dictionary<string, bool> traversedProjects,
+ List<DotNetProject> referencingProjects)
+ {
+ foreach (var projectReference in project.References.Where (IncludeProjectReference)) {
+ var resolvedProject = projectReference.ResolveProject (mainProject.ParentSolution) as DotNetProject;
+ if (resolvedProject == null)
+ continue;
+
+ if (resolvedProject == mainProject) {
+ traversedProjects [project.ItemId] = true;
+ referencingProjects.Add (project);
+ return true;
+ }
+
+ if (traversedProjects.TryGetValue (resolvedProject.ItemId, out bool referencesProject)) {
+ if (referencesProject) {
+ traversedProjects [project.ItemId] = referencesProject;
+ referencingProjects.Add (project);
+ return true;
+ }
+ continue;
+ }
+
+ if (GetReferencingProjects (mainProject, resolvedProject, traversedProjects, referencingProjects)) {
+ traversedProjects [project.ItemId] = true;
+ referencingProjects.Add (project);
+ return true;
+ }
+ }
+
+ traversedProjects [project.ItemId] = false;
+
+ return false;
+ }
+
+ static bool IncludeProjectReference (ProjectReference projectReference)
+ {
+ return projectReference.ReferenceType == ReferenceType.Project &&
+ projectReference.ReferenceOutputAssembly;
+ }
}
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/IBuildIntegratedNuGetProject.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/IBuildIntegratedNuGetProject.cs index b14d19a7ba..666e49130f 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/IBuildIntegratedNuGetProject.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/IBuildIntegratedNuGetProject.cs @@ -37,7 +37,13 @@ namespace MonoDevelop.PackageManagement void OnBeforeUninstall (IEnumerable<NuGetProjectAction> actions); void OnAfterExecuteActions (IEnumerable<NuGetProjectAction> actions); Task PostProcessAsync (INuGetProjectContext nuGetProjectContext, CancellationToken token); - void NotifyProjectReferencesChanged (); + + /// <summary> + /// Notifies the project references changed. + /// </summary> + /// <param name="includeTransitiveProjectReferences">If set to <c>true</c> also notify references + /// have changed in all projects that transitively reference this project.</param> + void NotifyProjectReferencesChanged (bool includeTransitiveProjectReferences); } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/IMonoDevelopBuildIntegratedRestorer.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/IMonoDevelopBuildIntegratedRestorer.cs new file mode 100644 index 0000000000..8c693b321e --- /dev/null +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/IMonoDevelopBuildIntegratedRestorer.cs @@ -0,0 +1,46 @@ +// +// IMonoDevelopBuildIntegratedRestorer.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.Threading;
+using System.Threading.Tasks; +using NuGet.ProjectManagement.Projects; + +namespace MonoDevelop.PackageManagement +{ + interface IMonoDevelopBuildIntegratedRestorer + { + Task RestorePackages ( + BuildIntegratedNuGetProject project, + CancellationToken cancellationToken); + + Task RestorePackages ( + IEnumerable<BuildIntegratedNuGetProject> projects, + CancellationToken cancellationToken); + + bool LockFileChanged { get; } + } +} diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopBuildIntegratedRestorer.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopBuildIntegratedRestorer.cs index c59a3bdb82..977892b125 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopBuildIntegratedRestorer.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopBuildIntegratedRestorer.cs @@ -44,7 +44,7 @@ using NuGet.Protocol.Core.Types; namespace MonoDevelop.PackageManagement
{
- internal class MonoDevelopBuildIntegratedRestorer
+ internal class MonoDevelopBuildIntegratedRestorer : IMonoDevelopBuildIntegratedRestorer
{
IPackageManagementEvents packageManagementEvents;
List<SourceRepository> sourceRepositories;
@@ -98,8 +98,10 @@ namespace MonoDevelop.PackageManagement LockFileChanged = true; await Runtime.RunInMainThread (() => { FileService.NotifyFilesChanged (changedLocks); - foreach (var project in affectedProjects) { - NotifyProjectReferencesChanged (project); + foreach (var project in affectedProjects) {
+ // Restoring the entire solution so do not refresh references for
+ // transitive project references since they should be refreshed anyway. + NotifyProjectReferencesChanged (project, includeTransitiveProjectReferences: false); } }); }
@@ -114,12 +116,17 @@ namespace MonoDevelop.PackageManagement var changedLock = await RestorePackagesInternal (project, cancellationToken); if (projectToReload != null) {
- await ReloadProject (projectToReload, changedLock);
+ // Need to ensure transitive project references are refreshed if only the single
+ // project is reloaded since they will still be out of date.
+ await ReloadProject (projectToReload, changedLock, refreshTransitiveReferences: true);
} else if (changedLock != null) { LockFileChanged = true;
await Runtime.RunInMainThread (() => { - FileService.NotifyFileChanged (changedLock); - NotifyProjectReferencesChanged (project); + FileService.NotifyFileChanged (changedLock);
+
+ // Restoring a single project so ensure references are refreshed for
+ // transitive project references. + NotifyProjectReferencesChanged (project, includeTransitiveProjectReferences: true); }); } } @@ -152,11 +159,13 @@ namespace MonoDevelop.PackageManagement return null; } - static void NotifyProjectReferencesChanged (BuildIntegratedNuGetProject project) + static void NotifyProjectReferencesChanged (
+ BuildIntegratedNuGetProject project,
+ bool includeTransitiveProjectReferences) { var buildIntegratedProject = project as IBuildIntegratedNuGetProject; if (buildIntegratedProject != null) {
- buildIntegratedProject.NotifyProjectReferencesChanged (); + buildIntegratedProject.NotifyProjectReferencesChanged (includeTransitiveProjectReferences); } }
@@ -190,7 +199,7 @@ namespace MonoDevelop.PackageManagement return null;
}
- Task ReloadProject (DotNetProject projectToReload, string changedLock)
+ Task ReloadProject (DotNetProject projectToReload, string changedLock, bool refreshTransitiveReferences = false)
{
return Runtime.RunInMainThread (async () => {
if (changedLock != null) {
@@ -198,6 +207,9 @@ namespace MonoDevelop.PackageManagement FileService.NotifyFileChanged (changedLock);
}
await projectToReload.ReevaluateProject (new ProgressMonitor ());
+
+ if (refreshTransitiveReferences)
+ projectToReload.DotNetCoreNotifyReferencesChanged (transitiveOnly: true);
});
}
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageReferenceNuGetProject.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageReferenceNuGetProject.cs index 5e5f23db73..3cd19824ce 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageReferenceNuGetProject.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageReferenceNuGetProject.cs @@ -273,7 +273,7 @@ namespace MonoDevelop.PackageManagement { } - public void NotifyProjectReferencesChanged () + public void NotifyProjectReferencesChanged (bool includeTransitiveProjectReferences) { Runtime.AssertMainThread (); diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageSearchResultViewModel.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageSearchResultViewModel.cs index 9a6d0d9f06..2005caeaf0 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageSearchResultViewModel.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageSearchResultViewModel.cs @@ -167,6 +167,11 @@ namespace MonoDevelop.PackageManagement get { return viewModel.DownloadCount >= 0; }
}
+ public string GetIdMarkup ()
+ {
+ return GetBoldText (Id);
+ }
+
public string GetNameMarkup ()
{
return GetBoldText (Name);
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectJsonBuildIntegratedNuGetProject.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectJsonBuildIntegratedNuGetProject.cs index 02ef5caddd..9c3086648a 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectJsonBuildIntegratedNuGetProject.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectJsonBuildIntegratedNuGetProject.cs @@ -123,7 +123,7 @@ namespace MonoDevelop.PackageManagement packageManagementEvents.OnPackageUninstalled (dotNetProject, eventArgs);
}
- public void NotifyProjectReferencesChanged ()
+ public void NotifyProjectReferencesChanged (bool includeTransitiveProjectReferences)
{
Runtime.AssertMainThread ();
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RestoreNuGetPackagesInNuGetIntegratedProject.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RestoreNuGetPackagesInNuGetIntegratedProject.cs index 7b796c7b1c..e5cef02523 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RestoreNuGetPackagesInNuGetIntegratedProject.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RestoreNuGetPackagesInNuGetIntegratedProject.cs @@ -24,6 +24,8 @@ // 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 MonoDevelop.Core;
@@ -34,21 +36,42 @@ namespace MonoDevelop.PackageManagement {
internal class RestoreNuGetPackagesInNuGetIntegratedProject : IPackageAction
{
- DotNetProject project;
+ IDotNetProject project;
BuildIntegratedNuGetProject nugetProject;
- MonoDevelopBuildIntegratedRestorer packageRestorer;
+ IMonoDevelopSolutionManager solutionManager;
+ IMonoDevelopBuildIntegratedRestorer packageRestorer;
IPackageManagementEvents packageManagementEvents;
+ List<BuildIntegratedNuGetProject> referencingProjects;
public RestoreNuGetPackagesInNuGetIntegratedProject (
DotNetProject project,
BuildIntegratedNuGetProject nugetProject,
- IMonoDevelopSolutionManager solutionManager)
+ IMonoDevelopSolutionManager solutionManager,
+ bool restoreTransitiveProjectReferences = false)
+ : this (
+ new DotNetProjectProxy (project),
+ nugetProject,
+ solutionManager,
+ new MonoDevelopBuildIntegratedRestorer (solutionManager),
+ restoreTransitiveProjectReferences)
+ {
+ }
+
+ public RestoreNuGetPackagesInNuGetIntegratedProject (
+ IDotNetProject project,
+ BuildIntegratedNuGetProject nugetProject,
+ IMonoDevelopSolutionManager solutionManager,
+ IMonoDevelopBuildIntegratedRestorer packageRestorer,
+ bool restoreTransitiveProjectReferences)
{
this.project = project;
this.nugetProject = nugetProject;
+ this.solutionManager = solutionManager;
+ this.packageRestorer = packageRestorer;
packageManagementEvents = PackageManagementServices.PackageManagementEvents;
- - packageRestorer = new MonoDevelopBuildIntegratedRestorer (solutionManager); +
+ if (restoreTransitiveProjectReferences)
+ IncludeTransitiveProjectReferences (); }
public PackageActionType ActionType {
@@ -75,12 +98,44 @@ namespace MonoDevelop.PackageManagement async Task ExecuteAsync (CancellationToken cancellationToken)
{
- await packageRestorer.RestorePackages (nugetProject, cancellationToken);
+ if (referencingProjects == null)
+ await packageRestorer.RestorePackages (nugetProject, cancellationToken);
+ else
+ await RestoreMultiplePackages (cancellationToken);
await Runtime.RunInMainThread (() => project.RefreshReferenceStatus ());
packageManagementEvents.OnPackagesRestored ();
}
+
+ /// <summary>
+ /// Execute will restore packages for all projects that transitively reference the project
+ /// passed to the constructor of this restore action if this method is passed.
+ /// </summary>
+ void IncludeTransitiveProjectReferences ()
+ {
+ var projects = project.DotNetProject.GetReferencingProjects ();
+ if (!projects.Any ())
+ return;
+
+ referencingProjects = new List<BuildIntegratedNuGetProject> ();
+ foreach (var referencingProject in projects) {
+ var projectProxy = new DotNetProjectProxy (referencingProject);
+ var currentNuGetProject = solutionManager.GetNuGetProject (projectProxy) as BuildIntegratedNuGetProject;
+ if (currentNuGetProject != null) {
+ referencingProjects.Add (currentNuGetProject);
+ }
+ }
+ }
+
+ Task RestoreMultiplePackages (CancellationToken cancellationToken)
+ {
+ var projects = new List<BuildIntegratedNuGetProject> ();
+ projects.Add (nugetProject);
+ projects.AddRange (referencingProjects);
+
+ return packageRestorer.RestorePackages (projects, cancellationToken);
+ }
}
}
diff --git a/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging.Gui/GtkNuGetPackageMetadataOptionsPanelWidget.cs b/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging.Gui/GtkNuGetPackageMetadataOptionsPanelWidget.cs index 0008cbeaf2..3f6f091de5 100644 --- a/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging.Gui/GtkNuGetPackageMetadataOptionsPanelWidget.cs +++ b/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging.Gui/GtkNuGetPackageMetadataOptionsPanelWidget.cs @@ -54,6 +54,9 @@ namespace MonoDevelop.Packaging.Gui void SetupAccessibility () { + packageDescriptionPaddingLabel.Accessible.Role = Atk.Role.Filler; + packageReleaseNotesPaddingLabel.Accessible.Role = Atk.Role.Filler; + packageIdTextBox.SetCommonAccessibilityAttributes ("NuGetMetadata.ID", GettextCatalog.GetString ("ID"), GettextCatalog.GetString ("Enter the ID of the NuGet package")); @@ -133,6 +136,7 @@ namespace MonoDevelop.Packaging.Gui GettextCatalog.GetString ("Release Notes"), GettextCatalog.GetString ("Enter the release notes for this NuGet package")); packageReleaseNotesTextView.SetAccessibilityLabelRelationship (packageReleaseNotesLabel); + } internal static System.Action<bool> OnProjectHasMetadataChanged; diff --git a/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging/MSBuildGlobalPropertyProvider.cs b/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging/MSBuildGlobalPropertyProvider.cs index a8d71b8ddf..8d7d050b1d 100644 --- a/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging/MSBuildGlobalPropertyProvider.cs +++ b/main/src/addins/MonoDevelop.Packaging/MonoDevelop.Packaging/MSBuildGlobalPropertyProvider.cs @@ -33,7 +33,7 @@ namespace MonoDevelop.Packaging { class MSBuildGlobalPropertyProvider : IMSBuildGlobalPropertyProvider { - Dictionary<string, string> properties; + Lazy<Dictionary<string, string>> properties = new Lazy<Dictionary<string, string>> (CreateProperties); #pragma warning disable 67 public event EventHandler GlobalPropertiesChanged; @@ -41,13 +41,17 @@ namespace MonoDevelop.Packaging public IDictionary<string, string> GetGlobalProperties () { - if (properties == null) { - string addinDirectory = Path.GetDirectoryName (GetType ().Assembly.Location); - string targetsDirectory = Path.Combine (addinDirectory, "Targets"); + return properties.Value; + } + + static Dictionary<string, string> CreateProperties () + { + string addinDirectory = Path.GetDirectoryName (typeof (MSBuildGlobalPropertyProvider).Assembly.Location); + string targetsDirectory = Path.Combine (addinDirectory, "Targets"); + + var properties = new Dictionary<string, string> (); + properties.Add ("NuGetAuthoringPath", targetsDirectory); - properties = new Dictionary<string, string> (); - properties.Add ("NuGetAuthoringPath", targetsDirectory); - } return properties; } } diff --git a/main/src/addins/MonoDevelop.Packaging/PostBuild.proj b/main/src/addins/MonoDevelop.Packaging/PostBuild.proj index 0cbc3eba24..881103530a 100644 --- a/main/src/addins/MonoDevelop.Packaging/PostBuild.proj +++ b/main/src/addins/MonoDevelop.Packaging/PostBuild.proj @@ -7,6 +7,6 @@ <_MyNuGetPackage Include="$(MSBuildProjectDirectory)\..\..\..\packages\NuGet.Build.Packaging.$(_BuildPackagingVersion)\NuGet.Build.Packaging.$(_BuildPackagingVersion).nupkg" /> </ItemGroup> <Target Name="_MyPostBuildTarget"> - <Copy SourceFiles="@(_MyNuGetPackage)" DestinationFolder="$(OutputPath)\packages" /> + <Copy SourceFiles="@(_MyNuGetPackage)" DestinationFolder="$(OutputPath)\packages" SkipUnchangedFiles="true" /> </Target> </Project>
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/RefactoringPreviewTooltipWindow.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/RefactoringPreviewTooltipWindow.cs index 5a3e11c048..bf095d965d 100644 --- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/RefactoringPreviewTooltipWindow.cs +++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/RefactoringPreviewTooltipWindow.cs @@ -38,6 +38,7 @@ using System.Linq; using MonoDevelop.Core; using Pango; using MonoDevelop.Ide.Editor.Highlighting; +using Gdk; namespace MonoDevelop.Refactoring { @@ -113,10 +114,25 @@ namespace MonoDevelop.Refactoring } catch (OperationCanceledException) {} return new List<DiffHunk> (); }); - if (diff.Count > 0 && !token.IsCancellationRequested) - ShowPopup (rect, PopupPosition.Left); + if (diff.Count > 0 && !token.IsCancellationRequested) { + var pos = PopupPosition.Left; + if (Platform.IsMac) { + var screenRect = GtkUtil.ToScreenCoordinates (IdeApp.Workbench.RootWindow, IdeApp.Workbench.RootWindow.GdkWindow, rect.ToGdkRectangle ()); + var geometry = Screen.GetUsableMonitorGeometry (Screen.GetMonitorAtPoint (screenRect.X, screenRect.Y)); + var request = SizeRequest (); + if (screenRect.X - geometry.X < request.Width) { + pos = PopupPosition.Top; + if (geometry.Bottom - screenRect.Bottom < request.Height) + pos = PopupPosition.Bottom; + } else { + pos = PopupPosition.Right; + } + } + ShowPopup (rect, pos); + } } + protected override void OnDestroyed () { popupSrc.Cancel (); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/CompletionOptionsPanel.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/CompletionOptionsPanel.cs index 1b93094ec8..e03bfce0aa 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/CompletionOptionsPanel.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.OptionPanels/CompletionOptionsPanel.cs @@ -65,9 +65,9 @@ namespace MonoDevelop.SourceEditor.OptionPanels includeCodeSnippetsCheckbutton.Active = IdeApp.Preferences.IncludeCodeSnippetsInCompletionList; automaticCompletionModeCheckbutton.Active = !IdeApp.Preferences.ForceSuggestionMode; - insertParenthesesCheckbutton.Active = IdeApp.Preferences.AddParenthesesAfterCompletion; - openingRadiobutton.Active = IdeApp.Preferences.AddOpeningOnly; - bothRadiobutton.Active = !IdeApp.Preferences.AddOpeningOnly; + insertParenthesesCheckbutton.Visible = false; + openingRadiobutton.Visible = false; + bothRadiobutton.Visible = false; InsertParensToggled (this, EventArgs.Empty); AutomaticCompletionToggled (this, EventArgs.Empty); @@ -97,9 +97,6 @@ namespace MonoDevelop.SourceEditor.OptionPanels IdeApp.Preferences.IncludeKeywordsInCompletionList.Value = includeKeywordsCheckbutton.Active; IdeApp.Preferences.IncludeCodeSnippetsInCompletionList.Value = includeCodeSnippetsCheckbutton.Active; IdeApp.Preferences.ForceSuggestionMode.Value = !automaticCompletionModeCheckbutton.Active; - - IdeApp.Preferences.AddParenthesesAfterCompletion.Value = insertParenthesesCheckbutton.Active; - IdeApp.Preferences.AddOpeningOnly.Value = openingRadiobutton.Active; } #endregion diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskStrip.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskStrip.cs index 9174d68d10..cfef8d4174 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskStrip.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskStrip.cs @@ -130,6 +130,8 @@ namespace MonoDevelop.SourceEditor.QuickTasks Events |= EventMask.ButtonPressMask; Accessible.Name = "MainWindow.QuickTaskStrip"; + Accessible.SetShouldIgnore (false); + Accessible.SetRole (AtkCocoa.Roles.AXRuler); Accessible.SetLabel (GettextCatalog.GetString ("Quick Task Strip")); Accessible.Description = GettextCatalog.GetString ("An overview of the current file's messages, warnings and errors"); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.Wrappers/SemanticHighlightingSyntaxMode.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.Wrappers/SemanticHighlightingSyntaxMode.cs index 948f9b1838..fb40caca1c 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.Wrappers/SemanticHighlightingSyntaxMode.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.Wrappers/SemanticHighlightingSyntaxMode.cs @@ -81,7 +81,6 @@ namespace MonoDevelop.SourceEditor.Wrappers } bool isDisposed; - Queue<Tuple<IDocumentLine, HighlightingSegmentTree>> lineSegments = new Queue<Tuple<IDocumentLine, HighlightingSegmentTree>> (); public SemanticHighlightingSyntaxMode (ExtensibleTextEditor editor, ISyntaxHighlighting syntaxMode, SemanticHighlighting semanticHighlighting) { @@ -113,9 +112,6 @@ namespace MonoDevelop.SourceEditor.Wrappers Application.Invoke ((o, args) => { if (isDisposed) return; - UnregisterLineSegmentTrees (); - lineSegments.Clear (); - var margin = editor.TextViewMargin; if (margin == null) return; @@ -124,26 +120,12 @@ namespace MonoDevelop.SourceEditor.Wrappers }); } - void UnregisterLineSegmentTrees () - { - if (isDisposed) - return; - foreach (var kv in lineSegments) { - try { - kv.Item2.RemoveListener (); - } catch (Exception) { - } - } - } - public void Dispose() { if (isDisposed) return; // Unregister before setting isDisposed=true, as that causes the method to bail out early. - UnregisterLineSegmentTrees (); isDisposed = true; - lineSegments = null; semanticHighlighting.SemanticHighlightingUpdated -= SemanticHighlighting_SemanticHighlightingUpdated; } @@ -153,54 +135,35 @@ namespace MonoDevelop.SourceEditor.Wrappers { if (line == null) throw new ArgumentNullException (nameof (line)); + if (!DefaultSourceEditorOptions.Instance.EnableSemanticHighlighting) { return await syntaxMode.GetHighlightedLineAsync (line, cancellationToken); } var syntaxLine = await syntaxMode.GetHighlightedLineAsync (line, cancellationToken).ConfigureAwait (false); - if (syntaxLine.Segments.Count == 0) + if (syntaxLine.Segments.Count == 0) { return syntaxLine; - lock (lineSegments) { - var segments = new List<ColoredSegment> (syntaxLine.Segments); - int endOffset = segments [segments.Count - 1].EndOffset; - try { - Tuple<IDocumentLine, HighlightingSegmentTree> tree = null; - - // This code should not have any lambda capture linq, as it is a hot loop. - int lineOffset = line.Offset; - foreach (var segment in lineSegments) {
- if (segment.Item1.Offset == lineOffset) {
- tree = segment;
- break;
- }
- }
- if (tree == null) { - tree = Tuple.Create (line, new HighlightingSegmentTree ()); - tree.Item2.InstallListener (editor.Document); - foreach (var seg2 in semanticHighlighting.GetColoredSegments (new TextSegment (lineOffset, line.Length))) { - tree.Item2.AddStyle (seg2, seg2.ColorStyleKey); - } - while (lineSegments.Count > MaximumCachedLineSegments) { - var removed = lineSegments.Dequeue (); - try { - removed.Item2.RemoveListener (); - } catch (Exception) { } - } - lineSegments.Enqueue (tree); - } - foreach (var treeseg in tree.Item2.GetSegmentsOverlapping (line)) { - var inLineStartOffset = Math.Max (0, treeseg.Offset - lineOffset); - var inLineEndOffset = Math.Min (line.Length, treeseg.EndOffset - lineOffset); - if (inLineEndOffset <= inLineStartOffset) - continue; - var semanticSegment = new ColoredSegment (inLineStartOffset, inLineEndOffset - inLineStartOffset, syntaxLine.Segments [0].ScopeStack.Push (treeseg.Style)); - SyntaxHighlighting.ReplaceSegment (segments, semanticSegment); + } + var segments = new List<ColoredSegment> (syntaxLine.Segments); + int endOffset = segments [segments.Count - 1].EndOffset; + try { + // This code should not have any lambda capture linq, as it is a hot loop. + int lineOffset = line.Offset; + + foreach (var treeseg in semanticHighlighting.GetColoredSegments (new TextSegment (lineOffset, line.Length))) { + var inLineStartOffset = Math.Max (0, treeseg.Offset - lineOffset); + var inLineEndOffset = Math.Min (line.Length, treeseg.EndOffset - lineOffset); + + if (inLineEndOffset <= inLineStartOffset) { + continue; } - } catch (Exception e) { - LoggingService.LogError ("Error in semantic highlighting: " + e); - return syntaxLine; + var semanticSegment = new ColoredSegment (inLineStartOffset, inLineEndOffset - inLineStartOffset, treeseg.ScopeStack); + SyntaxHighlighting.ReplaceSegment (segments, semanticSegment); } - return new HighlightedLine (line, segments); + } catch (Exception e) { + LoggingService.LogError ("Error in semantic highlighting: " + e); + return syntaxLine; } + return new HighlightedLine (line, segments); } async Task<ScopeStack> ISyntaxHighlighting.GetScopeStackAsync (int offset, CancellationToken cancellationToken) diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/EditActions.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/EditActions.cs index 564f7a772d..976c8c6893 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/EditActions.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/EditActions.cs @@ -75,21 +75,23 @@ namespace MonoDevelop.SourceEditor { if (!data.IsSomethingSelected && MonoDevelop.Ide.Editor.DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket) { if (data.Caret.Offset > 0) { - var stack = await data.Document.SyntaxMode.GetScopeStackAsync (data.Caret.Offset, CancellationToken.None); - if (stack.Any (s => s.Contains ("string"))) { - DeleteActions.Backspace (data); - return; - } - char ch = data.Document.GetCharAt (data.Caret.Offset - 1); + DeleteActions.Backspace (data); + if (data.Caret.Offset > 0) { + var stack = await data.Document.SyntaxMode.GetScopeStackAsync (data.Caret.Offset - 1, CancellationToken.None); + if (stack.Any (s => s.Contains ("string") || s.Contains ("comment"))) { + return; + } + } + int idx = open.IndexOf (ch); - if (idx >= 0) { int nextCharOffset = GetNextNonWsCharOffset (data, data.Caret.Offset); if (nextCharOffset >= 0 && closing[idx] == data.Document.GetCharAt (nextCharOffset)) { data.Remove (data.Caret.Offset, nextCharOffset - data.Caret.Offset + 1); } } + return; } } DeleteActions.Backspace (data); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorWidget.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorWidget.cs index 579854ddc2..70bfadff65 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorWidget.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorWidget.cs @@ -236,6 +236,7 @@ namespace MonoDevelop.SourceEditor scrolledBackground = new EventBox (); scrolledBackground.Accessible.SetShouldIgnore (true); scrolledWindow = new CompactScrolledWindow (); + scrolledWindow.CanFocus = false; scrolledWindow.ButtonPressEvent += PrepareEvent; scrolledWindow.Accessible.SetShouldIgnore (true); scrolledBackground.Add (scrolledWindow); diff --git a/main/src/addins/MonoDevelop.WebReferences/MonoDevelop.WebReferences.Dialogs/WebReferenceDialog.cs b/main/src/addins/MonoDevelop.WebReferences/MonoDevelop.WebReferences.Dialogs/WebReferenceDialog.cs index dd598d13c6..234deb1883 100644 --- a/main/src/addins/MonoDevelop.WebReferences/MonoDevelop.WebReferences.Dialogs/WebReferenceDialog.cs +++ b/main/src/addins/MonoDevelop.WebReferences/MonoDevelop.WebReferences.Dialogs/WebReferenceDialog.cs @@ -7,6 +7,7 @@ using System.Threading; using Gtk; using MonoDevelop.Core; +using MonoDevelop.Core.Assemblies; using MonoDevelop.Ide.Gui; using MonoDevelop.Ide.WebBrowser; using MonoDevelop.WebReferences; @@ -149,7 +150,7 @@ namespace MonoDevelop.WebReferences.Dialogs #endregion #region Member Variables - const string homeUrl = "http://www.w3schools.com/xml/tempconvert.asmx"; + const string homeUrl = "https://www.w3schools.com/xml/tempconvert.asmx?WSDL"; WebServiceDiscoveryResult selectedService; // protected Gtk.Alignment frmBrowserAlign; #endregion @@ -491,7 +492,15 @@ namespace MonoDevelop.WebReferences.Dialogs btnOK.Sensitive = isWebService; tlbNavigate.Visible = WebBrowserService.CanGetWebBrowser; tbxReferenceName.Sensitive = isWebService; - comboModel.Sensitive = !project.IsPortableLibrary; + if (project.IsPortableLibrary) + comboModel.Sensitive = false; + else if (IsWcfSupported ()) + comboModel.Sensitive = true; + else { + // Select web references instead of WCF. + comboModel.Active = 1; + comboModel.Sensitive = false; + } break; case DialogState.CreateConfig: @@ -595,6 +604,15 @@ namespace MonoDevelop.WebReferences.Dialogs } } + /// <summary> + /// PCL or projects that target .NET Framework are considered to support WCF. + /// </summary> + bool IsWcfSupported () + { + return project.TargetFramework.Id.Identifier == TargetFrameworkMoniker.ID_NET_FRAMEWORK || + project.IsPortableLibrary; + } + protected void OnBtnBackClicked (object sender, EventArgs e) { switch (state) { diff --git a/main/src/addins/PerformanceDiagnostics/PerformanceDiagnostics/Properties/PerformanceDiagnostics.addin.xml b/main/src/addins/PerformanceDiagnostics/PerformanceDiagnostics/Properties/PerformanceDiagnostics.addin.xml index d6ac4b04ff..4f6d2f7c0a 100644 --- a/main/src/addins/PerformanceDiagnostics/PerformanceDiagnostics/Properties/PerformanceDiagnostics.addin.xml +++ b/main/src/addins/PerformanceDiagnostics/PerformanceDiagnostics/Properties/PerformanceDiagnostics.addin.xml @@ -27,7 +27,7 @@ <Section id="PerformanceDiagnostics" _label="Performance Diagnostics" insertafter="VersionControl"> - <Section id="General" + <Section id="PerformanceDiagnosticsGeneral" _label="General" fill="true" class="PerformanceDiagnosticsAddIn.GlobalOptionsPanel" diff --git a/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Templates/T4PreprocessedTemplateCSharp.xft.xml b/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Templates/T4PreprocessedTemplateCSharp.xft.xml index cbd768e485..ca1f305f0d 100644 --- a/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Templates/T4PreprocessedTemplateCSharp.xft.xml +++ b/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Templates/T4PreprocessedTemplateCSharp.xft.xml @@ -16,7 +16,7 @@ <!-- Template Content --> <TemplateFiles> <File name="${Name}.tt" CustomTool="TextTemplatingFilePreprocessor"> - <![CDATA[<#@ template language="C#" #> + <![CDATA[<#@ template language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> diff --git a/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Templates/T4TemplateCSharp.xft.xml b/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Templates/T4TemplateCSharp.xft.xml index c57eab6a4c..a15503a6d0 100644 --- a/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Templates/T4TemplateCSharp.xft.xml +++ b/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Templates/T4TemplateCSharp.xft.xml @@ -15,7 +15,7 @@ <!-- Template Content --> <TemplateFiles> <File name="${Name}.tt" CustomTool="TextTemplatingFileGenerator"> - <![CDATA[<#@ template language="C#" #> + <![CDATA[<#@ template language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextLinkEditMode.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextLinkEditMode.cs index f5a563ae55..ad4d1e382b 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextLinkEditMode.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextLinkEditMode.cs @@ -219,12 +219,21 @@ namespace Mono.TextEditor handler (this, e); } - TextLink closedLink = null; + TextLink closedLink = null, currentSelectedLink = null; void HandlePositionChanged (object sender, DocumentLocationEventArgs e) { int caretOffset = Editor.Caret.Offset - baseOffset; TextLink link = links.Find (l => !l.PrimaryLink.IsInvalid () && l.PrimaryLink.Offset <= caretOffset && caretOffset <= l.PrimaryLink.EndOffset); + + if (link != currentSelectedLink) { + foreach (var l in textLinkMarkers) { + Editor.Document.CommitLineUpdate (l.LineSegment); + } + currentSelectedLink = link; + } + + if (link != null && link.Count > 0 && link.IsEditable) { if (closedLink == link) return; @@ -277,6 +286,7 @@ namespace Mono.TextEditor Editor.Document.CommitUpdateAll (); this.undoDepth = Editor.Document.GetCurrentUndoDepth (); ShowHelpWindow (); + currentSelectedLink = null; } public bool HasChangedText { diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.AddIns/FalseCondition.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.AddIns/FalseCondition.cs new file mode 100644 index 0000000000..cdeb0dc46c --- /dev/null +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.AddIns/FalseCondition.cs @@ -0,0 +1,48 @@ +// +// FalseCondition.cs +// +// Author: +// Lluis Sanchez <llsan@microsoft.com> +// +// Copyright (c) 2017 Microsoft +// +// 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.Core.AddIns +{ + /// <summary> + /// An extension point condition that always evaluates to false + /// </summary> + public class FalseCondition : ConditionType + { + public static readonly FalseCondition Instance = new FalseCondition (); + + FalseCondition () + { + } + + public override bool Evaluate (NodeElement conditionNode) + { + return false; + } + } +} diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.AddIns/TrueCondition.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.AddIns/TrueCondition.cs new file mode 100644 index 0000000000..0ea239feca --- /dev/null +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.AddIns/TrueCondition.cs @@ -0,0 +1,48 @@ +// +// TrueCondition.cs +// +// Author: +// Lluis Sanchez <llsan@microsoft.com> +// +// Copyright (c) 2017 Microsoft +// +// 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.Core.AddIns +{ + /// <summary> + /// An extension point condition that always evaluates to True + /// </summary> + public class TrueCondition : ConditionType + { + public static readonly TrueCondition Instance = new TrueCondition (); + + TrueCondition () + { + } + + public override bool Evaluate (NodeElement conditionNode) + { + return true; + } + } +} diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj index 9aa335506e..a360e71054 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj @@ -1,11 +1,9 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> <Import Project="..\..\..\MonoDevelop.props" /> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <ProductVersion>8.0.30703</ProductVersion> - <SchemaVersion>2.0</SchemaVersion> <ProjectGuid>{7525BB88-6142-4A26-93B9-A30C6983390A}</ProjectGuid> <OutputType>Library</OutputType> <AssemblyName>MonoDevelop.Core</AssemblyName> @@ -99,29 +97,9 @@ <MSBuild_OSS_BinDir Condition="'$(OS)' == 'Unix' and '$(MSBuild_OSS_BinDir)' == '' and Exists('$(MSBuildToolsPath)\..\..\..\msbuild\15.0\bin\MSBuild.dll')">$(MSBuildToolsPath)\..\..\..\msbuild\15.0\bin\</MSBuild_OSS_BinDir> </PropertyGroup> <ItemGroup> - <Reference Include="System" /> - <Reference Include="Mono.Posix" /> - <Reference Include="System.Composition.AttributedModel, Version=1.0.31.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> - <HintPath>..\..\..\packages\System.Composition.AttributedModel.1.0.31\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll</HintPath> - </Reference> - <Reference Include="System.Composition.Hosting, Version=1.0.31.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> - <HintPath>..\..\..\packages\System.Composition.Hosting.1.0.31\lib\portable-net45+win8+wp8+wpa81\System.Composition.Hosting.dll</HintPath> - </Reference> - <Reference Include="System.Composition.Runtime, Version=1.0.31.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> - <HintPath>..\..\..\packages\System.Composition.Runtime.1.0.31\lib\portable-net45+win8+wp8+wpa81\System.Composition.Runtime.dll</HintPath> - </Reference> - <Reference Include="System.Composition.TypedParts, Version=1.0.31.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> - <HintPath>..\..\..\packages\System.Composition.TypedParts.1.0.31\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll</HintPath> + <Reference Include="ICSharpCode.SharpZipLib"> + <HintPath>..\..\..\packages\JetBrains.SharpZipLib.Stripped.0.87.20170615.10\lib\net40\ICSharpCode.SharpZipLib.dll</HintPath> </Reference> - <Reference Include="System.Xml" /> - <Reference Include="System.Runtime.Remoting" /> - <Reference Include="System.Configuration" /> - <Reference Include="System.Core" /> - <Reference Include="monodoc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" /> - <Reference Include="System.Xml.Linq" /> - <Reference Include="System.Web" /> - <Reference Include="System.ServiceModel" /> - <Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.Build"> <HintPath>$(MSBuild_OSS_BinDir)Microsoft.Build.dll</HintPath> <Private>False</Private> @@ -134,24 +112,41 @@ <HintPath>$(MSBuild_OSS_BinDir)Microsoft.Build.Utilities.Core.dll</HintPath> <Private>False</Private> </Reference> - <Reference Include="ICSharpCode.SharpZipLib"> - <HintPath>..\..\..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath> + <Reference Include="Microsoft.CodeAnalysis"> + <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.Common.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.dll</HintPath> + <Private>false</Private> </Reference> - <Reference Include="mscorlib" /> - <Reference Include="System.ComponentModel.Composition" /> - <Reference Include="System.Numerics" /> - <Reference Include="Microsoft.CodeAnalysis.Elfie"> - <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.Elfie.1.0.0-rc9\lib\net45\Microsoft.CodeAnalysis.Elfie.dll</HintPath> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="Mono.Cecil"> + <HintPath>..\..\..\packages\Mono.Cecil.0.10.0-beta5\lib\net40\Mono.Cecil.dll</HintPath> + </Reference> + <Reference Include="Mono.Cecil.Mdb"> + <HintPath>..\..\..\packages\Mono.Cecil.0.10.0-beta5\lib\net40\Mono.Cecil.Mdb.dll</HintPath> + </Reference> + <Reference Include="Mono.Cecil.Pdb"> + <HintPath>..\..\..\packages\Mono.Cecil.0.10.0-beta5\lib\net40\Mono.Cecil.Pdb.dll</HintPath> </Reference> - <Reference Include="System.Composition.Convention"> - <HintPath>..\..\..\packages\Microsoft.Composition.1.0.30\lib\portable-net45+win8+wp8+wpa81\System.Composition.Convention.dll</HintPath> + <Reference Include="Mono.Cecil.Rocks"> + <HintPath>..\..\..\packages\Mono.Cecil.0.10.0-beta5\lib\net40\Mono.Cecil.Rocks.dll</HintPath> </Reference> + <Reference Include="monodoc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" /> + <Reference Include="Mono.Posix" /> + <Reference Include="mscorlib" /> + <Reference Include="Newtonsoft.Json"> + <HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> + </Reference> + <Reference Include="System" /> <Reference Include="System.AppContext"> <HintPath>..\..\..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll</HintPath> </Reference> + <Reference Include="System.Collections.Immutable"> + <HintPath>..\..\..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath> + </Reference> + <Reference Include="System.Configuration" /> <Reference Include="System.Console"> <HintPath>..\..\..\packages\System.Console.4.3.0\lib\net46\System.Console.dll</HintPath> </Reference> + <Reference Include="System.Core" /> <Reference Include="System.Diagnostics.FileVersionInfo"> <HintPath>..\..\..\packages\System.Diagnostics.FileVersionInfo.4.3.0\lib\net46\System.Diagnostics.FileVersionInfo.dll</HintPath> </Reference> @@ -161,11 +156,22 @@ <Reference Include="System.IO.Compression"> <HintPath>..\..\..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath> </Reference> + <Reference Include="System.IO.FileSystem"> + <HintPath>..\..\..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath> + </Reference> <Reference Include="System.IO.FileSystem.Primitives"> <HintPath>..\..\..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath> </Reference> - <Reference Include="System.IO.FileSystem"> - <HintPath>..\..\..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath> + <Reference Include="System.Runtime.Remoting" /> + <!-- NOTE: NuGet installs the PCL version of System.Reflection.Metadata by default but it is windows-specific. Use netstandard version instead. --> + <Reference Include="System.Reflection.Metadata"> + <HintPath>..\..\..\packages\System.Reflection.Metadata.1.4.2\lib\netstandard1.1\System.Reflection.Metadata.dll</HintPath> + </Reference> + <Reference Include="System.Runtime.InteropServices.RuntimeInformation"> + <HintPath>..\..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath> + </Reference> + <Reference Include="System.Security.Cryptography.Algorithms"> + <HintPath>..\..\..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll</HintPath> </Reference> <Reference Include="System.Security.Cryptography.Encoding"> <HintPath>..\..\..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath> @@ -173,12 +179,10 @@ <Reference Include="System.Security.Cryptography.Primitives"> <HintPath>..\..\..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath> </Reference> - <Reference Include="System.Security.Cryptography.Algorithms"> - <HintPath>..\..\..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll</HintPath> - </Reference> <Reference Include="System.Security.Cryptography.X509Certificates"> <HintPath>..\..\..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath> </Reference> + <Reference Include="System.ServiceModel" /> <Reference Include="System.Text.Encoding.CodePages"> <HintPath>..\..\..\packages\System.Text.Encoding.CodePages.4.3.0\lib\net46\System.Text.Encoding.CodePages.dll</HintPath> </Reference> @@ -186,8 +190,10 @@ <HintPath>..\..\..\packages\System.Threading.Thread.4.3.0\lib\net46\System.Threading.Thread.dll</HintPath> </Reference> <Reference Include="System.ValueTuple"> - <HintPath>..\..\..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath> + <HintPath>..\..\..\packages\System.ValueTuple.4.3.1\lib\netstandard1.0\System.ValueTuple.dll</HintPath> </Reference> + <Reference Include="System.Xml" /> + <Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.ReaderWriter"> <HintPath>..\..\..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll</HintPath> </Reference> @@ -200,67 +206,7 @@ <Reference Include="System.Xml.XPath.XDocument"> <HintPath>..\..\..\packages\System.Xml.XPath.XDocument.4.3.0\lib\net46\System.Xml.XPath.XDocument.dll</HintPath> </Reference> - <Reference Include="System.Runtime.InteropServices.RuntimeInformation"> - <HintPath>..\..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath> - </Reference> - <Reference Include="System.Collections.Immutable"> - <HintPath>..\..\..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath> - </Reference> - <!-- NOTE: NuGet installs the PCL version of System.Reflection.Metadata by default but it is windows-specific. Use netstandard version instead. --> - <Reference Include="System.Reflection.Metadata"> - <HintPath>..\..\..\packages\System.Reflection.Metadata.1.4.2\lib\netstandard1.1\System.Reflection.Metadata.dll</HintPath> - </Reference> - <Reference Include="Newtonsoft.Json"> - <HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> - </Reference> - <Reference Include="Mono.Cecil"> - <HintPath>..\..\..\packages\Mono.Cecil.0.10.0-beta5\lib\net40\Mono.Cecil.dll</HintPath> - </Reference> - <Reference Include="Mono.Cecil.Mdb"> - <HintPath>..\..\..\packages\Mono.Cecil.0.10.0-beta5\lib\net40\Mono.Cecil.Mdb.dll</HintPath> - </Reference> - <Reference Include="Mono.Cecil.Pdb"> - <HintPath>..\..\..\packages\Mono.Cecil.0.10.0-beta5\lib\net40\Mono.Cecil.Pdb.dll</HintPath> - </Reference> - <Reference Include="Mono.Cecil.Rocks"> - <HintPath>..\..\..\packages\Mono.Cecil.0.10.0-beta5\lib\net40\Mono.Cecil.Rocks.dll</HintPath> - </Reference> - <Reference Include="Microsoft.CodeAnalysis"> - <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.Common.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.dll</HintPath> - </Reference> - <Reference Include="Microsoft.CodeAnalysis.CSharp"> - <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.CSharp.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll</HintPath> - </Reference> - <Reference Include="Microsoft.CodeAnalysis.VisualBasic"> - <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.VisualBasic.dll</HintPath> - </Reference> - <Reference Include="Microsoft.CodeAnalysis.Workspaces.Desktop"> - <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.2.3.0-beta1\lib\net46\Microsoft.CodeAnalysis.Workspaces.Desktop.dll</HintPath> - </Reference> - <Reference Include="Microsoft.CodeAnalysis.Workspaces"> - <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.2.3.0-beta1\lib\net46\Microsoft.CodeAnalysis.Workspaces.dll</HintPath> - </Reference> - <Reference Include="Microsoft.CodeAnalysis.CSharp.Workspaces"> - <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.Workspaces.dll</HintPath> - </Reference> - <Reference Include="Microsoft.CodeAnalysis.VisualBasic.Workspaces"> - <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.Workspaces.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll</HintPath> - </Reference> - <Reference Include="Microsoft.CodeAnalysis.Features"> - <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.Features.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.Features.dll</HintPath> - </Reference> - <Reference Include="Microsoft.CodeAnalysis.CSharp.Features"> - <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.CSharp.Features.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.Features.dll</HintPath> - </Reference> - <Reference Include="Microsoft.CodeAnalysis.VisualBasic.Features"> - <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.Features.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.VisualBasic.Features.dll</HintPath> - </Reference> - <Reference Include="Microsoft.CodeAnalysis.EditorFeatures"> - <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.EditorFeatures.2.3.0-beta1\lib\net46\Microsoft.CodeAnalysis.EditorFeatures.dll</HintPath> - </Reference> - <Reference Include="Microsoft.CodeAnalysis.EditorFeatures.Text"> - <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.EditorFeatures.Text.2.3.0-beta1\lib\net46\Microsoft.CodeAnalysis.EditorFeatures.Text.dll</HintPath> - </Reference> + <Reference Include="System.Web" /> </ItemGroup> <ItemGroup> <Compile Include="MonoDevelop.Core\StringParserService.cs" /> @@ -749,6 +695,8 @@ <Compile Include="MonoDevelop.Core\StringInternPool.cs" /> <Compile Include="MonoDevelop.Core\Hash.cs" /> <Compile Include="MonoDevelop.Core\StringTable.cs" /> + <Compile Include="MonoDevelop.Core.AddIns\FalseCondition.cs" /> + <Compile Include="MonoDevelop.Core.AddIns\TrueCondition.cs" /> </ItemGroup> <ItemGroup> <None Include="Makefile.am" /> diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringInternPool.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringInternPool.cs index d0f9b6f8a0..e7cd62fd7b 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringInternPool.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringInternPool.cs @@ -56,5 +56,20 @@ namespace MonoDevelop.Core {
return table.Add (chars);
}
+
+ public static string AddShared (StringBuilder chars)
+ {
+ return StringTable.AddShared (chars);
+ }
+
+ public static string AddShared (string chars)
+ {
+ return StringTable.AddShared (chars);
+ }
+
+ public static string AddShared (string chars, int start, int len)
+ {
+ return StringTable.AddShared (chars, start, len);
+ }
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringTable.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringTable.cs index 8ff7a5e8cd..c2a60d4010 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringTable.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/StringTable.cs @@ -536,6 +536,33 @@ namespace MonoDevelop.Core return AddSharedSlow(hashCode, chars);
}
+ internal static string AddShared (string chars)
+ {
+ var hashCode = Hash.GetFNVHashCode (chars);
+
+ string shared = FindSharedEntry (chars, hashCode);
+ if (shared != null) {
+ return shared;
+ }
+
+ AddSharedSlow (hashCode, chars);
+ return chars;
+ }
+
+ internal static string AddShared (string chars, int start, int len)
+ {
+ var hashCode = Hash.GetFNVHashCode (chars, start, len);
+
+ string shared = FindSharedEntry (chars, start, len, hashCode);
+ if (shared != null) {
+ return shared;
+ }
+
+ string text = chars.Substring (start, len);
+ AddSharedSlow (hashCode, text);
+ return text;
+ }
+
private static string AddSharedSlow(int hashCode, StringBuilder builder)
{
string text = builder.ToString();
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs index 31bd453d1a..8d47e18ad6 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs @@ -933,8 +933,7 @@ namespace MonoDevelop.Projects.MSBuild MSBuildItemEvaluated CreateEvaluatedItem (MSBuildEvaluationContext context, ProjectInfo pinfo, MSBuildProject project, MSBuildItem sourceItem, string include, string evaluatedFile = null, string recursiveDir = null) { - lock (EngineManager.Pool) - include = EngineManager.Pool.Add (include);
+ include = StringInternPool.AddShared (include);
var it = new MSBuildItemEvaluated (project, sourceItem.Name, sourceItem.Include, include); var md = new Dictionary<string,IMSBuildPropertyEvaluated> (); diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEngineManager.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEngineManager.cs index 1a425b759b..1a48a53aca 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEngineManager.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEngineManager.cs @@ -34,8 +34,6 @@ namespace MonoDevelop.Projects.MSBuild object localLock = new object (); bool disposed; - internal Core.StringInternPool Pool { get; } = new Core.StringInternPool (); - public MSBuildEngine GetEngine (bool supportsMSBuild) { /* if (supportsMSBuild) { 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 6560a0a12e..55ada7b308 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs @@ -458,9 +458,7 @@ namespace MonoDevelop.Projects.MSBuild while (i != -1); sb.Append (str, last, str.Length - last); - lock (project.Pool) { - return project.Pool.Add (sb); - } + return StringInternPool.AddShared (sb); } finally { evaluationSbs.Enqueue (sb); } @@ -500,15 +498,12 @@ namespace MonoDevelop.Projects.MSBuild i += 2; int j = FindClosingChar (str, i, ')'); if (j == -1) { - lock (project.Pool) - val = project.Pool.Add (str, start, str.Length - start); + val = StringInternPool.AddShared (str, start, str.Length - start); i = str.Length; return false; } - string prop; - lock (project.Pool) - prop = project.Pool.Add (str, i, j - i).Trim (); + string prop = StringInternPool.AddShared (str, i, j - i).Trim (); i = j + 1; bool res = false; @@ -532,9 +527,7 @@ namespace MonoDevelop.Projects.MSBuild } } if (!res) - lock (project.Pool) { - val = project.Pool.Add (str, start, j - start + 1); - } + val = StringInternPool.AddShared (str, start, j - start + 1); return res; } 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 08cf608024..8ea842408d 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs @@ -1104,8 +1104,6 @@ namespace MonoDevelop.Projects.MSBuild internal Dictionary<string, string> GlobalProperties { get { return globalProperties; } } - - internal StringInternPool Pool => engineManager.Pool; } static class XmlUtil diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectInstance.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectInstance.cs index f7b32d777f..b7fe15428d 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectInstance.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectInstance.cs @@ -93,6 +93,13 @@ namespace MonoDevelop.Projects.MSBuild projectInstance = engine.CreateProjectInstance (info.Project); try { + // Set properties defined by global property providers, and then + // properties explicitly set to this instance + + foreach (var gpp in MSBuildProjectService.GlobalPropertyProviders) { + foreach (var prop in gpp.GetGlobalProperties ()) + engine.SetGlobalProperty (projectInstance, prop.Key, prop.Value); + } foreach (var prop in globalProperties) engine.SetGlobalProperty (projectInstance, prop.Key, prop.Value); diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs index d8d1e99616..3e5c6d0d25 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs @@ -94,6 +94,15 @@ namespace MonoDevelop.Projects.MSBuild } } + internal static IEnumerable<IMSBuildGlobalPropertyProvider> GlobalPropertyProviders { + get { + if (customGlobalPropertyProviders != null) + return globalPropertyProviders.Concat (customGlobalPropertyProviders); + else + return globalPropertyProviders; + } + } + static MSBuildProjectService () { Services.ProjectService.DataContextChanged += delegate { @@ -200,6 +209,21 @@ namespace MonoDevelop.Projects.MSBuild customProjectItemTypes.Remove (name); } + static List<IMSBuildGlobalPropertyProvider> customGlobalPropertyProviders; + + internal static void RegisterGlobalPropertyProvider (IMSBuildGlobalPropertyProvider provider) + { + if (customGlobalPropertyProviders == null) + customGlobalPropertyProviders = new List<IMSBuildGlobalPropertyProvider> (); + customGlobalPropertyProviders.Add (provider); + } + + internal static void UnregisterGlobalPropertyProvider (IMSBuildGlobalPropertyProvider provider) + { + if (customGlobalPropertyProviders != null) + customGlobalPropertyProviders.Remove (provider); + } + /// <summary> /// Registers a custom project import search path. This path will be used as a fallback when evaluating /// an import and targets file is not found using the value assigned by MSBuild to the property. diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildWhitespace.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildWhitespace.cs index 276e548582..114802419b 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildWhitespace.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildWhitespace.cs @@ -203,9 +203,6 @@ namespace MonoDevelop.Projects.MSBuild } } - // PERF: Keep a global pool for whitespace in MSBuild. - // There are not many variations on a properly formatted project so the pool is small. - readonly static StringInternPool whitespacePool = new StringInternPool (); public static object ConsumeUntilNewLine (ref object ws) { if (ws == null) @@ -219,11 +216,8 @@ namespace MonoDevelop.Projects.MSBuild if (n == s.Length - 1) break; // Default case, consume the whole string int len = n + 1; - string res; - lock (whitespacePool) { - res = whitespacePool.Add (s, 0, len); - ws = whitespacePool.Add (s, len, s.Length - len); - } + string res = StringInternPool.AddShared (s, 0, len); + ws = StringInternPool.AddShared (s, len, s.Length - len); return res; } } @@ -243,10 +237,7 @@ namespace MonoDevelop.Projects.MSBuild return res; } } - string result; - lock (whitespacePool) { - result = whitespacePool.Add (sb); - } + string result = StringInternPool.AddShared (sb); ws = null; return result; } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.SharedAssetsProjects/SharedAssetsProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.SharedAssetsProjects/SharedAssetsProject.cs index 7461135756..447484027d 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.SharedAssetsProjects/SharedAssetsProject.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.SharedAssetsProjects/SharedAssetsProject.cs @@ -274,7 +274,7 @@ namespace MonoDevelop.Projects.SharedAssetsProjects return ProjectFeatures.None; } - protected override bool OnFastCheckNeedsBuild (ConfigurationSelector configuration) + protected override bool OnFastCheckNeedsBuild (ConfigurationSelector configuration, TargetEvaluationContext context) { return false; } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/OperationContext.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/OperationContext.cs index 96594b3302..41f0d3f92d 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/OperationContext.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/OperationContext.cs @@ -25,6 +25,7 @@ // THE SOFTWARE. using System; using System.Collections.Generic; +using MonoDevelop.Core.Execution; namespace MonoDevelop.Projects { @@ -56,7 +57,13 @@ namespace MonoDevelop.Projects customData = new Dictionary<object, object> (other.customData); else customData = null; + ExecutionTarget = other.ExecutionTarget; } + + /// <summary> + /// Execution target for which the operation is being executed + /// </summary> + public ExecutionTarget ExecutionTarget { get; set; } } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs index a1333466c8..866af7a0df 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs @@ -1067,7 +1067,12 @@ namespace MonoDevelop.Projects /// </param> public Task<TargetEvaluationResult> RunTarget (ProgressMonitor monitor, string target, ConfigurationSelector configuration, TargetEvaluationContext context = null) { - return ProjectExtension.OnRunTarget (monitor, target, configuration, context ?? new TargetEvaluationContext ()); + // Initialize the evaluation context. This initialization is shared with FastCheckNeedsBuild. + // Extenders will override OnConfigureTargetEvaluationContext to add custom properties and do other + // initializations required by MSBuild. + context = ProjectExtension.OnConfigureTargetEvaluationContext (target, configuration, context ?? new TargetEvaluationContext ()); + + return ProjectExtension.OnRunTarget (monitor, target, configuration, context); } public bool SupportsTarget (string target) @@ -1086,6 +1091,24 @@ namespace MonoDevelop.Projects } /// <summary> + /// Initialize the evaluation context that is going to be used to execute an MSBuild target. + /// </summary> + /// <returns>The updated context.</returns> + /// <param name="target">Target.</param> + /// <param name="configuration">Configuration.</param> + /// <param name="context">Context.</param> + /// <remarks> + /// This method can be overriden to add custom properties and do other initializations on the evaluation + /// context. The method is always called before executing OnRunTarget and other methods that do + /// target evaluations. The method can modify the provided context instance and return it, or it can + /// create a new instance. + /// </remarks> + protected virtual TargetEvaluationContext OnConfigureTargetEvaluationContext (string target, ConfigurationSelector configuration, TargetEvaluationContext context) + { + return context; + } + + /// <summary> /// Runs a build or execution target. /// </summary> /// <returns> @@ -1687,7 +1710,7 @@ namespace MonoDevelop.Projects if (UsingMSBuildEngine (configuration)) { var result = await RunMSBuildTarget (monitor, "Build", configuration, context); if (!result.BuildResult.Failed) - SetFastBuildCheckClean (configuration); + SetFastBuildCheckClean (configuration, context); return result; } @@ -1720,16 +1743,31 @@ namespace MonoDevelop.Projects bool disableFastUpToDateCheck; - //the configuration of the last build that completed successfully - //null if any file in the project has since changed + // The configuration of the last build that completed successfully, + // null if any file in the project has since changed string fastUpToDateCheckGoodConfig; + + // The global properties used in the last build + IPropertySet fastUpToDateCheckGlobalProperties; + + // Timestamp of the last build DateTime fastUpToDateTimestamp; public bool FastCheckNeedsBuild (ConfigurationSelector configuration) { - return ProjectExtension.OnFastCheckNeedsBuild (configuration); + return FastCheckNeedsBuild (configuration, new TargetEvaluationContext ()); } - + + public bool FastCheckNeedsBuild (ConfigurationSelector configuration, TargetEvaluationContext context) + { + // Initialize the evaluation context. This initialization is shared with RunTarget. + // Extenders will override OnConfigureTargetEvaluationContext to add custom properties and do other + // initializations required by MSBuild. + context = ProjectExtension.OnConfigureTargetEvaluationContext ("Build", configuration, context ?? new TargetEvaluationContext ()); + return ProjectExtension.OnFastCheckNeedsBuild (configuration, context); + } + + [Obsolete ("Use OnFastCheckNeedsBuild (configuration, TargetEvaluationContext)")] protected virtual bool OnFastCheckNeedsBuild (ConfigurationSelector configuration) { if (disableFastUpToDateCheck || fastUpToDateCheckGoodConfig == null) @@ -1738,15 +1776,52 @@ namespace MonoDevelop.Projects if (cfg == null || cfg.Id != fastUpToDateCheckGoodConfig) return true; + return false; + } + + /// <summary> + /// Checks if this project needs to be built. + /// </summary> + /// <returns><c>true</c>, if the project is dirty and needs to be rebuilt, <c>false</c> otherwise.</returns> + /// <param name="configuration">Build configuration.</param> + /// <param name="context">Evaluation context.</param> + /// <remarks> + /// This method can be overriden to provide custom logic for checking if a project needs to be built, either + /// due to changes in the content or in the configuration. + /// </remarks> + protected virtual bool OnFastCheckNeedsBuild (ConfigurationSelector configuration, TargetEvaluationContext context) + { + // Chain the new OnFastCheckNeedsBuild override to the old one, so that extensions + // using the old API keep working +#pragma warning disable 618 + if (ProjectExtension.OnFastCheckNeedsBuild (configuration)) + return true; +#pragma warning restore 618 + // Shouldn't need to build, but if a dependency was changed since this project build flag was reset, // the project needs to be rebuilt foreach (var dep in GetReferencedItems (configuration).OfType<Project> ()) { - if (dep.FastCheckNeedsBuild (configuration) || dep.fastUpToDateTimestamp >= fastUpToDateTimestamp) { + if (dep.FastCheckNeedsBuild (configuration, context) || dep.fastUpToDateTimestamp >= fastUpToDateTimestamp) { fastUpToDateCheckGoodConfig = null; return true; } } + + // Check if global properties have changed + + var cachedCount = fastUpToDateCheckGlobalProperties != null ? fastUpToDateCheckGlobalProperties.GetProperties ().Count () : 0; + + if (cachedCount != context.GlobalProperties.GetProperties ().Count ()) + return true; + + if (cachedCount == 0) + return false; + + foreach (var p in context.GlobalProperties.GetProperties ()) { + if (fastUpToDateCheckGlobalProperties.GetValue (p.Name) != p.Value) + return true; + } return false; } @@ -1755,10 +1830,11 @@ namespace MonoDevelop.Projects fastUpToDateCheckGoodConfig = null; } - void SetFastBuildCheckClean (ConfigurationSelector configuration) + void SetFastBuildCheckClean (ConfigurationSelector configuration, TargetEvaluationContext context) { var cfg = GetConfiguration (configuration); fastUpToDateCheckGoodConfig = cfg != null ? cfg.Id : null; + fastUpToDateCheckGlobalProperties = context.GlobalProperties; fastUpToDateTimestamp = DateTime.Now; } @@ -3862,6 +3938,11 @@ namespace MonoDevelop.Projects Project.OnWriteRunConfiguration (monitor, runConfig, properties); } + internal protected override TargetEvaluationContext OnConfigureTargetEvaluationContext (string target, ConfigurationSelector configuration, TargetEvaluationContext context) + { + return Project.OnConfigureTargetEvaluationContext (target, configuration, context); + } + internal protected override Task<TargetEvaluationResult> OnRunTarget (ProgressMonitor monitor, string target, ConfigurationSelector configuration, TargetEvaluationContext context) { return Project.DoRunTarget (monitor, target, configuration, context); @@ -3978,10 +4059,17 @@ namespace MonoDevelop.Projects Project.OnPrepareForEvaluation (project); } +#pragma warning disable 672, 618 internal protected override bool OnFastCheckNeedsBuild (ConfigurationSelector configuration) { return Project.OnFastCheckNeedsBuild (configuration); } +#pragma warning restore 672, 618 + + internal protected override bool OnFastCheckNeedsBuild (ConfigurationSelector configuration, TargetEvaluationContext context) + { + return Project.OnFastCheckNeedsBuild (configuration, context); + } internal protected override Task<ProjectFile []> OnGetSourceFiles (ProgressMonitor monitor, ConfigurationSelector configuration) { diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectExtension.cs index 5d32a28e6a..3544528240 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectExtension.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectExtension.cs @@ -85,6 +85,19 @@ namespace MonoDevelop.Projects next.OnWriteRunConfiguration (monitor, config, properties); } + /// <summary> + /// Called to initialize a TargetEvaluationContext instance required by RunTarget() + /// and other methods that invoke MSBuild targets + /// </summary> + /// <returns>The initialized evaluation context (it can be just the provided context)</returns> + /// <param name="target">The MSBuild target that is going to be invoked</param> + /// <param name="configuration">Build configuration</param> + /// <param name="context">Execution context</param> + internal protected virtual TargetEvaluationContext OnConfigureTargetEvaluationContext (string target, ConfigurationSelector configuration, TargetEvaluationContext context) + { + return next.OnConfigureTargetEvaluationContext (target, configuration, context); + } + internal protected virtual Task<TargetEvaluationResult> OnRunTarget (ProgressMonitor monitor, string target, ConfigurationSelector configuration, TargetEvaluationContext context) { return next.OnRunTarget (monitor, target, configuration, context); @@ -218,11 +231,27 @@ namespace MonoDevelop.Projects } } + [Obsolete ("Use OnFastCheckNeedsBuild (ConfigurationSelector,TargetEvaluationContext)")] internal protected virtual bool OnFastCheckNeedsBuild (ConfigurationSelector configuration) { return next.OnFastCheckNeedsBuild (configuration); } + /// <summary> + /// Checks if this project needs to be built. + /// </summary> + /// <returns><c>true</c>, if the project is dirty and needs to be rebuilt, <c>false</c> otherwise.</returns> + /// <param name="configuration">Build configuration.</param> + /// <param name="context">Evaluation context.</param> + /// <remarks> + /// This method can be overriden to provide custom logic for checking if a project needs to be built, either + /// due to changes in the content or in the configuration. + /// </remarks> + internal protected virtual bool OnFastCheckNeedsBuild (ConfigurationSelector configuration, TargetEvaluationContext context) + { + return next.OnFastCheckNeedsBuild (configuration, context); + } + #endregion #region Events diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObject.cs index afccbde274..1c77c88439 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObject.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObject.cs @@ -38,6 +38,7 @@ using System.Runtime.Remoting.Messaging; using MonoDevelop.Core.StringParsing; using System.Threading; using System.Collections.Immutable; +using MonoDevelop.Core.AddIns; namespace MonoDevelop.Projects @@ -67,9 +68,7 @@ namespace MonoDevelop.Projects if (!initializeCalled) { initializeCalled = true; - extensionContext = AddinManager.CreateExtensionContext (); - extensionContext.RegisterCondition ("ItemType", new ItemTypeCondition (GetType ())); - ExtensionContext.RegisterCondition ("AppliesTo", new AppliesToCondition (this)); + extensionContext = CreateExtensionContext (this); OnInitialize (); InitializeExtensionChain (); @@ -435,7 +434,23 @@ namespace MonoDevelop.Projects static void LoadExtensions () { - modelExtensions = AddinManager.GetExtensionNodes<ProjectModelExtensionNode> (ProjectService.ProjectModelExtensionsPath).Concat (customNodes).ToArray (); + // Create a context for loading the default extensions. The context is necessary because + // the conditions declared in the extension point must always be present. + var extensionContext = CreateExtensionContext (null); + modelExtensions = extensionContext.GetExtensionNodes<ProjectModelExtensionNode> (ProjectService.ProjectModelExtensionsPath).Concat (customNodes).ToArray (); + } + + static ExtensionContext CreateExtensionContext (WorkspaceObject targetObject) + { + var extensionContext = AddinManager.CreateExtensionContext (); + if (targetObject == null) { + extensionContext.RegisterCondition ("ItemType", FalseCondition.Instance); + extensionContext.RegisterCondition ("AppliesTo", FalseCondition.Instance); + } else { + extensionContext.RegisterCondition ("ItemType", new ItemTypeCondition (targetObject.GetType ())); + extensionContext.RegisterCondition ("AppliesTo", new AppliesToCondition (targetObject)); + } + return extensionContext; } /// <summary> diff --git a/main/src/core/MonoDevelop.Core/packages.config b/main/src/core/MonoDevelop.Core/packages.config index 9062608930..e5b2ea5b94 100644 --- a/main/src/core/MonoDevelop.Core/packages.config +++ b/main/src/core/MonoDevelop.Core/packages.config @@ -23,7 +23,7 @@ <package id="Microsoft.VisualStudio.Text.UI" version="15.0.26201" targetFramework="net45" /> <package id="Mono.Cecil" version="0.10.0-beta5" targetFramework="net45" /> <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" /> - <package id="SharpZipLib" version="0.86.0" targetFramework="net45" /> + <package id="JetBrains.SharpZipLib.Stripped" version="0.87.20170615.10" targetFramework="net461" /> <package id="System.AppContext" version="4.3.0" targetFramework="net461" /> <package id="System.Collections" version="4.3.0" targetFramework="net461" /> <package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net461" /> @@ -67,7 +67,7 @@ <package id="System.Threading.Tasks" version="4.3.0" targetFramework="net461" /> <package id="System.Threading.Tasks.Parallel" version="4.3.0" targetFramework="net461" /> <package id="System.Threading.Thread" version="4.3.0" targetFramework="net461" /> - <package id="System.ValueTuple" version="4.3.0" targetFramework="net461" /> + <package id="System.ValueTuple" version="4.3.1" targetFramework="net461" /> <package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net461" /> <package id="System.Xml.XDocument" version="4.3.0" targetFramework="net461" /> <package id="System.Xml.XmlDocument" version="4.3.0" targetFramework="net461" /> diff --git a/main/src/core/MonoDevelop.Ide/ExtensionModel/Commands.addin.xml b/main/src/core/MonoDevelop.Ide/ExtensionModel/Commands.addin.xml index 54e1362133..6fe92d0bc0 100644 --- a/main/src/core/MonoDevelop.Ide/ExtensionModel/Commands.addin.xml +++ b/main/src/core/MonoDevelop.Ide/ExtensionModel/Commands.addin.xml @@ -828,6 +828,9 @@ <Command id = "MonoDevelop.Ide.Commands.HelpCommands.DumpA11yTreeDelayed" defaultHandler = "MonoDevelop.Ide.Commands.DumpA11yTreeDelayedHandler" _label = "Dump Accessibility Tree (10s)" /> + <Command id = "MonoDevelop.Ide.Commands.HelpCommands.MarkLog" + defaultHandler = "MonoDevelop.Ide.Commands.MarkLogHandler" + _label = "Mark Log" /> </Category> <!-- SearchCommands --> diff --git a/main/src/core/MonoDevelop.Ide/ExtensionModel/MainMenu.addin.xml b/main/src/core/MonoDevelop.Ide/ExtensionModel/MainMenu.addin.xml index e122cf42f1..993e0046f2 100644 --- a/main/src/core/MonoDevelop.Ide/ExtensionModel/MainMenu.addin.xml +++ b/main/src/core/MonoDevelop.Ide/ExtensionModel/MainMenu.addin.xml @@ -288,6 +288,7 @@ <CommandItem id = "MonoDevelop.Ide.Commands.HelpCommands.DumpUITree" /> <CommandItem id = "MonoDevelop.Ide.Commands.HelpCommands.DumpA11yTree" /> <CommandItem id = "MonoDevelop.Ide.Commands.HelpCommands.DumpA11yTreeDelayed" /> + <CommandItem id = "MonoDevelop.Ide.Commands.HelpCommands.MarkLog" /> </ItemSet> <Condition id = "Platform" value = "!mac"> <SeparatorItem id = "SeparatorAbout" /> diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelper.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelper.cs index 9f8bd48c01..35c99558f2 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelper.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelper.cs @@ -126,8 +126,10 @@ namespace MonoDevelop.Components.AtkCocoaHelper AXCell, AXColumn, AXGroup, + AXGrowArea, AXImage, AXLink, + AXList, AXMenuButton, AXPopUpButton, AXRadioButton, @@ -533,6 +535,7 @@ namespace MonoDevelop.Components.AtkCocoaHelper string Identifier { get; set; } string Help { get; set; } bool Hidden { get; set; } + int Index { get; set; } // For Navigable Static Text Func<string> Contents { set; } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelperMac.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelperMac.cs index dc0ddd15ec..6dedc4b8d9 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelperMac.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelperMac.cs @@ -855,6 +855,26 @@ namespace MonoDevelop.Components.AtkCocoaHelper p.GetVisibleCharacterRange = value; } } + + public int Index { + get { + var p = realProxyElement; + if (p == null) { + throw new Exception ("Not proxy element"); + } + + return (int) p.AccessibilityIndex; + } + + set { + var p = realProxyElement; + if (p == null) { + throw new Exception ("Not a proxy element"); + } + + p.AccessibilityIndex = value; + } + } } class RealAccessibilityElementProxy : NSAccessibilityElement, INSAccessibility diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelperNoOp.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelperNoOp.cs index c73624c21d..6843a55a72 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelperNoOp.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelperNoOp.cs @@ -219,6 +219,14 @@ namespace MonoDevelop.Components.AtkCocoaHelper } } + public int Index { + get { + return 0; + } + set { + } + } + public Gtk.Widget GtkParent { get; set; } public Gdk.Rectangle FrameInGtkParent { get; set; } public Gdk.Rectangle FrameInParent { get; set; } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingSet.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingSet.cs index e649670aa1..0e98831e68 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingSet.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingSet.cs @@ -100,7 +100,12 @@ namespace MonoDevelop.Components.Commands public bool Equals (KeyBindingSet other) { - if (parent != other && bindings.Count != other.bindings.Count) + // TODO: full IEquatable<KeyBindingSet> implementation + // the current solutions is just enough to detect whether a custom set equals a predefined one + // and is not a real equality check. See KeyBindingsPanel.SelectCurrentScheme(). + if (other == null) + return false; + if (parent != null && parent != other && !parent.Equals (other.parent)) return false; foreach (KeyValuePair<string, string> binding in bindings) { string accel; @@ -214,9 +219,21 @@ namespace MonoDevelop.Components.Commands case "binding": command = reader.GetAttribute (commandAttr); binding = reader.GetAttribute (shortcutAttr); + + if (string.IsNullOrEmpty (command)) + continue; + + if (!string.IsNullOrEmpty (binding)) + binding = KeyBindingManager.FixChordSeparators (binding); + + string pbind; + if (parent?.bindings != null && parent.bindings.TryGetValue (command, out pbind)) { + if (binding == pbind) + continue; + } else if (string.IsNullOrEmpty (binding)) + continue; - if (!string.IsNullOrEmpty (command)) - bindings.Add (command, KeyBindingManager.FixChordSeparators(binding)); + bindings.Add (command, binding); break; } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/DockBarItem.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/DockBarItem.cs index 2e383f3b5e..5356ff36ae 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/DockBarItem.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/DockBarItem.cs @@ -165,6 +165,7 @@ namespace MonoDevelop.Components.Docking Styles.Changed += UpdateStyle; Accessible.Name = "DockbarItem"; + Accessible.Role = Atk.Role.PushButton; } void IAnimatable.BatchBegin () { } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/ContextMenuExtensionsMac.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/ContextMenuExtensionsMac.cs index 25e57dc339..4a4aa06711 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/ContextMenuExtensionsMac.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/ContextMenuExtensionsMac.cs @@ -27,6 +27,7 @@ using System; #if MAC using AppKit; +using CoreGraphics; using Foundation; using MonoDevelop.Ide; #endif @@ -64,7 +65,6 @@ namespace MonoDevelop.Components } - static CoreGraphics.CGPoint lastOpenPositon; public static void ShowContextMenu (Gtk.Widget parent, int x, int y, NSMenu menu, bool selectFirstItem = false) { if (parent == null) @@ -96,11 +96,9 @@ namespace MonoDevelop.Components if (selectFirstItem) { var pt = new CoreGraphics.CGPoint (x, y); - lastOpenPositon = pt; menu.PopUpMenu (menu.ItemAt (0), pt, nsview); } else { var pt = new CoreGraphics.CGPoint (x, nswindow.Frame.Height - y - titleBarOffset); - lastOpenPositon = pt; var tmp_event = NSEvent.MouseEvent (NSEventType.LeftMouseDown, pt, 0, 0, @@ -123,10 +121,11 @@ namespace MonoDevelop.Components ShowContextMenu (parent, x, y, menu); } - static NSMenuItem CreateMenuItem (ContextMenuItem item) + static void AddMenuItem (NSLocationAwareMenu menu, ContextMenuItem item) { if (item.IsSeparator) { - return NSMenuItem.SeparatorItem; + menu.AddItem (NSMenuItem.SeparatorItem); + return; } var menuItem = new NSMenuItem (item.Label.Replace ("_",""), (s, e) => item.Click ()); @@ -144,60 +143,20 @@ namespace MonoDevelop.Components } if (item.SubMenu != null && item.SubMenu.Items.Count > 0) { - menuItem.Submenu = FromMenu (item.SubMenu, null); + var subMenu = FromMenu (item.SubMenu, null); + subMenu.Parent = menu; + menuItem.Submenu = subMenu; } - return menuItem; + menu.AddItem (menuItem); } - class ContextMenuDelegate : NSObject + static NSLocationAwareMenu FromMenu (ContextMenu menu, Action closeHandler) { - ContextMenu menu; - ContextMenuItem oldItem; - public ContextMenuDelegate (ContextMenu menu) - { - this.menu = menu; - } - - public Action CloseHandler { get; set; } - - [Export ("menuDidClose:")] - void MenuDidClose (NSMenu menu) - { - if (menu.Supermenu != null) - return; - if (CloseHandler != null) { - CloseHandler (); - } - this.menu.FireClosedEvent (); - } - - [Export ("menu:willHighlightItem:")] - void MenuWillHighlightItem (NSMenu menu, NSMenuItem willHighlightItem) - { - if (oldItem != null) { - oldItem.FireDeselectedEvent (); - oldItem = null; - } - if (willHighlightItem == null) - return; - int index = (int)menu.IndexOf (willHighlightItem); - if (index < 0) - return; - oldItem = this.menu.Items [index]; - - oldItem.FireSelectedEvent (new Xwt.Rectangle (lastOpenPositon.X, lastOpenPositon.Y, menu.Size.Width, menu.Size.Height)); - } - } - - static NSMenu FromMenu (ContextMenu menu, Action closeHandler) - { - var result = new NSMenu () { AutoEnablesItems = false }; - result.WeakDelegate = new ContextMenuDelegate (menu) { CloseHandler = closeHandler }; + var result = new NSLocationAwareMenu (menu, closeHandler) { AutoEnablesItems = false }; foreach (var menuItem in menu.Items) { - var item = CreateMenuItem (menuItem); - result.AddItem (item); + AddMenuItem (result, menuItem); } return result; @@ -209,6 +168,77 @@ namespace MonoDevelop.Components { return (NSImage)macToolkit.GetNativeImage (image); } + + class NSLocationAwareMenu : NSMenu + { + public CGPoint Location { get; private set; } + public NSLocationAwareMenu Parent { get; set; } + + public NSLocationAwareMenu (ContextMenu menu, Action closeHandler) + { + WeakDelegate = new ContextMenuDelegate (menu) { CloseHandler = closeHandler }; + } + + public override bool PopUpMenu (NSMenuItem item, CGPoint location, NSView view) + { + Location = location; + var parentMenu = item?.ParentItem?.Menu as NSLocationAwareMenu; + if (parentMenu != null) { + Location = new CGPoint ( + Location.X + parentMenu.Location.X, + Location.Y + parentMenu.Location.Y); + } + return base.PopUpMenu (item, location, view); + } + + class ContextMenuDelegate : NSObject + { + ContextMenu menu; + ContextMenuItem oldItem; + public ContextMenuDelegate (ContextMenu menu) + { + this.menu = menu; + } + + public Action CloseHandler { get; set; } + + [Export ("menuDidClose:")] + void MenuDidClose (NSMenu menu) + { + if (menu.Supermenu != null) + return; + if (CloseHandler != null) { + CloseHandler (); + } + this.menu.FireClosedEvent (); + } + + [Export ("menu:willHighlightItem:")] + void MenuWillHighlightItem (NSMenu menu, NSMenuItem willHighlightItem) + { + if (oldItem != null) { + oldItem.FireDeselectedEvent (); + oldItem = null; + } + if (willHighlightItem == null) + return; + int index = (int)menu.IndexOf (willHighlightItem); + if (index < 0) + return; + oldItem = this.menu.Items [index]; + nfloat x = 0, y = 0; + var locationAwareMenu = menu as NSLocationAwareMenu; + if (locationAwareMenu != null) { + while (locationAwareMenu.Parent != null) + locationAwareMenu = locationAwareMenu.Parent; + x = locationAwareMenu.Location.X; + y = locationAwareMenu.Location.Y; + menu = locationAwareMenu; + } + oldItem.FireSelectedEvent (new Xwt.Rectangle (x, y, menu.Size.Width, menu.Size.Height)); + } + } + } } #endif }
\ No newline at end of file diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/InformationPopoverWidget.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/InformationPopoverWidget.cs index 376556e212..707aba213a 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/InformationPopoverWidget.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/InformationPopoverWidget.cs @@ -42,6 +42,7 @@ namespace MonoDevelop.Components { severity = TaskSeverity.Information; imageView = new Xwt.ImageView (); + imageView.Accessible.Role = Xwt.Accessibility.Role.Filler; UpdateIcon (); Content = imageView; CanGetFocus = true; @@ -66,6 +67,8 @@ namespace MonoDevelop.Components set { message = value; UpdatePopover (); + + this.Accessible.Label = value; } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/MenuButton.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/MenuButton.cs index 842770df79..e331af12ef 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/MenuButton.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/MenuButton.cs @@ -52,6 +52,7 @@ namespace MonoDevelop.Components Add (box); image = new ImageView (); + image.Accessible.Role = Atk.Role.Filler; image.NoShowAll = true; box.PackStart (image, false, false, 0); label = new Label (); @@ -170,6 +171,7 @@ namespace MonoDevelop.Components } else { if (arrow == null ) { arrow = new Arrow (Gtk.ArrowType.Down, ShadowType.Out); + arrow.Accessible.Role = Atk.Role.Filler; arrow.Show (); ((HBox)label.Parent).PackEnd (arrow, false, false, 0); } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/MiniButton.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/MiniButton.cs index 29a8b3ca9c..91df3fbd5e 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/MiniButton.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/MiniButton.cs @@ -27,6 +27,7 @@ using System; using Gtk; +using MonoDevelop.Components.AtkCocoaHelper; namespace MonoDevelop.Components { class MiniButton: Gtk.EventBox @@ -41,6 +42,10 @@ namespace MonoDevelop.Components { Events |= Gdk.EventMask.EnterNotifyMask | Gdk.EventMask.LeaveNotifyMask; Clickable = true; + + Accessible.Role = Atk.Role.PushButton; + var actionHandler = new ActionDelegate (this); + actionHandler.PerformPress += PerformPress; } public MiniButton (Gtk.Widget label): this () @@ -102,7 +107,12 @@ namespace MonoDevelop.Components if (Clicked != null) Clicked (this, EventArgs.Empty); } - + + void PerformPress (object sender, EventArgs args) + { + OnClicked (); + } + protected override bool OnButtonPressEvent (Gdk.EventButton evnt) { if (!ClickOnRelease && Clickable && evnt.Button == 1 && !evnt.TriggersContextMenu ()) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/PathBar.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/PathBar.cs index 868f98a924..58e65dba0a 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/PathBar.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/PathBar.cs @@ -78,6 +78,7 @@ namespace MonoDevelop.Components get { if (accessible == null) { accessible = AccessibilityElementProxy.ButtonElementProxy (); + accessible.SetRole (AtkCocoa.Roles.AXPopUpButton); accessible.Identifier = "Breadcrumb"; accessible.PerformPress += OnPerformShowMenu; @@ -183,6 +184,8 @@ namespace MonoDevelop.Components Accessible.Name = "PathBar"; Accessible.SetLabel (GettextCatalog.GetString ("Breadcrumb Bar")); Accessible.Description = GettextCatalog.GetString ("Jump to definitions in the current file"); + Accessible.SetRole (AtkCocoa.Roles.AXList); + Accessible.SetOrientation (Orientation.Horizontal); CanFocus = true; @@ -302,6 +305,7 @@ namespace MonoDevelop.Components Gdk.Rectangle rect = new Gdk.Rectangle (x, y, width, height); entry.Accessible.FrameInGtkParent = rect; + entry.Accessible.FrameInParent = rect; } protected override bool OnExposeEvent (EventExpose evnt) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Tabstrip.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Tabstrip.cs index 5db69245bb..ab2b4d2d2b 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Tabstrip.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Tabstrip.cs @@ -128,6 +128,7 @@ namespace MonoDevelop.Components var proxies = new AtkCocoaHelper.AccessibilityElementProxy [tabs.Count]; foreach (var tab in tabs) { proxies [i] = tab.Accessible; + tab.Accessible.Index = i; i++; } @@ -204,7 +205,7 @@ namespace MonoDevelop.Components { requisition.Height = (int)Math.Ceiling (tabSizes.Max (p => p.Y)); } - + protected override bool OnExposeEvent (Gdk.EventExpose evnt) { using (var cr = Gdk.CairoHelper.Create (evnt.Window)) { @@ -212,16 +213,21 @@ namespace MonoDevelop.Components cr.SetSourceColor (Styles.SubTabBarBackgroundColor.ToCairoColor ()); cr.Fill (); + Tab active = null; for (int i = tabs.Count; i --> 0;) { - if (i == ActiveTab) + if (i == ActiveTab) { + active = tabs [i]; continue; + } var tab = tabs[i]; var bounds = GetBounds (tab); tab.HoverPosition = tab == hoverTab ? new Cairo.PointD (mx - bounds.X, my) : new Cairo.PointD (-1, -1); tab.Draw (cr, bounds); } - - tabs[ActiveTab].Draw (cr, GetBounds (tabs[ActiveTab])); + + if (active != null) { + active.Draw (cr, GetBounds (active)); + } } return base.OnExposeEvent (evnt); @@ -291,7 +297,9 @@ namespace MonoDevelop.Components protected override void OnActivate () { - ActiveTab = focusedTab; + if (focusedTab >= 0 && focusedTab < tabs.Count) { + ActiveTab = focusedTab; + } base.OnActivate (); } } @@ -360,7 +368,6 @@ namespace MonoDevelop.Components Gdk.Rectangle gdkRect = new Gdk.Rectangle ((int)allocation.X, (int)allocation.Y, (int)allocation.Width, (int)allocation.Height); Accessible.FrameInGtkParent = gdkRect; // If Y != 0, then we need to flip the y axis - Accessible.FrameInParent = gdkRect; } } @@ -399,8 +406,10 @@ namespace MonoDevelop.Components this.TabPosition = tabPosition; Accessible = AccessibilityElementProxy.ButtonElementProxy (); + Accessible.SetRole (AtkCocoa.Roles.AXRadioButton, "tab"); Accessible.Title = label; Accessible.GtkParent = parent; + Accessible.Identifier = "Tabstrip.Tab"; Accessible.PerformPress += OnTabPressed; } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/HelpCommands.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/HelpCommands.cs index 7f0d57ede9..bdd66ebf1c 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/HelpCommands.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/HelpCommands.cs @@ -32,6 +32,7 @@ using System.Timers; using MonoDevelop.Ide.Gui.Dialogs; using MonoDevelop.Ide.Gui; using MonoDevelop.Components.Commands; +using MonoDevelop.Core; namespace MonoDevelop.Ide.Commands { @@ -176,4 +177,12 @@ namespace MonoDevelop.Ide.Commands } #endif } + + class MarkLogHandler : CommandHandler + { + protected override void Run () + { + LoggingService.LogInfo ("\n\n--- --- --- --- MARK --- --- --- ---\n\n"); + } + } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/ViewCommands.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/ViewCommands.cs index 3fae99b2eb..7a1eca14b3 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/ViewCommands.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/ViewCommands.cs @@ -336,6 +336,10 @@ namespace MonoDevelop.Ide.Commands protected override void Run () { + // Already in 2-column mode? + if (DockNotebook.ActiveNotebook?.Container?.SplitCount > 0) + return; + IdeApp.Workbench.LockActiveWindowChangeEvent (); var container = DockNotebook.ActiveNotebook.Container; var tab = DockNotebook.ActiveNotebook.CurrentTab; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/Formats/OldFormat.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/Formats/OldFormat.cs index 151d7a4a2a..09675a6a12 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/Formats/OldFormat.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/Formats/OldFormat.cs @@ -196,6 +196,22 @@ namespace MonoDevelop.Ide.Editor.Highlighting settings.Add (new ThemeSetting ("Variable", new List<string> { "variable" }, ConvertChunkStyle (colorScheme.UserVariableUsage))); settings.Add (new ThemeSetting ("variable.other", new List<string> { "variable.other" }, ConvertChunkStyle (colorScheme.ScriptKeyword))); settings.Add (new ThemeSetting ("Keyword", new List<string> { "keyword - (source.c keyword.operator | source.c++ keyword.operator | source.objc keyword.operator | source.objc++ keyword.operator), keyword.operator.word" }, ConvertChunkStyle (colorScheme.KeywordOther))); + settings.Add (new ThemeSetting ("Keyword (Access)", new List<string> { "keyword.other.access" }, ConvertChunkStyle (colorScheme.KeywordAccessors))); + settings.Add (new ThemeSetting ("Keyword (Types)", new List<string> { "keyword.other.type" }, ConvertChunkStyle (colorScheme.KeywordTypes))); + settings.Add (new ThemeSetting ("Keyword (Operator)", new List<string> { "keyword.operator" }, ConvertChunkStyle (colorScheme.KeywordOperators))); + settings.Add (new ThemeSetting ("Keyword (Selection)", new List<string> { "keyword.other.selection" }, ConvertChunkStyle (colorScheme.KeywordSelection))); + settings.Add (new ThemeSetting ("Keyword (Itarator)", new List<string> { "keyword.other.iteration" }, ConvertChunkStyle (colorScheme.KeywordIteration))); + settings.Add (new ThemeSetting ("Keyword (Jump)", new List<string> { "keyword.other.jump" }, ConvertChunkStyle (colorScheme.KeywordJump))); + settings.Add (new ThemeSetting ("Keyword (Context)", new List<string> { "keyword.other.context" }, ConvertChunkStyle (colorScheme.KeywordContext))); + settings.Add (new ThemeSetting ("Keyword (Exception)", new List<string> { "keyword.other.exception" }, ConvertChunkStyle (colorScheme.KeywordException))); + settings.Add (new ThemeSetting ("Keyword (Modifier)", new List<string> { "keyword.other.modifiers" }, ConvertChunkStyle (colorScheme.KeywordModifiers))); + settings.Add (new ThemeSetting ("Keyword (Void)", new List<string> { "keyword.other.void" }, ConvertChunkStyle (colorScheme.KeywordVoid))); + settings.Add (new ThemeSetting ("Keyword (Namespace)", new List<string> { "keyword.other.namespace" }, ConvertChunkStyle (colorScheme.KeywordNamespace))); + settings.Add (new ThemeSetting ("Keyword (Property)", new List<string> { "keyword.other.property" }, ConvertChunkStyle (colorScheme.KeywordProperty))); + settings.Add (new ThemeSetting ("Keyword (Declaration)", new List<string> { "keyword.other.declaration" }, ConvertChunkStyle (colorScheme.KeywordDeclaration))); + settings.Add (new ThemeSetting ("Keyword (Parameter)", new List<string> { "keyword.other.parameter" }, ConvertChunkStyle (colorScheme.KeywordParameter))); + settings.Add (new ThemeSetting ("Keyword (Operator)", new List<string> { "keyword.other.access" }, ConvertChunkStyle (colorScheme.KeywordOperatorDeclaration))); + settings.Add (new ThemeSetting ("storage", new List<string> { "storage" }, ConvertChunkStyle (colorScheme.KeywordOther))); settings.Add (new ThemeSetting ("storage.type", new List<string> { "storage.type" }, ConvertChunkStyle (colorScheme.KeywordOther))); settings.Add (new ThemeSetting ("punctuation", new List<string> { "punctuation" }, ConvertChunkStyle (colorScheme.Punctuation))); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/syntaxes/CSharp/C#.sublime-syntax b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/syntaxes/CSharp/C#.sublime-syntax index dfafc3a212..7ec0cfc9b4 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/syntaxes/CSharp/C#.sublime-syntax +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/syntaxes/CSharp/C#.sublime-syntax @@ -94,8 +94,38 @@ contexts: pop: true keywords: - match: '@\w+\b' - - match: '\b(this|base|as|is|new|sizeof|typeof|stackalloc|else|if|switch|case|default|do|for|foreach|in|while|break|continue|goto|return|yield|partial|global|where|__arglist|__makeref|__reftype|__refvalue|by|descending|from|group|into|orderby|select|let|ascending|join|on|equals|try|throw|catch|finally|abstract|async|await|const|event|extern|override|readonly|sealed|static|virtual|volatile|public|protected|private|internal|bool|byte|char|decimal|double|float|int|long|sbyte|short|uint|ushort|ulong|object|string|var|dynamic|void|namespace|using|get|set|add|remove|value|class|interface|delegate|enum|struct|params|ref|out|explicit|implicit|operator|checked|unchecked|fixed|unsafe|lock)\b' - scope: keyword.source.cs + - match: '\b(this|base)\b' + scope: keyword.other.access.source.cs + - match: '\b(as|is|new|sizeof|typeof|stackalloc)\b' + scope: keyword.operator.source.cs + - match: '\b(else|if|switch|case|default)\b' + scope: keyword.other.selection.source.cs + - match: '\b(do|for|foreach|in|while)\b' + scope: keyword.other.iteration.source.cs + - match: '\b(break|continue|goto|return)\b' + scope: keyword.other.jump.source.cs + - match: '\b(yield|partial|global|where|__arglist|__makeref|__reftype|__refvalue|by|descending|from|group|into|orderby|select|let|ascending|join|on|equals)\b' + scope: keyword.other.context.source.cs + - match: '\b(try|throw|catch|finally)\b' + scope: keyword.other.exception.source.cs + - match: '\b(abstract|async|await|const|event|extern|override|readonly|sealed|static|virtual|volatile|public|protected|private|internal)\b' + scope: keyword.other.modifiers.source.cs + - match: '\b(bool|byte|char|decimal|double|float|int|long|sbyte|short|uint|ushort|ulong|object|string|var|dynamic)\b' + scope: keyword.other.type.source.cs + - match: '\b(void)\b' + scope: keyword.other.void.source.cs + - match: '\b(namespace|using)\b' + scope: keyword.other.namespace.source.cs + - match: '\b(get|set|add|remove|value)\b' + scope: keyword.other.property.source.cs + - match: '\b(class|interface|delegate|enum|struct)\b' + scope: keyword.other.declaration.source.cs + - match: '\b(params|ref|out)\b' + scope: keyword.other.parameter.source.cs + - match: '\b(explicit|implicit|operator)\b' + scope: keyword.operator.declaration.source.cs + - match: '\b(checked|unchecked|fixed|unsafe|lock)\b' + scope: keyword.other.source.cs - match: '\b(true|false|null)\b' scope: constant.language.source.cs numbers: diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/GruvboxStyle.json b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/GruvboxStyle.json index d78fa1c2e6..cf06ce46e1 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/GruvboxStyle.json +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/GruvboxStyle.json @@ -71,10 +71,10 @@ { "name": "Debugger Current Line Marker", "color": "#69684c", "bordercolor": "#69684c" }, { "name": "Debugger Stack Line Marker", "color": "#5c6b4d", "bordercolor": "#5c6b4d" }, - { "name": "Primary Link", "color": "foreground", "secondcolor": "#7f4a81" }, - { "name": "Primary Link(Highlighted)", "color": "foreground", "secondcolor": "#b167b3" }, - { "name": "Secondary Link", "color": "foreground", "secondcolor": "#262228" }, - { "name": "Secondary Link(Highlighted)", "color": "foreground", "secondcolor": "#4e4552" }, + { "name": "Primary Link", "color": "#7f4a81", "secondcolor": "#7f4a81" }, + { "name": "Primary Link(Highlighted)", "color": "#b167b3", "secondcolor": "#b167b3" }, + { "name": "Secondary Link", "color": "#262228", "secondcolor": "#262228" }, + { "name": "Secondary Link(Highlighted)", "color": "#4e4552", "secondcolor": "#4e4552" }, { "name": "Message Bubble Error Marker", "color": "#b28d37" }, { "name": "Message Bubble Error Tag", "color": "#e3a6a1", "secondcolor": "black" }, diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/MonokaiStyle.json b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/MonokaiStyle.json index f750cb5951..f37696bc33 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/MonokaiStyle.json +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/MonokaiStyle.json @@ -79,10 +79,10 @@ { "name": "Debugger Current Line Marker", "color": "#69684c", "bordercolor": "#69684c" }, { "name": "Debugger Stack Line Marker", "color": "#618336", "bordercolor": "#618336" }, - { "name": "Primary Link", "color": "monokai-white", "secondcolor": "#7f4a81" }, - { "name": "Primary Link(Highlighted)", "color": "monokai-white", "secondcolor": "#b167b3" }, - { "name": "Secondary Link", "color": "monokai-white", "secondcolor": "#262228" }, - { "name": "Secondary Link(Highlighted)", "color": "monokai-white", "secondcolor": "#4e4552" }, + { "name": "Primary Link", "color": "#4f4a81", "secondcolor": "#4f4a81" }, + { "name": "Primary Link(Highlighted)", "color": "#4147b3", "secondcolor": "#4147b3" }, + { "name": "Secondary Link", "color": "#262228", "secondcolor": "#262228" }, + { "name": "Secondary Link(Highlighted)", "color": "#4e4552", "secondcolor": "#4e4552" }, { "name": "Message Bubble Error Marker", "color": "#b28d37" }, { "name": "Message Bubble Error Tag", "color": "#e3a6a1", "secondcolor": "black" }, diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/NightshadeStyle.json b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/NightshadeStyle.json index 383b3f67b6..21fdf806e2 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/NightshadeStyle.json +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/NightshadeStyle.json @@ -91,10 +91,10 @@ { "name": "Debugger Current Line Marker", "color": "#69684c", "bordercolor": "#69684c" }, { "name": "Debugger Stack Line Marker", "color": "#4a6429", "bordercolor": "#4a6429" }, - { "name": "Primary Link", "color": "chocolate1", "secondcolor": "chocolate3" }, - { "name": "Primary Link(Highlighted)", "color": "chocolate1", "secondcolor": "chocolate2" }, - { "name": "Secondary Link", "color": "white", "secondcolor": "aluminium6" }, - { "name": "Secondary Link(Highlighted)", "color": "aluminium1", "secondcolor": "aluminium5" }, + { "name": "Primary Link", "color": "chocolate3", "secondcolor": "chocolate3" }, + { "name": "Primary Link(Highlighted)", "color": "chocolate2", "secondcolor": "chocolate2" }, + { "name": "Secondary Link", "color": "aluminium6", "secondcolor": "aluminium6" }, + { "name": "Secondary Link(Highlighted)", "color": "aluminium5", "secondcolor": "aluminium5" }, { "name": "Message Bubble Error Marker", "color": "#b28d37" }, { "name": "Message Bubble Error Tag", "color": "#e3a6a1", "secondcolor": "black" }, diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/OblivionStyle.json b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/OblivionStyle.json index 68223e0c50..3af8b35d14 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/OblivionStyle.json +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/OblivionStyle.json @@ -83,10 +83,10 @@ { "name": "Debugger Current Line Marker", "color": "#69684c", "bordercolor": "#69684c" }, { "name": "Debugger Stack Line Marker", "color": "#5f7247", "bordercolor": "#5f7247" }, - { "name": "Primary Link", "color": "chocolate1", "secondcolor": "chocolate3" }, - { "name": "Primary Link(Highlighted)", "color": "chocolate1", "secondcolor": "chocolate2" }, - { "name": "Secondary Link", "color": "white", "secondcolor": "aluminium6" }, - { "name": "Secondary Link(Highlighted)", "color": "aluminium1", "secondcolor": "aluminium5" }, + { "name": "Primary Link", "color": "chocolate3", "secondcolor": "chocolate3" }, + { "name": "Primary Link(Highlighted)", "color": "chocolate2", "secondcolor": "chocolate2" }, + { "name": "Secondary Link", "color": "aluminium6", "secondcolor": "aluminium6" }, + { "name": "Secondary Link(Highlighted)", "color": "aluminium5", "secondcolor": "aluminium5" }, { "name": "Message Bubble Error Marker", "color": "#b28d37" }, { "name": "Message Bubble Error Tag", "color": "#e3a6a1", "secondcolor": "black" }, diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/SolarizedDarkStyle.json b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/SolarizedDarkStyle.json index ca411840d2..cc513b6a86 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/SolarizedDarkStyle.json +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/SolarizedDarkStyle.json @@ -77,6 +77,11 @@ { "name": "Debugger Current Line Marker", "color": "#69684c", "bordercolor": "#69684c" }, { "name": "Debugger Stack Line Marker", "color": "#54653f", "bordercolor": "#54653f" }, + { "name": "Primary Link", "color": "base2", "secondcolor": "base2" }, + { "name": "Primary Link(Highlighted)", "color": "base2", "secondcolor": "base2" }, + { "name": "Secondary Link", "color": "base02", "secondcolor": "base02" }, + { "name": "Secondary Link(Highlighted)", "color": "base02", "secondcolor": "base02" }, + { "name": "Message Bubble Error Marker", "color": "#b28d37" }, { "name": "Message Bubble Error Tag", "color": "#e3a6a1", "secondcolor": "black" }, { "name": "Message Bubble Error Counter", "color": "black", "secondcolor": "#e3a6a1" }, diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/SolarizedLightStyle.json b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/SolarizedLightStyle.json index 293e2d814e..926f48db6c 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/SolarizedLightStyle.json +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/themes/SolarizedLightStyle.json @@ -68,6 +68,11 @@ { "name": "Debugger Stack Line Marker", "color": "#c9e1a9", "bordercolor": "#c9e1a9" }, + { "name": "Primary Link", "color": "base02", "secondcolor": "base02" }, + { "name": "Primary Link(Highlighted)", "color": "base02", "secondcolor": "base02" }, + { "name": "Secondary Link", "color": "base2", "secondcolor": "base2" }, + { "name": "Secondary Link(Highlighted)", "color": "base2", "secondcolor": "base2" }, + { "name": "Message Bubble Error Marker", "color": "#b28d37" }, { "name": "Message Bubble Error Tag", "color": "#e3a6a1", "secondcolor": "black" }, { "name": "Message Bubble Error Counter", "color": "black", "secondcolor": "#e3a6a1" }, diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindInFilesDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindInFilesDialog.cs index 3083309e5f..bc6396245c 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindInFilesDialog.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindInFilesDialog.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 System; using System.Linq; using System.Threading; using System.Text; @@ -35,6 +35,7 @@ using Gtk; using System.Collections.Generic; using MonoDevelop.Ide.Gui.Content; using System.Threading.Tasks; +using MonoDevelop.Components.AtkCocoaHelper; namespace MonoDevelop.Ide.FindInFiles { @@ -235,8 +236,40 @@ namespace MonoDevelop.Ide.FindInFiles UpdateSensitivity (); return true; }); + SetupAccessibility (); } - + + void SetupAccessibility () + { + comboboxentryFind.SetCommonAccessibilityAttributes ("FindInFilesDialog.comboboxentryFind", + "Find", + GettextCatalog.GetString ("Enter string to find")); + comboboxentryFind.SetAccessibilityLabelRelationship (labelFind); + searchentryFileMask.SetCommonAccessibilityAttributes ("FindInFilesDialog.searchentryFileMask", + "File Mask", + GettextCatalog.GetString ("Enter the file mask")); + searchentryFileMask.SetAccessibilityLabelRelationship (labelFileMask); + } + + void SetupAccessibilityForReplace () + { + comboboxentryReplace.SetCommonAccessibilityAttributes ("FindInFilesDialog.comboboxentryReplace", + "Replace", + GettextCatalog.GetString ("Enter string to replace")); + comboboxentryReplace.SetAccessibilityLabelRelationship (labelReplace); + } + + + void SetupAccessibilityForPath () + { + comboboxentryPath.SetCommonAccessibilityAttributes ("FindInFilesDialog.comboboxentryPath", + "Path", + GettextCatalog.GetString ("Enter the Path")); + comboboxentryPath.SetAccessibilityLabelRelationship (labelPath); + } + + + static void TableAddRow (Table table, uint row, Widget column1, Widget column2) { uint rows = table.NRows; @@ -326,7 +359,8 @@ namespace MonoDevelop.Ide.FindInFiles LoadHistory ("MonoDevelop.FindReplaceDialogs.ReplaceHistory", comboboxentryReplace); comboboxentryReplace.Show (); labelReplace.Show (); - + SetupAccessibilityForReplace (); + TableAddRow (tableFindAndReplace, 1, labelReplace, comboboxentryReplace); buttonReplace = new Button () { @@ -396,6 +430,8 @@ namespace MonoDevelop.Ide.FindInFiles hboxPath.PackStart (comboboxentryPath); labelPath.MnemonicWidget = comboboxentryPath; + + SetupAccessibilityForPath (); buttonBrowsePaths = new Button { Label = "..." }; buttonBrowsePaths.Clicked += ButtonBrowsePathsClicked; @@ -679,10 +715,10 @@ namespace MonoDevelop.Ide.FindInFiles } protected override void OnDestroyed () - {
+ { if (resultPad != null) { var resultWidget = resultPad.Control.GetNativeWidget<SearchResultWidget> (); - if (resultWidget.ResultCount > 0) {
+ if (resultWidget.ResultCount > 0) { resultPad.Window.Activate (true); } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Dialogs/ItemOptionsDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Dialogs/ItemOptionsDialog.cs index 937fe4b9cc..49fbb50511 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Dialogs/ItemOptionsDialog.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Dialogs/ItemOptionsDialog.cs @@ -31,6 +31,7 @@ using MonoDevelop.Components; using MonoDevelop.Projects.Extensions; using MonoDevelop.Ide.Gui.Dialogs; using MonoDevelop.Projects; +using MonoDevelop.Core.AddIns; namespace MonoDevelop.Ide.Gui.Dialogs { @@ -56,17 +57,9 @@ namespace MonoDevelop.Ide.Gui.Dialogs extensionContext.RegisterCondition ("ProjectTypeId", new ProjectTypeIdCondition ((Project)DataObject)); extensionContext.RegisterCondition ("SupportsTarget", new SupportsTargetCondition ((Project)DataObject)); } else { - extensionContext.RegisterCondition ("AppliesTo", new FalseCondition ()); - extensionContext.RegisterCondition ("FlavorType", new FalseCondition ()); - extensionContext.RegisterCondition ("ProjectTypeId", new FalseCondition ()); - } - } - - class FalseCondition: ConditionType - { - public override bool Evaluate (NodeElement conditionNode) - { - return false; + extensionContext.RegisterCondition ("AppliesTo", FalseCondition.Instance); + extensionContext.RegisterCondition ("FlavorType", FalseCondition.Instance); + extensionContext.RegisterCondition ("ProjectTypeId", FalseCondition.Instance); } } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.OptionPanels/DotNetCompileTargetSelector.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.OptionPanels/DotNetCompileTargetSelector.cs new file mode 100644 index 0000000000..2d4c1ed5f8 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.OptionPanels/DotNetCompileTargetSelector.cs @@ -0,0 +1,53 @@ +// +// DotNetCompileTargetSelector.cs +// +// Author: +// Jason Imison <jaimison@microsoft.com> +// +// Copyright (c) 2017 Microsoft Corporation +// +// 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 Gtk; +using MonoDevelop.Core; +using MonoDevelop.Projects; + +namespace MonoDevelop.Ide.Gui.OptionPanels +{ + public class DotNetCompileTargetSelector : ComboBox + { + public DotNetCompileTargetSelector () + { + var store = new ListStore (typeof (string)); + store.AppendValues (GettextCatalog.GetString ("Executable")); + store.AppendValues (GettextCatalog.GetString ("Library")); + store.AppendValues (GettextCatalog.GetString ("Executable with GUI")); + store.AppendValues (GettextCatalog.GetString ("Module")); + this.Model = store; + var cr = new CellRendererText (); + this.PackStart (cr, true); + this.AddAttribute (cr, "text", 0); + } + + public CompileTarget CompileTarget { + get { return (CompileTarget)this.Active; } + set { this.Active = (int)value; } + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads/ErrorListPad.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads/ErrorListPad.cs index f7538ac892..0e5eead727 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads/ErrorListPad.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads/ErrorListPad.cs @@ -631,17 +631,10 @@ namespace MonoDevelop.Ide.Gui.Pads var descriptionCol = view.AppendColumn (GettextCatalog.GetString ("Description"), descriptionCellRenderer); descriptionCol.SetCellDataFunc (descriptionCellRenderer, new Gtk.TreeCellDataFunc (DescriptionDataFunc)); descriptionCol.Resizable = true; - descriptionCellRenderer.WrapMode = Pango.WrapMode.Word; descriptionCellRenderer.PreferedMaxWidth = IdeApp.Workbench.RootWindow.Allocation.Width / 3; + descriptionCellRenderer.WrapWidth = descriptionCellRenderer.PreferedMaxWidth; + descriptionCellRenderer.WrapMode = Pango.WrapMode.Word; - descriptionCol.AddNotification("width", delegate - { - if (descriptionCellRenderer.WrapWidth == descriptionCol.Width) - return; - descriptionCellRenderer.WrapWidth = descriptionCol.Width; - descriptionCol.QueueResize (); - }); - col = view.AppendColumn (GettextCatalog.GetString ("File"), view.TextRenderer); col.SetCellDataFunc (view.TextRenderer, new Gtk.TreeCellDataFunc (FileDataFunc)); col.Resizable = true; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/MonoDevelopStatusBar.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/MonoDevelopStatusBar.cs index 669aa6dcdb..4f211b52ec 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/MonoDevelopStatusBar.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/MonoDevelopStatusBar.cs @@ -35,6 +35,7 @@ using System.Collections.Generic; using MonoDevelop.Components.Docking; using MonoDevelop.Ide.Gui.Dialogs; using MonoDevelop.Components; +using MonoDevelop.Components.AtkCocoaHelper; using MonoDevelop.Components.MainToolbar; namespace MonoDevelop.Ide @@ -52,13 +53,19 @@ namespace MonoDevelop.Ide Spacing = 0; HasResizeGrip = true; + Accessible.Role = Atk.Role.Filler; + HeaderBox hb = new HeaderBox (1, 0, 0, 0); + hb.Accessible.Role = Atk.Role.Filler; hb.StyleSet += (o, args) => { hb.BorderColor = Styles.DockSeparatorColor.ToGdkColor (); hb.BackgroundColor = Styles.DockBarBackground.ToGdkColor (); }; var mainBox = new HBox (); - mainBox.PackStart (new Label (""), true, true, 0); + mainBox.Accessible.Role = Atk.Role.Filler; + var alignment = new Alignment (0f, 0f, 0f, 0f); + alignment.Accessible.Role = Atk.Role.Filler; + mainBox.PackStart (alignment, true, true, 0); hb.Add (mainBox); hb.ShowAll (); PackStart (hb, true, true, 0); @@ -67,15 +74,26 @@ namespace MonoDevelop.Ide if (FeedbackService.Enabled) { CustomFrame fr = new CustomFrame (0, 0, 1, 0); + fr.Accessible.Role = Atk.Role.Filler; var px = Xwt.Drawing.Image.FromResource ("feedback-16.png"); HBox b = new HBox (false, 3); - b.PackStart (new Xwt.ImageView (px).ToGtkWidget ()); - b.PackStart (new Gtk.Label ("Feedback")); + b.Accessible.Role = Atk.Role.Filler; + + var im = new Xwt.ImageView (px).ToGtkWidget (); + im.Accessible.Role = Atk.Role.Filler; + b.PackStart (im); + var label = new Gtk.Label (GettextCatalog.GetString ("Feedback")); + label.Accessible.Role = Atk.Role.Filler; + b.PackStart (label); Gtk.Alignment al = new Gtk.Alignment (0f, 0f, 1f, 1f); + al.Accessible.Role = Atk.Role.Filler; al.RightPadding = 5; al.LeftPadding = 3; al.Add (b); feedbackButton = new MiniButton (al); + feedbackButton.Accessible.SetLabel (GettextCatalog.GetString ("Feedback")); + feedbackButton.Accessible.Description = GettextCatalog.GetString ("Click to send feedback to the development team"); + //feedbackButton.BackroundColor = new Gdk.Color (200, 200, 255); fr.Add (feedbackButton); mainBox.PackStart (fr, false, false, 0); @@ -99,6 +117,7 @@ namespace MonoDevelop.Ide // Dock area CustomFrame dfr = new CustomFrame (0, 0, 1, 0); + dfr.Accessible.Role = Atk.Role.Filler; dfr.StyleSet += (o, args) => { dfr.BorderColor = Styles.DockSeparatorColor.ToGdkColor (); }; @@ -113,6 +132,7 @@ namespace MonoDevelop.Ide // Resize grip + resizeGrip.Accessible.SetRole (AtkCocoa.Roles.AXGrowArea); resizeGrip.WidthRequest = ResizeGripWidth; resizeGrip.HeightRequest = 0; resizeGrip.VisibleWindow = false; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/SdiWorkspaceWindow.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/SdiWorkspaceWindow.cs index 08f596c6aa..b887e4d0da 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/SdiWorkspaceWindow.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/SdiWorkspaceWindow.cs @@ -354,11 +354,42 @@ namespace MonoDevelop.Ide.Gui static IEnumerable<Gtk.Widget> GetFocussableWidgets (Gtk.Widget widget) { var c = widget as Container; - if (widget.CanFocus) + + if (widget.CanFocus) { yield return widget; + } + if (c != null) { - foreach (var f in c.FocusChain.SelectMany (GetFocussableWidgets).Where (y => y != null)) + foreach (var f in c.FocusChain.SelectMany (GetFocussableWidgets).Where (y => y != null)) { yield return f; + } + } + + if (c?.Children?.Length != 0) { + foreach (var f in c.Children) { + var container = f as Container; + if (container != null) { + foreach (var child in GetFocussableChildren (container)) { + yield return child; + } + } + } + } + } + + static IEnumerable<Gtk.Widget> GetFocussableChildren (Gtk.Container container) + { + if (container.CanFocus) { + yield return container; + } + + foreach (var f in container.Children) { + var c = f as Container; + if (c != null) { + foreach (var child in GetFocussableChildren (c)) { + yield return child; + } + } } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Workbench.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Workbench.cs index 509e56c695..a1c6bb1584 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Workbench.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Workbench.cs @@ -369,6 +369,12 @@ namespace MonoDevelop.Ide.Gui if (result == AlertButton.Cancel) return false; + if (result == AlertButton.CloseWithoutSave) { + doc.Window.ViewContent.DiscardChanges (); + await doc.Window.CloseWindow (true); + continue; + } + await doc.Save (); if (doc.IsDirty) { doc.Select (); @@ -385,8 +391,8 @@ namespace MonoDevelop.Ide.Gui (object)(doc.Window.ViewContent.IsUntitled ? doc.Window.ViewContent.UntitledName : System.IO.Path.GetFileName (doc.Window.ViewContent.ContentName))), - "", - AlertButton.Cancel, doc.Window.ViewContent.IsUntitled ? AlertButton.SaveAs : AlertButton.Save); + GettextCatalog.GetString ("If you don't save, all changes will be permanently lost."), + AlertButton.CloseWithoutSave, AlertButton.Cancel, doc.Window.ViewContent.IsUntitled ? AlertButton.SaveAs : AlertButton.Save); } public void CloseAllDocuments (bool leaveActiveDocumentOpen) @@ -579,7 +585,6 @@ namespace MonoDevelop.Ide.Gui if (info.Options.HasFlag (OpenDocumentOptions.BringToFront)) { doc.Select (); - doc.Window.SelectWindow (); NavigationHistoryService.LogActiveDocument (); } return doc; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/BaseDirectoryPanelWidget.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/BaseDirectoryPanelWidget.cs index 0094dea3de..7f0ed03eca 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/BaseDirectoryPanelWidget.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/BaseDirectoryPanelWidget.cs @@ -1,4 +1,4 @@ -// BaseDirectoryPanel.cs +// BaseDirectoryPanel.cs // // Author: // Lluis Sanchez Gual <lluis@novell.com> @@ -44,9 +44,15 @@ namespace MonoDevelop.Ide.Projects.OptionPanels var a = folderentry.EntryAccessible; a.SetTitleUIElement (label3.Accessible); label3.Accessible.SetTitleFor (a); + SetupAccessibility (); + } + + private void SetupAccessibility () + { folderentry.SetEntryAccessibilityAttributes ("BaseDirectory.FolderEntry", - GettextCatalog.GetString ("Root Directory"), - GettextCatalog.GetString ("Entry the root directory for the project")); + GettextCatalog.GetString ("Root Directory"), + GettextCatalog.GetString ("Entry the root directory for the project")); + folderentry.SetAccessibilityLabelRelationship (label3); } public string BaseDirectory { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CombineBuildOptions.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CombineBuildOptions.cs index 9cf84eca7b..0f2da9d00d 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CombineBuildOptions.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CombineBuildOptions.cs @@ -27,6 +27,8 @@ using System; using MonoDevelop.Components; using MonoDevelop.Ide.Gui.Dialogs; using MonoDevelop.Projects; +using MonoDevelop.Components.AtkCocoaHelper; +using MonoDevelop.Core; namespace MonoDevelop.Ide.Projects.OptionPanels { @@ -54,6 +56,16 @@ namespace MonoDevelop.Ide.Projects.OptionPanels Build (); this.solution = solution; folderEntry.Path = solution.OutputDirectory; + SetupAccessibility (); + } + + private void SetupAccessibility () + { + + folderEntry.SetCommonAccessibilityAttributes ("CombineBuildOptions.folderEntry", + "", + GettextCatalog.GetString ("Enter the output directory")); + folderEntry.SetAccessibilityLabelRelationship (this.label73); } public void Store() diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CombineInformationPanel.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CombineInformationPanel.cs index 766f937ea7..10e3e684b9 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CombineInformationPanel.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/CombineInformationPanel.cs @@ -34,6 +34,8 @@ using MonoDevelop.Core; using MonoDevelop.Ide.Gui.Dialogs; using Gtk; using MonoDevelop.Components; +using MonoDevelop.Components.AtkCocoaHelper; + namespace MonoDevelop.Ide.Projects.OptionPanels { @@ -63,7 +65,16 @@ namespace MonoDevelop.Ide.Projects.OptionPanels versEntry.Text = solution.Version; descView.Buffer.Text = solution.Description; - } + SetupAccessibility (); + } + + void SetupAccessibility () + { + versEntry.SetCommonAccessibilityAttributes ("CombineInformationPanel.versEntry", + "", + GettextCatalog.GetString ("Enter the version")); + versEntry.SetAccessibilityLabelRelationship (versLabel); + } public void Store (Solution solution) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/GeneralProjectOptions.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/GeneralProjectOptions.cs index 1cd80fb20f..98fa93ede2 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/GeneralProjectOptions.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/GeneralProjectOptions.cs @@ -42,13 +42,12 @@ namespace MonoDevelop.Ide.Projects.OptionPanels { return widget = new GeneralProjectOptionsWidget (ConfiguredProject, ParentDialog); } - + public override void ApplyChanges() { widget.Store (); } } - partial class GeneralProjectOptionsWidget : Gtk.Bin { Project project; @@ -57,12 +56,9 @@ namespace MonoDevelop.Ide.Projects.OptionPanels public GeneralProjectOptionsWidget (Project project, OptionsDialog dialog) { Build (); - this.project = project; this.dialog = dialog; - nameLabel.UseUnderline = true; - descriptionLabel.UseUnderline = true; projectNameEntry.Text = project.Name; @@ -76,7 +72,6 @@ namespace MonoDevelop.Ide.Projects.OptionPanels defaultNamespaceLabel.Visible = false; projectDefaultNamespaceEntry.Visible = false; } - entryVersion.Text = project.Version; checkSolutionVersion.Active = project.SyncVersionWithSolution; entryVersion.Sensitive = !project.SyncVersionWithSolution; @@ -86,6 +81,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels void SetAccessibilityAttributes () { + label55.Accessible.Role = Atk.Role.Filler; informationHeaderLabel.Accessible.SetTitleFor (table11.Accessible); table11.Accessible.SetTitleUIElement (informationHeaderLabel.Accessible); @@ -117,7 +113,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels GettextCatalog.GetString ("Enter the default namespace for the project")); defaultNamespaceLabel.Accessible.SetTitleFor (projectDescriptionTextView.Accessible); } - + public void Store () { if (projectNameEntry.Text != project.Name) { @@ -125,7 +121,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels if (project.ParentSolution != null) dialog.ModifiedObjects.Add (project.ParentSolution); } - + project.Description = projectDescriptionTextView.Buffer.Text; if (project is DotNetProject) { ((DotNetProject)project).DefaultNamespace = projectDefaultNamespaceEntry.Text; @@ -151,4 +147,3 @@ namespace MonoDevelop.Ide.Projects.OptionPanels } } - diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/OutputOptionsPanel.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/OutputOptionsPanel.cs index afb3211a3f..8e9ea17f25 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/OutputOptionsPanel.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/OutputOptionsPanel.cs @@ -94,6 +94,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels void SetupAccessibility () { + label91.Accessible.Role = Atk.Role.Filler; assemblyNameEntry.SetCommonAccessibilityAttributes ("OutputOptionsPanel.AssemblyEntry", GettextCatalog.GetString ("Assembly Name"), GettextCatalog.GetString ("Enter the name of the output assembly")); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/LanguageCellRenderer.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/LanguageCellRenderer.cs index cf30a4f59d..e2454a959f 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/LanguageCellRenderer.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/LanguageCellRenderer.cs @@ -93,7 +93,7 @@ namespace MonoDevelop.Ide.Projects return; } - if (!Template.AvailableLanguages.Any () || !IsTemplateRowSelected (widget, flags)) { + if (!RenderRecentTemplate && (!Template.AvailableLanguages.Any () || !IsTemplateRowSelected (widget, flags))) { return; } 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 d906a3910a..b1309458b6 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs @@ -57,7 +57,7 @@ namespace MonoDevelop.Ide.Projects const string UseGitPropertyName = "Dialogs.NewProjectDialog.UseGit";
const string CreateGitIgnoreFilePropertyName = "Dialogs.NewProjectDialog.CreateGitIgnoreFile";
- const string CreateProjectSubDirectoryPropertyName = "MonoDevelop.Core.Gui.Dialogs.NewProjectDialog.AutoCreateProjectSubdir";
+ internal const string CreateProjectSubDirectoryPropertyName = "MonoDevelop.Core.Gui.Dialogs.NewProjectDialog.AutoCreateProjectSubdir";
const string NewSolutionLastSelectedCategoryPropertyName = "Dialogs.NewProjectDialog.LastSelectedCategoryPath";
const string NewSolutionLastSelectedTemplatePropertyName = "Dialogs.NewProjectDialog.LastSelectedTemplate";
const string NewProjectLastSelectedCategoryPropertyName = "Dialogs.NewProjectDialog.AddNewProjectLastSelectedCategoryPath";
@@ -193,7 +193,8 @@ namespace MonoDevelop.Ide.Projects SetDefaultLocation ();
SetDefaultGitSettings ();
SelectedLanguage = PropertyService.Get (SelectedLanguagePropertyName, "C#");
- projectConfiguration.CreateProjectDirectoryInsideSolutionDirectory = PropertyService.Get (CreateProjectSubDirectoryPropertyName, true);
+ if (IsNewSolution)
+ projectConfiguration.CreateProjectDirectoryInsideSolutionDirectory = PropertyService.Get (CreateProjectSubDirectoryPropertyName, true);
}
void UpdateDefaultSettings ()
@@ -268,7 +269,7 @@ namespace MonoDevelop.Ide.Projects PropertyService.Set (CreateGitIgnoreFilePropertyName, projectConfiguration.CreateGitIgnoreFile);
}
- INewProjectDialogBackend CreateNewProjectDialog ()
+ protected virtual INewProjectDialogBackend CreateNewProjectDialog ()
{
return new GtkNewProjectDialogBackend ();
}
@@ -315,11 +316,25 @@ namespace MonoDevelop.Ide.Projects void LoadTemplateCategories ()
{
Predicate<SolutionTemplate> templateMatch = GetTemplateFilter ();
- templateCategories = IdeApp.Services.TemplatingService.GetProjectTemplateCategories (templateMatch).ToList ();
+ templateCategories = TemplatingService.GetProjectTemplateCategories (templateMatch).ToList ();
if (IsNewSolution)
- recentTemplates = IdeApp.Services.TemplatingService.RecentTemplates.GetTemplates (templateCategories).Where (t => t.IsMatch (SolutionTemplateVisibility.NewSolution)).ToList ();
+ recentTemplates = TemplatingService.RecentTemplates.GetTemplates (templateCategories).Where (t => t.IsMatch (SolutionTemplateVisibility.NewSolution)).ToList ();
else
- recentTemplates = IdeApp.Services.TemplatingService.RecentTemplates.GetTemplates (templateCategories).ToList ();
+ recentTemplates = TemplatingService.RecentTemplates.GetTemplates (templateCategories).ToList ();
+ }
+
+ // Allow testing of the controller by allowing tests to specify the
+ // TemplatingService. IdeApp.Services is not initialized during unit tests.
+ TemplatingService templatingService;
+
+ internal TemplatingService TemplatingService {
+ get {
+ if (templatingService != null)
+ return templatingService;
+
+ return IdeApp.Services.TemplatingService;
+ }
+ set { templatingService = value; }
}
Predicate<SolutionTemplate> GetTemplateFilter ()
@@ -480,7 +495,7 @@ namespace MonoDevelop.Ide.Projects // Fallback to checking all templates that match the template id in the same category
// and support the condition.
- SolutionTemplate matchedTemplate = IdeApp.Services.TemplatingService.GetTemplate (
+ SolutionTemplate matchedTemplate = TemplatingService.GetTemplate (
templateCategories,
currentTemplate => IsTemplateMatch (currentTemplate, SelectedTemplate, language, finalConfigurationPage.Parameters),
category => true,
@@ -746,7 +761,7 @@ namespace MonoDevelop.Ide.Projects DisposeExistingNewItems ();
try {
- result = await IdeApp.Services.TemplatingService.ProcessTemplate (template, projectConfiguration, ParentFolder);
+ result = await 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/FileTemplate.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/FileTemplate.cs index 1e511e3a34..b183a357c2 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/FileTemplate.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/FileTemplate.cs @@ -38,6 +38,7 @@ using System.Xml; using Gtk; using Mono.Addins; using MonoDevelop.Core; +using MonoDevelop.Core.AddIns; using MonoDevelop.Ide.Codons; using MonoDevelop.Ide.Gui; using MonoDevelop.Projects; @@ -220,9 +221,9 @@ namespace MonoDevelop.Ide.Templates extensionContext.RegisterCondition ("FlavorType", new FlavorTypeCondition (project)); extensionContext.RegisterCondition ("ProjectTypeId", new ProjectTypeIdCondition (project)); } else { - extensionContext.RegisterCondition ("AppliesTo", new TrueCondition ()); - extensionContext.RegisterCondition ("FlavorType", new TrueCondition ()); - extensionContext.RegisterCondition ("ProjectTypeId", new TrueCondition ()); + extensionContext.RegisterCondition ("AppliesTo", TrueCondition.Instance); + extensionContext.RegisterCondition ("FlavorType", TrueCondition.Instance); + extensionContext.RegisterCondition ("ProjectTypeId", TrueCondition.Instance); } var list = new List<FileTemplate> (); @@ -236,14 +237,6 @@ namespace MonoDevelop.Ide.Templates return list; } - class TrueCondition : ConditionType - { - public override bool Evaluate (NodeElement conditionNode) - { - return true; - } - } - internal static FileTemplate GetFileTemplateByID (string templateID) { var node = AddinManager.GetExtensionNodes<ProjectTemplateCodon> (EXTENSION_PATH) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineProjectTemplatingProvider.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineProjectTemplatingProvider.cs index 1b1854e247..5cf26b9d36 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineProjectTemplatingProvider.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/MicrosoftTemplateEngineProjectTemplatingProvider.cs @@ -44,6 +44,7 @@ using Microsoft.TemplateEngine.Abstractions; using MonoDevelop.Ide.CodeFormatting; using MonoDevelop.Core.StringParsing; using MonoDevelop.Core.Text; +using MonoDevelop.Projects.Policies; namespace MonoDevelop.Ide.Templates { @@ -147,6 +148,9 @@ namespace MonoDevelop.Ide.Templates var parameters = GetParameters (solutionTemplate, config); var templateInfo = solutionTemplate.templateInfo; var workspaceItems = new List<IWorkspaceFileObject> (); + + var filesBeforeCreation = Directory.GetFiles (config.ProjectLocation, "*", SearchOption.AllDirectories); + var result = await templateCreator.InstantiateAsync ( templateInfo, config.ProjectName, @@ -174,10 +178,10 @@ namespace MonoDevelop.Ide.Templates } //TODO: Once templates support "D396686C-DE0E-4DE6-906D-291CD29FC5DE" use that to load projects - 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)); - } + foreach (var path in result.ResultInfo.PrimaryOutputs) { + var fullPath = Path.Combine (config.ProjectLocation, path.Path); + if (Services.ProjectService.IsSolutionItemFile (fullPath)) + workspaceItems.Add (await MonoDevelop.Projects.Services.ProjectService.ReadSolutionItem (new Core.ProgressMonitor (), fullPath)); } var metadata = new Dictionary<string, string> (); @@ -215,7 +219,8 @@ namespace MonoDevelop.Ide.Templates // Format all source files generated during the project creation foreach (var p in workspaceItems.OfType<Project> ()) { foreach (var file in p.Files) - await FormatFile (p, file.FilePath); + if (!filesBeforeCreation.Contains ((string)file.FilePath, FilePath.PathComparer)) //Format only newly created files + await FormatFile (parentFolder?.Policies ?? p.Policies, file.FilePath); } processResult.SetFilesToOpen (filesToOpen); return processResult; @@ -249,7 +254,7 @@ namespace MonoDevelop.Ide.Templates .Where (parameter => parameter.IsValid); } - async Task FormatFile (Project p, FilePath file) + async Task FormatFile (PolicyContainer policies, FilePath file) { string mime = DesktopService.GetMimeTypeForUri (file); if (mime == null) @@ -259,7 +264,7 @@ namespace MonoDevelop.Ide.Templates if (formatter != null) { try { var content = await TextFileUtility.ReadAllTextAsync (file); - var formatted = formatter.FormatText (p.Policies, content.Text); + var formatted = formatter.FormatText (policies, content.Text); if (formatted != null) TextFileUtility.WriteText (file, formatted, content.Encoding); } catch (Exception ex) { 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 0b917b754f..22a3df9eaa 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/ProjectTemplatingProvider.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/ProjectTemplatingProvider.cs @@ -82,7 +82,7 @@ namespace MonoDevelop.Ide.Templates cinfo.ProjectName = config.ProjectName;
cinfo.SolutionName = config.SolutionName;
cinfo.ParentFolder = parentFolder;
- cinfo.ActiveConfiguration = IdeApp.Workspace.ActiveConfiguration;
+ cinfo.ActiveConfiguration = IdeApp.Workspace?.ActiveConfiguration ?? ConfigurationSelector.Default;
cinfo.Parameters = config.Parameters;
return cinfo;
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplateImageProvider.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplateImageProvider.cs index fb699a2907..9558d8849b 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplateImageProvider.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/TemplateImageProvider.cs @@ -52,7 +52,11 @@ namespace MonoDevelop.Ide.Templates Image LoadImageFromResource (string imageId)
{
- return IdeApp.Services.TemplatingService.LoadTemplateImage (imageId);
+ if (IdeApp.IsInitialized)
+ return IdeApp.Services.TemplatingService.LoadTemplateImage (imageId);
+
+ // Should only happen when running unit tests.
+ return null;
}
public void Dispose ()
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj index f439777a80..9a8a810544 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj @@ -1,10 +1,8 @@ -<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> <Import Project="..\..\..\MonoDevelop.props" /> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <ProductVersion>8.0.30703</ProductVersion> - <SchemaVersion>2.0</SchemaVersion> <ProjectGuid>{27096E7F-C91C-4AC6-B289-6897A701DF21}</ProjectGuid> <OutputType>Library</OutputType> <AssemblyName>MonoDevelop.Ide</AssemblyName> @@ -102,21 +100,10 @@ <NoWarn>1591;1573</NoWarn> </PropertyGroup> <ItemGroup> - <Reference Include="System" /> - <Reference Include="System.Drawing" /> - <Reference Include="System.Xml" /> - <Reference Include="System.Data" /> - <Reference Include="System.Web.Services" /> - <Reference Include="Mono.Posix" /> - <Reference Include="System.Runtime.Remoting" /> - <Reference Include="monodoc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" /> - <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f"> - <SpecificVersion>False</SpecificVersion> - </Reference> <Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f"> <SpecificVersion>False</SpecificVersion> </Reference> - <Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f"> + <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f"> <SpecificVersion>False</SpecificVersion> </Reference> <Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f"> @@ -125,29 +112,68 @@ <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f"> <SpecificVersion>False</SpecificVersion> </Reference> - <Reference Include="System.Core" /> - <Reference Include="Mono.Cairo" /> - <Reference Include="System.Web" /> - <Reference Include="System.Xml.Linq" /> - <Reference Include="System.Design" /> - <Reference Include="System.Windows.Forms" /> - <Reference Include="System.Runtime.Serialization" /> - <Reference Include="System.Threading.Tasks.Dataflow, Version=4.6.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> - <HintPath>..\..\..\packages\System.Threading.Tasks.Dataflow.4.7.0\lib\netstandard1.0\System.Threading.Tasks.Dataflow.dll</HintPath> - <Private>True</Private> + <Reference Include="ICSharpCode.SharpZipLib"> + <HintPath>..\..\..\packages\JetBrains.SharpZipLib.Stripped.0.87.20170615.10\lib\net40\ICSharpCode.SharpZipLib.dll</HintPath> </Reference> - <Reference Include="Xamarin.Mac" Condition=" '$(Configuration)' == 'DebugMac' Or '$(Configuration)' == 'ReleaseMac' "> - <HintPath>..\..\..\external\Xamarin.Mac.dll</HintPath> + <Reference Include="Microsoft.CodeAnalysis"> + <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.Common.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.dll</HintPath> + </Reference> + <Reference Include="Microsoft.CodeAnalysis.CSharp"> + <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.CSharp.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll</HintPath> + </Reference> + <Reference Include="Microsoft.CodeAnalysis.CSharp.Features"> + <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.CSharp.Features.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.Features.dll</HintPath> + </Reference> + <Reference Include="Microsoft.CodeAnalysis.CSharp.Workspaces"> + <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.Workspaces.dll</HintPath> + </Reference> + <Reference Include="Microsoft.CodeAnalysis.EditorFeatures"> + <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.EditorFeatures.2.3.0-beta1\lib\net46\Microsoft.CodeAnalysis.EditorFeatures.dll</HintPath> + </Reference> + <Reference Include="Microsoft.CodeAnalysis.EditorFeatures.Text"> + <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.EditorFeatures.Text.2.3.0-beta1\lib\net46\Microsoft.CodeAnalysis.EditorFeatures.Text.dll</HintPath> + </Reference> + <Reference Include="Microsoft.CodeAnalysis.Elfie"> + <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.Elfie.1.0.0-rc9\lib\net45\Microsoft.CodeAnalysis.Elfie.dll</HintPath> + </Reference> + <Reference Include="Microsoft.CodeAnalysis.Features"> + <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.Features.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.Features.dll</HintPath> + </Reference> + <Reference Include="Microsoft.CodeAnalysis.VisualBasic"> + <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.VisualBasic.dll</HintPath> + </Reference> + <Reference Include="Microsoft.CodeAnalysis.VisualBasic.Features"> + <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.Features.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.VisualBasic.Features.dll</HintPath> + </Reference> + <Reference Include="Microsoft.CodeAnalysis.VisualBasic.Workspaces"> + <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.Workspaces.2.3.0-beta1\lib\netstandard1.3\Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll</HintPath> + </Reference> + <Reference Include="Microsoft.CodeAnalysis.Workspaces"> + <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.2.3.0-beta1\lib\net46\Microsoft.CodeAnalysis.Workspaces.dll</HintPath> + </Reference> + <Reference Include="Microsoft.CodeAnalysis.Workspaces.Desktop"> + <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.2.3.0-beta1\lib\net46\Microsoft.CodeAnalysis.Workspaces.Desktop.dll</HintPath> + </Reference> + <Reference Include="Microsoft.TemplateEngine.Abstractions"> + <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Abstractions.1.0.0-beta2-20170523-241\lib\net45\Microsoft.TemplateEngine.Abstractions.dll</HintPath> + </Reference> + <Reference Include="Microsoft.TemplateEngine.Core"> + <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Core.1.0.0-beta2-20170523-241\lib\net45\Microsoft.TemplateEngine.Core.dll</HintPath> + </Reference> + <Reference Include="Microsoft.TemplateEngine.Core.Contracts"> + <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Core.Contracts.1.0.0-beta2-20170523-241\lib\net45\Microsoft.TemplateEngine.Core.Contracts.dll</HintPath> + </Reference> + <Reference Include="Microsoft.TemplateEngine.Edge"> + <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Edge.1.0.0-beta2-20170523-241\lib\net45\Microsoft.TemplateEngine.Edge.dll</HintPath> + </Reference> + <Reference Include="Microsoft.TemplateEngine.Orchestrator.RunnableProjects"> + <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Orchestrator.RunnableProjects.1.0.0-beta2-20170523-241\lib\net45\Microsoft.TemplateEngine.Orchestrator.RunnableProjects.dll</HintPath> + </Reference> + <Reference Include="Microsoft.TemplateEngine.Utils"> + <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Utils.1.0.0-beta2-20170523-241\lib\net45\Microsoft.TemplateEngine.Utils.dll</HintPath> </Reference> - <Reference Include="System.Windows" Condition=" '$(Configuration)' == 'DebugWin32' Or '$(Configuration)' == 'ReleaseWin32' " /> - <Reference Include="PresentationCore" Condition=" '$(Configuration)' == 'DebugWin32' Or '$(Configuration)' == 'ReleaseWin32' " /> - <Reference Include="PresentationFramework" Condition=" '$(Configuration)' == 'DebugWin32' Or '$(Configuration)' == 'ReleaseWin32' " /> - <Reference Include="WindowsBase" Condition=" '$(Configuration)' == 'DebugWin32' Or '$(Configuration)' == 'ReleaseWin32' " /> - <Reference Include="WindowsFormsIntegration" Condition=" '$(Configuration)' == 'DebugWin32' Or '$(Configuration)' == 'ReleaseWin32' " /> - <Reference Include="System.Xaml" /> <Reference Include="Microsoft.VisualStudio.Composition, Version=15.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <HintPath>..\..\..\packages\Microsoft.VisualStudio.Composition.15.3.38\lib\net45\Microsoft.VisualStudio.Composition.dll</HintPath> - <Private>True</Private> </Reference> <Reference Include="Microsoft.VisualStudio.CoreUtility"> <HintPath>..\..\..\packages\Microsoft.VisualStudio.CoreUtility.15.0.26201\lib\net45\Microsoft.VisualStudio.CoreUtility.dll</HintPath> @@ -165,71 +191,67 @@ <HintPath>..\..\..\packages\Microsoft.VisualStudio.Validation.15.3.15\lib\net45\Microsoft.VisualStudio.Validation.dll</HintPath> <Private>True</Private> </Reference> - <Reference Include="System.ComponentModel.Composition" /> - <Reference Include="ICSharpCode.SharpZipLib"> - <HintPath>..\..\..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath> - <Private>False</Private> - </Reference> - <Reference Include="System.Collections.Immutable"> - <HintPath>..\..\..\build\bin\System.Collections.Immutable.dll</HintPath> - </Reference> - <Reference Include="System.Reflection.Metadata"> - <HintPath>..\..\..\build\bin\System.Reflection.Metadata.dll</HintPath> - </Reference> - <Reference Include="Microsoft.CodeAnalysis"> - <HintPath>..\..\..\build\bin\Microsoft.CodeAnalysis.dll</HintPath> - <Private>False</Private> - </Reference> - <Reference Include="Microsoft.CodeAnalysis.Workspaces"> - <HintPath>..\..\..\build\bin\Microsoft.CodeAnalysis.Workspaces.dll</HintPath> - <Private>False</Private> - </Reference> - <Reference Include="Microsoft.CodeAnalysis.Workspaces.Desktop"> - <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.2.3.0-beta1\lib\net46\Microsoft.CodeAnalysis.Workspaces.Desktop.dll</HintPath> + <Reference Include="Mono.Cairo" /> + <Reference Include="Mono.Posix" /> + <Reference Include="monodoc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" /> + <Reference Include="mscorlib" /> + <Reference Include="Newtonsoft.Json"> + <HintPath>..\..\..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <Private>False</Private> </Reference> - <Reference Include="Microsoft.CodeAnalysis.EditorFeatures.Text"> - <HintPath>..\..\..\packages\Microsoft.CodeAnalysis.EditorFeatures.Text.2.3.0-beta1\lib\net46\Microsoft.CodeAnalysis.EditorFeatures.Text.dll</HintPath> - <Private>False</Private> + <Reference Include="pango-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f"> + <SpecificVersion>False</SpecificVersion> </Reference> - <Reference Include="ICSharpCode.SharpZipLib"> - <HintPath>..\..\..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath> + <Reference Include="PresentationCore" Condition=" '$(Configuration)' == 'DebugWin32' Or '$(Configuration)' == 'ReleaseWin32' " /> + <Reference Include="PresentationFramework" Condition=" '$(Configuration)' == 'DebugWin32' Or '$(Configuration)' == 'ReleaseWin32' " /> + <Reference Include="System" /> + <Reference Include="System.Collections.Immutable"> + <HintPath>..\..\..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath> </Reference> + <Reference Include="System.ComponentModel.Composition" /> <Reference Include="System.Composition.AttributedModel"> <HintPath>..\..\..\packages\System.Composition.AttributedModel.1.0.31\lib\netstandard1.0\System.Composition.AttributedModel.dll</HintPath> </Reference> + <Reference Include="System.Composition.Convention"> + <HintPath>..\..\..\packages\Microsoft.Composition.1.0.30\lib\portable-net45+win8+wp8+wpa81\System.Composition.Convention.dll</HintPath> + </Reference> + <Reference Include="System.Composition.Hosting"> + <HintPath>..\..\..\packages\System.Composition.Hosting.1.0.31\lib\netstandard1.0\System.Composition.Hosting.dll</HintPath> + </Reference> <Reference Include="System.Composition.Runtime"> <HintPath>..\..\..\packages\System.Composition.Runtime.1.0.31\lib\netstandard1.0\System.Composition.Runtime.dll</HintPath> </Reference> - <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> - <Private>False</Private> + <Reference Include="System.Composition.TypedParts"> + <HintPath>..\..\..\packages\System.Composition.TypedParts.1.0.31\lib\netstandard1.0\System.Composition.TypedParts.dll</HintPath> </Reference> + <Reference Include="System.Core" /> + <Reference Include="System.Data" /> + <Reference Include="System.Design" /> + <Reference Include="System.Drawing" /> <Reference Include="System.IO.Compression" /> - <Reference Include="Microsoft.TemplateEngine.Abstractions"> - <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Abstractions.1.0.0-beta2-20170523-241\lib\net45\Microsoft.TemplateEngine.Abstractions.dll</HintPath> - </Reference> - <Reference Include="Microsoft.TemplateEngine.Core.Contracts"> - <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Core.Contracts.1.0.0-beta2-20170523-241\lib\net45\Microsoft.TemplateEngine.Core.Contracts.dll</HintPath> - </Reference> - <Reference Include="Microsoft.TemplateEngine.Utils"> - <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Utils.1.0.0-beta2-20170523-241\lib\net45\Microsoft.TemplateEngine.Utils.dll</HintPath> - </Reference> - <Reference Include="Microsoft.TemplateEngine.Core"> - <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Core.1.0.0-beta2-20170523-241\lib\net45\Microsoft.TemplateEngine.Core.dll</HintPath> + <Reference Include="System.Reflection.Metadata"> + <HintPath>..\..\..\packages\System.Reflection.Metadata.1.4.2\lib\netstandard1.1\System.Reflection.Metadata.dll</HintPath> </Reference> - <Reference Include="Microsoft.TemplateEngine.Orchestrator.RunnableProjects"> - <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Orchestrator.RunnableProjects.1.0.0-beta2-20170523-241\lib\net45\Microsoft.TemplateEngine.Orchestrator.RunnableProjects.dll</HintPath> + <Reference Include="System.Runtime.Remoting" /> + <Reference Include="System.Runtime.Serialization" /> + <Reference Include="System.Threading.Tasks.Dataflow, Version=4.6.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> + <HintPath>..\..\..\packages\System.Threading.Tasks.Dataflow.4.7.0\lib\netstandard1.0\System.Threading.Tasks.Dataflow.dll</HintPath> + <Private>True</Private> </Reference> - <Reference Include="Microsoft.TemplateEngine.Edge"> - <HintPath>..\..\..\packages\Microsoft.TemplateEngine.Edge.1.0.0-beta2-20170523-241\lib\net45\Microsoft.TemplateEngine.Edge.dll</HintPath> + <Reference Include="System.Web" /> + <Reference Include="System.Web.Services" /> + <Reference Include="System.Windows" Condition=" '$(Configuration)' == 'DebugWin32' Or '$(Configuration)' == 'ReleaseWin32' " /> + <Reference Include="System.Windows.Forms" /> + <Reference Include="System.Xaml" /> + <Reference Include="System.Xml" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="WindowsBase" Condition=" '$(Configuration)' == 'DebugWin32' Or '$(Configuration)' == 'ReleaseWin32' " /> + <Reference Include="WindowsFormsIntegration" Condition=" '$(Configuration)' == 'DebugWin32' Or '$(Configuration)' == 'ReleaseWin32' " /> + <Reference Include="Xamarin.Mac" Condition=" '$(Configuration)' == 'DebugMac' Or '$(Configuration)' == 'ReleaseMac' "> + <HintPath>..\..\..\external\Xamarin.Mac.dll</HintPath> </Reference> - <Reference Include="Newtonsoft.Json"> - <HintPath>..\..\..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> - <Private>False</Private> + <Reference Include="YamlDotNet"> + <HintPath>..\..\..\packages\YamlDotNet.Signed.4.0.1-pre291\lib\net35\YamlDotNet.dll</HintPath> </Reference> </ItemGroup> <ItemGroup> @@ -9437,6 +9459,7 @@ <Compile Include="MonoDevelop.Ide.Editor.Highlighting\RoslynClassificationHighlighting.cs" /> <Compile Include="MonoDevelop.Ide.Projects\LanguageCellRenderer.cs" /> <Compile Include="MonoDevelop.Components\RestartPanel.cs" /> + <Compile Include="MonoDevelop.Ide.Gui.OptionPanels\DotNetCompileTargetSelector.cs" /> </ItemGroup> <ItemGroup> <None Include="Makefile.am" /> @@ -9533,6 +9556,6 @@ </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Target Name="AfterBuild"> - <Copy SourceFiles="@(Data)" DestinationFolder="..\..\..\build\data\%(Data.RelativeDir)" /> + <Copy SourceFiles="@(Data)" DestinationFolder="..\..\..\build\data\%(Data.RelativeDir)" SkipUnchangedFiles="true" /> </Target> </Project> diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdePreferences.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdePreferences.cs index b898615c52..004851fad1 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdePreferences.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/IdePreferences.cs @@ -139,8 +139,6 @@ namespace MonoDevelop.Ide public readonly ConfigurationProperty<bool> AddImportedItemsToCompletionList = ConfigurationProperty.Create ("AddImportedItemsToCompletionList", false); public readonly ConfigurationProperty<bool> IncludeKeywordsInCompletionList = ConfigurationProperty.Create ("IncludeKeywordsInCompletionList", true); public readonly ConfigurationProperty<bool> IncludeCodeSnippetsInCompletionList = ConfigurationProperty.Create ("IncludeCodeSnippetsInCompletionList", true); - public readonly ConfigurationProperty<bool> AddParenthesesAfterCompletion = ConfigurationProperty.Create ("AddParenthesesAfterCompletion", true); - public readonly ConfigurationProperty<bool> AddOpeningOnly = ConfigurationProperty.Create ("AddOpeningOnly", false); public readonly ConfigurationProperty<bool> FilterCompletionListByEditorBrowsable = ConfigurationProperty.Create ("FilterCompletionListByEditorBrowsable", true); public readonly ConfigurationProperty<bool> IncludeEditorBrowsableAdvancedMembers = ConfigurationProperty.Create ("IncludeEditorBrowsableAdvancedMembers", true); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs index 19e3b067ca..a88c448dfc 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs @@ -1182,7 +1182,7 @@ namespace MonoDevelop.Ide BuildResult res = null; try { tt.Trace ("Cleaning item"); - res = await entry.Clean (monitor, IdeApp.Workspace.ActiveConfiguration, operationContext); + res = await entry.Clean (monitor, IdeApp.Workspace.ActiveConfiguration, InitOperationContext (entry, operationContext)); } catch (Exception ex) { monitor.ReportError (GettextCatalog.GetString ("Clean failed."), ex); } finally { @@ -1435,13 +1435,13 @@ namespace MonoDevelop.Ide var sei = target as Project; if (sei != null) { - if (sei.FastCheckNeedsBuild (configuration)) + if (sei.FastCheckNeedsBuild (configuration, InitOperationContext (target, new TargetEvaluationContext ()))) return true; //TODO: respect solution level dependencies var deps = new HashSet<SolutionItem> (); CollectReferencedItems (sei, deps, configuration); foreach (var dep in deps.OfType<Project> ()) { - if (dep.FastCheckNeedsBuild (configuration)) + if (dep.FastCheckNeedsBuild (configuration, InitOperationContext (target, new TargetEvaluationContext ()))) return true; } return false; @@ -1450,7 +1450,7 @@ namespace MonoDevelop.Ide var sln = target as Solution; if (sln != null) { foreach (var item in sln.GetAllProjects ()) { - if (item.FastCheckNeedsBuild (configuration)) + if (item.FastCheckNeedsBuild (configuration, InitOperationContext (target, new TargetEvaluationContext ()))) return true; } return false; @@ -1517,7 +1517,7 @@ namespace MonoDevelop.Ide if (skipPrebuildCheck || result.ErrorCount == 0) { tt.Trace ("Building item"); - result = await entry.Build (monitor, IdeApp.Workspace.ActiveConfiguration, true, operationContext); + result = await entry.Build (monitor, IdeApp.Workspace.ActiveConfiguration, true, InitOperationContext (entry, operationContext)); } } catch (Exception ex) { monitor.ReportError (GettextCatalog.GetString ("Build failed."), ex); @@ -1534,6 +1534,25 @@ namespace MonoDevelop.Ide return result; } + + /// <summary> + /// Initializes the context to be used for build operations. It currently just initializes + /// it with the currently selected execution target. + /// </summary> + T InitOperationContext<T> (IBuildTarget target, T context) where T:OperationContext + { + OperationContext ctx = context; + if (ctx == null) + ctx = new OperationContext (); + if (ctx.ExecutionTarget == null) { + var item = target as SolutionItem; + if (item != null) + ctx.ExecutionTarget = IdeApp.Workspace.GetActiveExecutionTarget (item); + else + ctx.ExecutionTarget = IdeApp.Workspace.ActiveExecutionTarget; + } + return (T)ctx; + } // Note: This must run in the main thread async Task PromptForSave (BuildResult result) diff --git a/main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Projects.OptionPanels.CombineBuildOptionsWidget.cs b/main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Projects.OptionPanels.CombineBuildOptionsWidget.cs index 642f591582..f0c3177361 100644 --- a/main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Projects.OptionPanels.CombineBuildOptionsWidget.cs +++ b/main/src/core/MonoDevelop.Ide/gtk-gui/MonoDevelop.Ide.Projects.OptionPanels.CombineBuildOptionsWidget.cs @@ -5,62 +5,67 @@ namespace MonoDevelop.Ide.Projects.OptionPanels internal partial class CombineBuildOptionsWidget { private global::Gtk.VBox vbox68; + private global::Gtk.Label label73; + private global::Gtk.HBox hbox46; + private global::Gtk.Label label74; + private global::MonoDevelop.Components.FolderEntry folderEntry; - protected virtual void Build () + protected virtual void Build() { - global::Stetic.Gui.Initialize (this); + global::Stetic.Gui.Initialize(this); // Widget MonoDevelop.Ide.Projects.OptionPanels.CombineBuildOptionsWidget - global::Stetic.BinContainer.Attach (this); + global::Stetic.BinContainer.Attach(this); this.Name = "MonoDevelop.Ide.Projects.OptionPanels.CombineBuildOptionsWidget"; // Container child MonoDevelop.Ide.Projects.OptionPanels.CombineBuildOptionsWidget.Gtk.Container+ContainerChild - this.vbox68 = new global::Gtk.VBox (); + this.vbox68 = new global::Gtk.VBox(); this.vbox68.Name = "vbox68"; this.vbox68.BorderWidth = ((uint)(12)); // Container child vbox68.Gtk.Box+BoxChild - this.label73 = new global::Gtk.Label (); + this.label73 = new global::Gtk.Label(); this.label73.Name = "label73"; this.label73.Xalign = 0F; - this.label73.LabelProp = global::Mono.Unix.Catalog.GetString ("<b>Output Directory</b>"); + this.label73.LabelProp = global::Mono.Unix.Catalog.GetString("<b>Output Directory</b>"); this.label73.UseMarkup = true; - this.vbox68.Add (this.label73); - global::Gtk.Box.BoxChild w1 = ((global::Gtk.Box.BoxChild)(this.vbox68 [this.label73])); + this.vbox68.Add(this.label73); + global::Gtk.Box.BoxChild w1 = ((global::Gtk.Box.BoxChild)(this.vbox68[this.label73])); w1.Position = 0; w1.Expand = false; w1.Fill = false; // Container child vbox68.Gtk.Box+BoxChild - this.hbox46 = new global::Gtk.HBox (); + this.hbox46 = new global::Gtk.HBox(); this.hbox46.Name = "hbox46"; this.hbox46.Spacing = 6; // Container child hbox46.Gtk.Box+BoxChild - this.label74 = new global::Gtk.Label (); + this.label74 = new global::Gtk.Label(); this.label74.Name = "label74"; - this.label74.LabelProp = global::Mono.Unix.Catalog.GetString (" "); - this.hbox46.Add (this.label74); - global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.hbox46 [this.label74])); + this.label74.LabelProp = global::Mono.Unix.Catalog.GetString(" "); + this.hbox46.Add(this.label74); + global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.hbox46[this.label74])); w2.Position = 0; w2.Expand = false; w2.Fill = false; // Container child hbox46.Gtk.Box+BoxChild - this.folderEntry = new global::MonoDevelop.Components.FolderEntry (); + this.folderEntry = new global::MonoDevelop.Components.FolderEntry(); this.folderEntry.Name = "folderEntry"; - this.hbox46.Add (this.folderEntry); - global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox46 [this.folderEntry])); + this.hbox46.Add(this.folderEntry); + global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.hbox46[this.folderEntry])); w3.Position = 1; - this.vbox68.Add (this.hbox46); - global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.vbox68 [this.hbox46])); + this.vbox68.Add(this.hbox46); + global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.vbox68[this.hbox46])); w4.Position = 1; w4.Expand = false; w4.Fill = false; w4.Padding = ((uint)(6)); - this.Add (this.vbox68); - if ((this.Child != null)) { - this.Child.ShowAll (); + this.Add(this.vbox68); + if ((this.Child != null)) + { + this.Child.ShowAll(); } - this.Show (); + this.Show(); } } } diff --git a/main/src/core/MonoDevelop.Ide/packages.config b/main/src/core/MonoDevelop.Ide/packages.config index d9b79ad7a5..b0adcab8d3 100644 --- a/main/src/core/MonoDevelop.Ide/packages.config +++ b/main/src/core/MonoDevelop.Ide/packages.config @@ -13,7 +13,7 @@ <package id="Microsoft.VisualStudio.Text.UI" version="15.0.26201" targetFramework="net461" /> <package id="Microsoft.VisualStudio.Validation" version="15.3.15" targetFramework="net461" /> <package id="Newtonsoft.Json" version="8.0.3" targetFramework="net45" /> - <package id="SharpZipLib" version="0.86.0" targetFramework="net45" /> + <package id="JetBrains.SharpZipLib.Stripped" version="0.87.20170615.10" targetFramework="net461" /> <package id="System.Collections.Immutable" version="1.3.1" targetFramework="net45" /> <package id="System.Composition" version="1.0.31" targetFramework="net45" /> <package id="System.IO.Compression" version="4.3.0" targetFramework="net45" /> diff --git a/main/src/core/MonoDevelop.Startup/MonoDevelop.Startup.csproj b/main/src/core/MonoDevelop.Startup/MonoDevelop.Startup.csproj index 4301c1c776..dac10de985 100644 --- a/main/src/core/MonoDevelop.Startup/MonoDevelop.Startup.csproj +++ b/main/src/core/MonoDevelop.Startup/MonoDevelop.Startup.csproj @@ -127,5 +127,5 @@ </Content> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> - <Import Project="$(MSBuildThisFileDirectory)..\..\..\packages\LargeAddressAware.1.0.0\build\LargeAddressAware.targets" Condition="$(OS) != 'Unix' AND Exists('$(MSBuildThisFileDirectory)..\..\..\packages\LargeAddressAware.1.0.0\build\LargeAddressAware.targets')" /> + <Import Project="$(MSBuildThisFileDirectory)..\..\..\packages\LargeAddressAware.1.0.1\build\LargeAddressAware.targets" Condition="$(OS) != 'Unix' AND Exists('$(MSBuildThisFileDirectory)..\..\..\packages\LargeAddressAware.1.0.1\build\LargeAddressAware.targets')" /> </Project> diff --git a/main/src/core/MonoDevelop.Startup/app.config b/main/src/core/MonoDevelop.Startup/app.config index a6193c0c18..a4ff3b3413 100644 --- a/main/src/core/MonoDevelop.Startup/app.config +++ b/main/src/core/MonoDevelop.Startup/app.config @@ -6,8 +6,8 @@ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="ICSharpCode.SharpZipLib" publicKeyToken="1b03e6acf1164f73" culture="neutral" /> - <bindingRedirect oldVersion="0.0.0.0-0.86.0.518" newVersion="0.86.0.518" /> - <bindingRedirect oldVersion="2.84.0.0-4.84.0.0" newVersion="0.86.0.518" /> + <bindingRedirect oldVersion="0.0.0.0-0.86.0.518" newVersion="1.0.6375.31400" /> + <bindingRedirect oldVersion="2.84.0.0-4.84.0.0" newVersion="1.0.6375.31400" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> diff --git a/main/src/core/MonoDevelop.Startup/packages.config b/main/src/core/MonoDevelop.Startup/packages.config index b66b85fce8..5e81482871 100644 --- a/main/src/core/MonoDevelop.Startup/packages.config +++ b/main/src/core/MonoDevelop.Startup/packages.config @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="LargeAddressAware" version="1.0.0" /> + <package id="LargeAddressAware" version="1.0.1" /> </packages>
\ No newline at end of file diff --git a/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests.DefaultEditActions/DeleteActionTests.cs b/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests.DefaultEditActions/DeleteActionTests.cs index d8fcc9ff1e..d537f0e107 100644 --- a/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests.DefaultEditActions/DeleteActionTests.cs +++ b/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests.DefaultEditActions/DeleteActionTests.cs @@ -215,5 +215,30 @@ namespace Mono.TextEditor.Tests.Actions DeleteActions.NextSubword (data); Check (data, @" $"); } + + [Test] + public void AdvancedBackspaceTests () + { + var data = Create (@"($)", mimeType: "text/x-csharp"); + MonoDevelop.SourceEditor.EditActions.AdvancedBackspace (data); + Check (data, @"$"); + data = Create (@"[$]", mimeType:"text/x-csharp"); + MonoDevelop.SourceEditor.EditActions.AdvancedBackspace (data); + Check (data, @"$"); + data = Create ("\"$\"", mimeType:"text/x-csharp"); + MonoDevelop.SourceEditor.EditActions.AdvancedBackspace (data); + Check (data, @"$"); + data = Create ("'$'", mimeType: "text/x-csharp"); + MonoDevelop.SourceEditor.EditActions.AdvancedBackspace (data); + Check (data, @"$"); + + data = Create (@"// ($)", mimeType: "text/x-csharp"); + MonoDevelop.SourceEditor.EditActions.AdvancedBackspace (data); + Check (data, @"// $)"); + + data = Create (@""" ($)", mimeType: "text/x-csharp"); + MonoDevelop.SourceEditor.EditActions.AdvancedBackspace (data); + Check (data, @""" $)"); + } } } diff --git a/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests.DefaultEditActions/TextEditorTestBase.cs b/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests.DefaultEditActions/TextEditorTestBase.cs index 6fa47fa552..6446512e13 100644 --- a/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests.DefaultEditActions/TextEditorTestBase.cs +++ b/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests.DefaultEditActions/TextEditorTestBase.cs @@ -92,11 +92,13 @@ namespace Mono.TextEditor.Tests - public static TextEditorData Create (string content, ITextEditorOptions options = null) + public static TextEditorData Create (string content, ITextEditorOptions options = null, string mimeType = null) { var data = new TextEditorData (); if (options != null) data.Options = options; + if (mimeType != null) + data.Document.MimeType = mimeType; var sb = new StringBuilder (); int caretIndex = -1, selectionStart = -1, selectionEnd = -1; var foldSegments = new List<FoldSegment> (); diff --git a/main/tests/Ide.Tests/Ide.Tests.csproj b/main/tests/Ide.Tests/Ide.Tests.csproj index e70eb864bf..d03b6db42f 100644 --- a/main/tests/Ide.Tests/Ide.Tests.csproj +++ b/main/tests/Ide.Tests/Ide.Tests.csproj @@ -39,6 +39,9 @@ <ItemGroup> <Compile Include="ProjectTemplateTests.cs" /> <Compile Include="FileTransferTests.cs" /> + <Compile Include="MonoDevelop.Ide.Projects\NewProjectDialogTests.cs" /> + <Compile Include="MonoDevelop.Ide.Projects\TestableNewProjectDialogController.cs" /> + <Compile Include="MonoDevelop.Ide.Projects\DummyNewProjectDialogBackend.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup> diff --git a/main/tests/Ide.Tests/MonoDevelop.Ide.Projects/DummyNewProjectDialogBackend.cs b/main/tests/Ide.Tests/MonoDevelop.Ide.Projects/DummyNewProjectDialogBackend.cs new file mode 100644 index 0000000000..d3f02862c3 --- /dev/null +++ b/main/tests/Ide.Tests/MonoDevelop.Ide.Projects/DummyNewProjectDialogBackend.cs @@ -0,0 +1,50 @@ +// +// DummyNewProjectDialogBackend.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; + +namespace MonoDevelop.Ide.Projects +{ + class DummyNewProjectDialogBackend : INewProjectDialogBackend + { + public bool CanMoveToNextPage { get; set; } + + public void CloseDialog () + { + } + + public void RegisterController (INewProjectDialogController controller) + { + } + + public Action OnShowDialogCalled = () => { }; + + public void ShowDialog () + { + OnShowDialogCalled (); + } + } +} diff --git a/main/tests/Ide.Tests/MonoDevelop.Ide.Projects/NewProjectDialogTests.cs b/main/tests/Ide.Tests/MonoDevelop.Ide.Projects/NewProjectDialogTests.cs new file mode 100644 index 0000000000..545e9a42a5 --- /dev/null +++ b/main/tests/Ide.Tests/MonoDevelop.Ide.Projects/NewProjectDialogTests.cs @@ -0,0 +1,166 @@ +// +// NewProjectDialogTests.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 UnitTests; +using NUnit.Framework; +using MonoDevelop.Core; +using MonoDevelop.Projects; + +namespace MonoDevelop.Ide.Projects +{ + class NewProjectDialogTests : TestBase + { + TestableNewProjectDialogController controller; + bool createProjectDirectoryOriginalValue; + + [TestFixtureSetUp] + public void SetUp () + { + Simulate (); + + createProjectDirectoryOriginalValue = PropertyService.Get ( + NewProjectDialogController.CreateProjectSubDirectoryPropertyName, + true); + } + + public override void TearDown () + { + // Reset original property values. + PropertyService.Set ( + NewProjectDialogController.CreateProjectSubDirectoryPropertyName, + createProjectDirectoryOriginalValue); + } + + void CreateDialog () + { + controller = new TestableNewProjectDialogController (); + + // Set base path to avoid use of IdeApp.Preferences which is not + // initialized during tests. + controller.BasePath = Util.TestsRootDir; + } + + void CSharpLibraryTemplateSelectedByDefault () + { + controller.SelectedTemplateId = "MonoDevelop.CSharp.Library"; + } + + void UseExistingSolution () + { + var parentFolder = new SolutionFolder (); + controller.ParentFolder = parentFolder; + } + + [Test] + public void Show_CSharpLibrary_NoItemsCreated () + { + CreateDialog (); + CSharpLibraryTemplateSelectedByDefault (); + + controller.Backend.OnShowDialogCalled = () => { + controller.MoveToNextPage (); + }; + + bool result = controller.Show (); + + Assert.IsFalse (result); + } + + [Test] + public void CreateProjectDirectorySetting_IsTrue_FinalPageHasCreateDirectoryEnabledAndChecked () + { + CreateDialog (); + CSharpLibraryTemplateSelectedByDefault (); + PropertyService.Set (NewProjectDialogController.CreateProjectSubDirectoryPropertyName, true); + + controller.Backend.OnShowDialogCalled = () => { + controller.MoveToNextPage (); + }; + + controller.Show (); + + Assert.IsTrue (controller.FinalConfiguration.CreateProjectDirectoryInsideSolutionDirectory); + Assert.IsTrue (controller.FinalConfiguration.IsCreateProjectDirectoryInsideSolutionDirectoryEnabled); + } + + [Test] + public void CreateProjectDirectorySetting_IsFalse_FinalPageHasCreateDirectoryEnabledAndNotChecked () + { + CreateDialog (); + CSharpLibraryTemplateSelectedByDefault (); + PropertyService.Set (NewProjectDialogController.CreateProjectSubDirectoryPropertyName, false); + + controller.Backend.OnShowDialogCalled = () => { + controller.MoveToNextPage (); + }; + + controller.Show (); + + Assert.IsFalse (controller.FinalConfiguration.CreateProjectDirectoryInsideSolutionDirectory); + Assert.IsTrue (controller.FinalConfiguration.IsCreateProjectDirectoryInsideSolutionDirectoryEnabled); + } + + [Test] + public void CreateProjectDirectorySetting_IsTrueAndAddingProjectToExistingSolution_FinalPageHasCreateDirectoryDisabledAndChecked () + { + CreateDialog (); + CSharpLibraryTemplateSelectedByDefault (); + UseExistingSolution (); + PropertyService.Set (NewProjectDialogController.CreateProjectSubDirectoryPropertyName, true); + + controller.Backend.OnShowDialogCalled = () => { + controller.MoveToNextPage (); + }; + + controller.Show (); + + Assert.IsTrue (controller.FinalConfiguration.CreateProjectDirectoryInsideSolutionDirectory); + Assert.IsFalse (controller.FinalConfiguration.IsCreateProjectDirectoryInsideSolutionDirectoryEnabled); + } + + /// <summary> + /// Ensure a project directory is always created when adding a project to an existing solution even + /// if previously the create project directory setting was disabled. + /// </summary> + [Test] + public void CreateProjectDirectorySetting_IsFalseAndAddingProjectToExistingSolution_FinalPageHasCreateDirectoryDisabledAndChecked () + { + CreateDialog (); + CSharpLibraryTemplateSelectedByDefault (); + UseExistingSolution (); + PropertyService.Set (NewProjectDialogController.CreateProjectSubDirectoryPropertyName, false); + + controller.Backend.OnShowDialogCalled = () => { + controller.MoveToNextPage (); + }; + + controller.Show (); + + Assert.IsTrue (controller.FinalConfiguration.CreateProjectDirectoryInsideSolutionDirectory); + Assert.IsFalse (controller.FinalConfiguration.IsCreateProjectDirectoryInsideSolutionDirectoryEnabled); + } + } +} diff --git a/main/tests/Ide.Tests/MonoDevelop.Ide.Projects/TestableNewProjectDialogController.cs b/main/tests/Ide.Tests/MonoDevelop.Ide.Projects/TestableNewProjectDialogController.cs new file mode 100644 index 0000000000..40f11dc613 --- /dev/null +++ b/main/tests/Ide.Tests/MonoDevelop.Ide.Projects/TestableNewProjectDialogController.cs @@ -0,0 +1,47 @@ +// +// TestableNewProjectDialogController.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.Projects; +using MonoDevelop.Ide.Templates; + +namespace MonoDevelop.Ide +{ + class TestableNewProjectDialogController : NewProjectDialogController + { + public TestableNewProjectDialogController () + { + Backend = new DummyNewProjectDialogBackend (); + TemplatingService = new TemplatingService (); + } + + public DummyNewProjectDialogBackend Backend { get; private set; } + + protected override INewProjectDialogBackend CreateNewProjectDialog () + { + return Backend; + } + } +} diff --git a/main/tests/Ide.Tests/ProjectTemplateTests.cs b/main/tests/Ide.Tests/ProjectTemplateTests.cs index 890cb68fb7..a1dd4649a2 100644 --- a/main/tests/Ide.Tests/ProjectTemplateTests.cs +++ b/main/tests/Ide.Tests/ProjectTemplateTests.cs @@ -31,6 +31,11 @@ using NUnit.Framework; using UnitTests; using System.Linq; using System.Threading.Tasks; +using MonoDevelop.Ide.Gui.Content; +using MonoDevelop.Core; +using MonoDevelop.Ide.CodeFormatting; +using MonoDevelop.Core.Text; +using System; namespace MonoDevelop.Ide { @@ -92,6 +97,78 @@ namespace MonoDevelop.Ide var myclassFile = sharedAssetsProject.Files.First (f => f.FilePath.FileName == "MyClass.cs"); Assert.AreEqual ("Compile", myclassFile.BuildAction); } + + async Task FormatFile (Project p, FilePath file) + { + string mime = DesktopService.GetMimeTypeForUri (file); + if (mime == null) + return; + + var formatter = CodeFormatterService.GetFormatter (mime); + if (formatter != null) { + try { + var content = await TextFileUtility.ReadAllTextAsync (file); + var formatted = formatter.FormatText (p.Policies, content.Text); + if (formatted != null) + TextFileUtility.WriteText (file, formatted, content.Encoding); + } catch (Exception ex) { + LoggingService.LogError ("File formatting failed", ex); + } + } + } + + [Test ()] + public async Task Bug57840 () + { + var templatingService = new TemplatingService (); + var mutliplatformLibraryCategory = templatingService.GetProjectTemplateCategories ().Single (c => c.Id == "multiplat") + .Categories.Single (c => c.Id == "library") + .Categories.Single (c => c.Id == "general"); + var pclTemplate = mutliplatformLibraryCategory.Templates.Single (t => t.GroupId == "md-project-portable-library").GetTemplate ("C#"); + var standardTemplate = mutliplatformLibraryCategory.Templates.Single (t => t.GroupId == "Microsoft.Common.Library").GetTemplate ("C#"); + + var tempDirectory = Util.CreateTmpDir ("Bug57840Test"); + var result = await templatingService.ProcessTemplate (pclTemplate, new Ide.Projects.NewProjectConfiguration () { + CreateSolution = true, + Location = tempDirectory, + SolutionName = "Bug57840Test", + ProjectName = "Bug57840PclTestProject", + CreateProjectDirectoryInsideSolutionDirectory = false + }, null); + + var solution = result.WorkspaceItems.OfType<Solution> ().Single (); + + await solution.SaveAsync (Util.GetMonitor ()); + var project = solution.GetAllProjects ().Single (); + project.Policies.Set<TextStylePolicy> (new TextStylePolicy (1, 1, 1, true, true, true, EolMarker.Mac), "text/x-csharp"); + + var file = project.Files.Single (f => f.FilePath.FileName == "MyClass.cs").FilePath; + var fileContentBeforeFormat = await TextFileUtility.ReadAllTextAsync (file); + await FormatFile (project, file); + var fileContentAfterFormat = await TextFileUtility.ReadAllTextAsync (file); + + Assert.AreNotEqual (fileContentBeforeFormat.Text, fileContentAfterFormat.Text);//Make sure our weird formatting applied + + solution.Policies.Set<TextStylePolicy> (new TextStylePolicy (3, 3, 3, true, true, true, EolMarker.Mac), "text/x-csharp"); + + var result2 = await templatingService.ProcessTemplate (standardTemplate, new Ide.Projects.NewProjectConfiguration () { + CreateSolution = false, + Location = solution.BaseDirectory, + ProjectName = "Bug57840StandardTestProject", + CreateProjectDirectoryInsideSolutionDirectory = false + }, solution.RootFolder); + await solution.SaveAsync (Util.GetMonitor ()); + var fileContentAfterSecondProject = await TextFileUtility.ReadAllTextAsync (file); + Assert.AreEqual (fileContentAfterSecondProject.Text, fileContentAfterFormat.Text);//Make sure our weird formatting is preserved + var standardProject = result2.WorkspaceItems.OfType<DotNetProject> ().Single (); + var class1File = standardProject.Files.Single (f => f.FilePath.FileName == "Class1.cs").FilePath; + var fileContentAfterCreation = await TextFileUtility.ReadAllTextAsync (class1File); + standardProject.Policies.Set<TextStylePolicy> (new TextStylePolicy (3, 3, 3, true, true, true, EolMarker.Mac), "text/x-csharp"); + await FormatFile (standardProject, class1File); + var fileContentAfterForceFormatting = await TextFileUtility.ReadAllTextAsync (class1File); + Assert.AreEqual (fileContentAfterForceFormatting.Text, fileContentAfterCreation.Text, + "We expect them to be same because we placed same formatting policy on solution before creataion as after creation on project when we manually formatted."); + } } } diff --git a/main/tests/MacPlatform.Tests/CoreFoundationTests.cs b/main/tests/MacPlatform.Tests/CoreFoundationTests.cs index b69f2b1b39..45c8ab523e 100644 --- a/main/tests/MacPlatform.Tests/CoreFoundationTests.cs +++ b/main/tests/MacPlatform.Tests/CoreFoundationTests.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.IO; using MonoDevelop.MacInterop; using NUnit.Framework; @@ -53,22 +54,63 @@ namespace MacPlatform.Tests MonoDevelop.MacInterop.CoreFoundation.Release (testUrl); } + static string plistFile = Path.GetFullPath ( + Path.Combine ( + Path.GetDirectoryName (typeof (PListFile).Assembly.Location), + "..", + "MacOSX", + "Info.plist.in" + ) + ); + [Test] - public static void TestApplicationUrls () + public void TestApplicationUrls () { - string test = "/Applications/Xamarin Studio.app/Contents/Info.plist"; - string[] results = MonoDevelop.MacInterop.CoreFoundation.GetApplicationUrls (test, MonoDevelop.MacInterop.CoreFoundation.LSRolesMask.All); + using (var helper = new PListFile ()) { + string [] results = MonoDevelop.MacInterop.CoreFoundation.GetApplicationUrls (helper.FilePath, MonoDevelop.MacInterop.CoreFoundation.LSRolesMask.All); - Assert.Greater (results.Length, 0); + Assert.Greater (results.Length, 0); + } } [Test] - public static void TestApplicationUrl () + public void TestApplicationUrl () { - string test = "/Applications/Xamarin Studio.app/Contents/Info.plist"; - string result = MonoDevelop.MacInterop.CoreFoundation.GetApplicationUrl (test, MonoDevelop.MacInterop.CoreFoundation.LSRolesMask.All); + using (var helper = new PListFile ()) { + string result = MonoDevelop.MacInterop.CoreFoundation.GetApplicationUrl (helper.FilePath, MonoDevelop.MacInterop.CoreFoundation.LSRolesMask.All); + + Assert.NotNull (result); + } + } + + [Test] + public void TestApplicationUrlOnPListIn () + { + string [] results = MonoDevelop.MacInterop.CoreFoundation.GetApplicationUrls (plistFile, MonoDevelop.MacInterop.CoreFoundation.LSRolesMask.All); + + Assert.AreEqual (results.Length, 0); + + string result = MonoDevelop.MacInterop.CoreFoundation.GetApplicationUrl (plistFile, MonoDevelop.MacInterop.CoreFoundation.LSRolesMask.All); + + Assert.Null (result); + } + + class PListFile : IDisposable + { + readonly string dir = MonoDevelop.Core.FileService.CreateTempDirectory (); + public string FilePath { get; } + + public PListFile () + { + FilePath = Path.Combine (dir, "Info.plist"); + File.Copy (plistFile, FilePath, true); + } - Assert.NotNull (result); + public void Dispose () + { + if (Directory.Exists (dir)) + Directory.Delete (dir, true); + } } } } diff --git a/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/PortedRoslynTests/SymbolCompletionHandlerTests.cs b/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/PortedRoslynTests/SymbolCompletionHandlerTests.cs index 75b927450e..5b7b2c2eab 100644 --- a/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/PortedRoslynTests/SymbolCompletionHandlerTests.cs +++ b/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/PortedRoslynTests/SymbolCompletionHandlerTests.cs @@ -2127,6 +2127,21 @@ namespace Test VerifyItemIsAbsent (markup, "@namespace"); } + [Test] + public void AttributeNameWithoutAttributeSuffix () + { + var markup = @" +namespace Test +{ + class Foo : System.Attribute { } + + [F$$ + class Program { } +} +"; + + VerifyItemExists (markup, "Foo"); + } [Test] diff --git a/main/tests/UnitTests/MonoDevelop.CSharpBinding.Refactoring/CSharpFindReferencesProviderTests.cs b/main/tests/UnitTests/MonoDevelop.CSharpBinding.Refactoring/CSharpFindReferencesProviderTests.cs new file mode 100644 index 0000000000..4a274f842e --- /dev/null +++ b/main/tests/UnitTests/MonoDevelop.CSharpBinding.Refactoring/CSharpFindReferencesProviderTests.cs @@ -0,0 +1,125 @@ +// +// CSharpFindReferencesProviderTests.cs +// +// Author: +// Mike Krüger <mikkrg@microsoft.com> +// +// Copyright (c) 2017 Microsoft Corporation +// +// 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. +#pragma warning disable RECS0165 // Asynchronous methods should return a Task instead of void + +using System;
+using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using MonoDevelop.Core; +using MonoDevelop.CSharp.Formatting; +using MonoDevelop.CSharpBinding; +using MonoDevelop.CSharpBinding.Tests; +using MonoDevelop.Ide.Editor; +using MonoDevelop.Ide.FindInFiles; +using MonoDevelop.Ide.TypeSystem; +using MonoDevelop.Projects; +using MonoDevelop.Projects.Policies; +using NUnit.Framework; + +namespace MonoDevelop.CSharp.Refactoring +{ + [TestFixture] + class CSharpFindReferencesProviderTests : global::UnitTests.TestBase + { + + static async Task<List<SearchResult>> GatherReferences (string input, Func<MonoDevelop.Projects.Project, Task<IEnumerable<SearchResult>>> findRefsCallback) + { + TestWorkbenchWindow tww = new TestWorkbenchWindow (); + TestViewContent content = new TestViewContent (); + tww.ViewContent = content; + content.ContentName = "/a.cs"; + content.Data.MimeType = "text/x-csharp"; + + var doc = new MonoDevelop.Ide.Gui.Document (tww); + + var text = input; + content.Text = text; + + var project = Services.ProjectService.CreateProject ("C#"); + project.Name = "test"; + project.FileName = "test.csproj"; + project.Files.Add (new ProjectFile (content.ContentName, BuildAction.Compile)); + project.Policies.Set (PolicyService.InvariantPolicies.Get<CSharpFormattingPolicy> (), CSharpFormatter.MimeType); + var solution = new MonoDevelop.Projects.Solution (); + solution.AddConfiguration ("", true); + solution.DefaultSolutionFolder.AddItem (project); + using (var monitor = new ProgressMonitor ()) + await TypeSystemService.Load (solution, monitor); + content.Project = project; + doc.SetProject (project); + + await doc.UpdateParseDocument (); + try { + return (await findRefsCallback (project)).ToList (); + } finally { + TypeSystemService.Unload (solution); + } + } + + [Test] + public async Task TestFindReferences () + { + var refs = await GatherReferences (@"class FooBar {}", project => { + var provider = new CSharpFindReferencesProvider (); + return provider.FindReferences ("T:FooBar", project, default (CancellationToken)); + }); + Assert.AreEqual (1, refs.Count); + } + + [Test] + public async Task TestFindAllReferences () + { + var refs = await GatherReferences (@"class FooBar { +public void Foo() {} +public void Foo(int i) {} +public void Foo(string s) {} +public void Foo(int i, int j) {} + }", project => { + var provider = new CSharpFindReferencesProvider (); + return provider.FindAllReferences ("M:FooBar.Foo", project, default (CancellationToken)); + }); + Assert.AreEqual (4, refs.Count); + } + + /// <summary> + /// Bug 58060 - [VSFeedback Ticket] #454760 - "Find References" fails leaving an error in the log + /// </summary> + [Test] + public async Task TestBug58060 () + { + var refs = await GatherReferences (@"class FooBar { FooBar fb; }", project => { + var provider = new CSharpFindReferencesProvider (); + return provider.FindAllReferences ("T:FooBar", project, default (CancellationToken)); + }); + Assert.AreEqual (2, refs.Count); + } + + } +} diff --git a/main/tests/UnitTests/MonoDevelop.CSharpBinding/AutomaticBracketInsertionTests.cs b/main/tests/UnitTests/MonoDevelop.CSharpBinding/AutomaticBracketInsertionTests.cs index b9075af3d0..8d87148061 100644 --- a/main/tests/UnitTests/MonoDevelop.CSharpBinding/AutomaticBracketInsertionTests.cs +++ b/main/tests/UnitTests/MonoDevelop.CSharpBinding/AutomaticBracketInsertionTests.cs @@ -207,8 +207,7 @@ namespace MonoDevelop.CSharpBinding listWindow.CompletionWidget = widget; listWindow.CodeCompletionContext = widget.CurrentCodeCompletionContext; var model = ext.DocumentContext.ParsedDocument.GetAst<SemanticModel> (); - Ide.IdeApp.Preferences.AddParenthesesAfterCompletion.Set (true); - Ide.IdeApp.Preferences.AddOpeningOnly.Set (false); + DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket = true; var t = model.Compilation.GetTypeByMetadataName (type); diff --git a/main/tests/UnitTests/MonoDevelop.CSharpBinding/NamedArgumentCompletionTests.cs b/main/tests/UnitTests/MonoDevelop.CSharpBinding/NamedArgumentCompletionTests.cs index 0b9dcaeab8..25f13c449c 100644 --- a/main/tests/UnitTests/MonoDevelop.CSharpBinding/NamedArgumentCompletionTests.cs +++ b/main/tests/UnitTests/MonoDevelop.CSharpBinding/NamedArgumentCompletionTests.cs @@ -218,11 +218,10 @@ namespace MonoDevelop.CSharpBinding return widget.CompletedWord; } - [Test] public async Task TestSimpleCase () { - IdeApp.Preferences.AddParenthesesAfterCompletion.Set (true); + DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket = true; string completion = await Test (@"class MyClass { int foo; @@ -238,7 +237,7 @@ namespace MonoDevelop.CSharpBinding [Test] public async Task TestNoAutoCase () { - IdeApp.Preferences.AddParenthesesAfterCompletion.Set (false); + DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket = false; string completion = await Test (@"class MyClass { int foo; diff --git a/main/tests/UnitTests/MonoDevelop.Ide/KeyBindingSetTests.cs b/main/tests/UnitTests/MonoDevelop.Ide/KeyBindingSetTests.cs new file mode 100644 index 0000000000..36cbdf5cb1 --- /dev/null +++ b/main/tests/UnitTests/MonoDevelop.Ide/KeyBindingSetTests.cs @@ -0,0 +1,296 @@ +// +// KeyBindingSetTests.cs +// +// Author: +// Vsevolod Kukol <sevoku@microsoft.com> +// +// Copyright (c) 2017 (c) Microsoft Corporation +// +// 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.IO; +using System.Text; +using System.Xml; +using MonoDevelop.Components.Commands; +using NUnit.Framework; + +namespace MonoDevelop.Ide +{ + [TestFixture] + public class KeyBindingSetTests + { + [Test] + public void TestKeyBindingSetLoadXml () + { + var xml = "<schemes version=\"1.0\">" + + "<scheme name=\"Scheme1\">" + + " <binding command=\"Command1\" shortcut=\"Ctrl+1\" />" + + " <binding command=\"Command2\" shortcut=\"Ctrl+2 Alt+2\" />" + + "</scheme>" + + "</schemes>"; + + var set1 = new KeyBindingSet (); + + using (var str = new StringReader (xml)) + using (var reader = new XmlTextReader (str)) + Assert.True (set1.LoadScheme (reader, "Scheme1")); + + var cmd1 = set1.GetBindings (new ActionCommand ("Command1", "Test Command 1")); + Assert.AreEqual (1, cmd1.Length); + Assert.AreEqual ("Ctrl+1", cmd1 [0]); + + var cmd2 = set1.GetBindings (new ActionCommand ("Command2", "Test Command 2")); + Assert.AreEqual (2, cmd2.Length); + Assert.AreEqual ("Ctrl+2", cmd2 [0]); + Assert.AreEqual ("Alt+2", cmd2 [1]); + } + + [Test] + public void TestKeyBindingSetLoadXmlWithParent () + { + var xml = "<schemes version=\"1.0\">" + + "<scheme name=\"Scheme1\">" + + " <binding command=\"Command1\" shortcut=\"Alt+1\" />" + + " <binding command=\"Command2\" shortcut=\"\" />" + + "</scheme>" + + "</schemes>"; + + var cmd1 = new ActionCommand ("Command1", "Test Command 1"); + var cmd2 = new ActionCommand ("Command2", "Test Command 2"); + var cmd3 = new ActionCommand ("Command3", "Test Command 2"); + var parent = new KeyBindingSet (); + parent.SetBinding (cmd1, "Ctrl+1"); + parent.SetBinding (cmd2, "Ctrl+2"); + parent.SetBinding (cmd3, "Ctrl+3"); + + var set1 = new KeyBindingSet (parent); + Assert.AreEqual (new string [] { "Ctrl+1" }, set1.GetBindings (cmd1)); + Assert.AreEqual (new string [] { "Ctrl+2" }, set1.GetBindings (cmd2)); + + using (var str = new StringReader (xml)) + using (var reader = new XmlTextReader (str)) + Assert.True (set1.LoadScheme (reader, "Scheme1")); + + // verify that the set overrides its parent + Assert.AreEqual (new string [] { "Alt+1" }, set1.GetBindings (cmd1)); + Assert.AreEqual (new string [0], set1.GetBindings (cmd2)); + + // cmd3 should be still there + Assert.AreEqual (new string [] { "Ctrl+3" }, set1.GetBindings (cmd3)); + } + + [Test] + public void TestKeyBindingSetSaveXml () + { + var cmd1 = new ActionCommand ("Command1", "Test Command 1"); + var cmd2 = new ActionCommand ("Command2", "Test Command 2"); + var cmd3 = new ActionCommand ("Command3", "Test Command 3"); + var set1 = new KeyBindingSet (); + set1.SetBinding (cmd1, "Ctrl+1"); + set1.SetBinding (cmd2, "Ctrl+2"); + set1.SetBinding (cmd3, "Ctrl+3"); + + var sb = new StringBuilder (); + using (var str = new StringWriter(sb)) + using (var writer = new XmlTextWriter (str) { Indentation = 0, Formatting = Formatting.None}) + set1.Save (writer, "Scheme1"); + + var xml = sb.ToString (); + + var expectedXml = + "<scheme name=\"Scheme1\">" + + "<binding command=\"Command1\" shortcut=\"Ctrl+1\" />" + + "<binding command=\"Command2\" shortcut=\"Ctrl+2\" />" + + "<binding command=\"Command3\" shortcut=\"Ctrl+3\" />" + + "</scheme>"; + + Assert.AreEqual (expectedXml, xml); + + // verify that empty bindings are not stored + set1.SetBinding (cmd3, string.Empty); + + sb.Clear (); + using (var str = new StringWriter (sb)) + using (var writer = new XmlTextWriter (str) { Indentation = 0, Formatting = Formatting.None }) + set1.Save (writer, "Scheme1"); + + xml = sb.ToString (); + expectedXml = + "<scheme name=\"Scheme1\">" + + "<binding command=\"Command1\" shortcut=\"Ctrl+1\" />" + + "<binding command=\"Command2\" shortcut=\"Ctrl+2\" />" + + "</scheme>"; + + Assert.AreEqual (expectedXml, xml); + } + + [Test] + public void TestKeyBindingSetSaveXmlWithParent () + { + var cmd1 = new ActionCommand ("Command1", "Test Command 1"); + var cmd2 = new ActionCommand ("Command2", "Test Command 2"); + var cmd3 = new ActionCommand ("Command3", "Test Command 3"); + var parent = new KeyBindingSet (); + parent.SetBinding (cmd1, "Ctrl+1"); + parent.SetBinding (cmd2, "Ctrl+2"); + var set1 = new KeyBindingSet (parent); + set1.SetBinding (cmd3, "Ctrl+3"); + + var sb = new StringBuilder (); + using (var str = new StringWriter (sb)) + using (var writer = new XmlTextWriter (str) { Indentation = 0, Formatting = Formatting.None }) + set1.Save (writer, "Scheme1"); + + var xml = sb.ToString (); + + // parent bindings should be ignored + var expectedXml = + "<scheme name=\"Scheme1\">" + + "<binding command=\"Command3\" shortcut=\"Ctrl+3\" />" + + "</scheme>"; + + Assert.AreEqual (expectedXml, xml); + + // verify that parent overrides are stored, especially empty ones to disable bindings + set1.SetBinding (cmd1, "Alt+1"); + set1.SetBinding (cmd2, string.Empty); + + sb.Clear (); + using (var str = new StringWriter (sb)) + using (var writer = new XmlTextWriter (str) { Indentation = 0, Formatting = Formatting.None }) + set1.Save (writer, "Scheme1"); + + xml = sb.ToString (); + expectedXml = + "<scheme name=\"Scheme1\">" + + "<binding command=\"Command3\" shortcut=\"Ctrl+3\" />" + + "<binding command=\"Command1\" shortcut=\"Alt+1\" />" + + "<binding command=\"Command2\" shortcut=\"\" />" + + "</scheme>"; + + Assert.AreEqual (expectedXml, xml); + } + + [Test] + public void TestKeyBindingSetWithParent () + { + var cmd1 = new ActionCommand ("Command1", "Test Command 1"); + var cmd2 = new ActionCommand ("Command2", "Test Command 2"); + var cmd3 = new ActionCommand ("Command3", "Test Command 3"); + + var set1 = new KeyBindingSet (); + set1.SetBinding (cmd1, "Ctrl+1"); + set1.SetBinding (cmd2, "Ctrl+2"); + + var set2 = new KeyBindingSet (set1); + set2.SetBinding (cmd2, "Alt+2"); + set2.SetBinding (cmd3, "Ctrl+3"); + + // verify that set1 has only cmd1 and cmd2 bindings + Assert.AreEqual (new string [] { "Ctrl+1" }, set1.GetBindings (cmd1)); + Assert.AreEqual (new string [] { "Ctrl+2" }, set1.GetBindings (cmd2)); + Assert.AreEqual (new string [0], set1.GetBindings (cmd3)); + + // verify that set2 has cmd1 binding from set1 + Assert.AreEqual (set1.GetBindings (cmd1), set2.GetBindings (cmd1)); + + // verify that set 2 overrides cmd2 + Assert.AreNotEqual (set1.GetBindings (cmd2), set2.GetBindings (cmd2)); + Assert.AreEqual (new string [] { "Alt+2" }, set2.GetBindings (cmd2)); + + // verify that set2 has cmd3 binding + Assert.AreEqual (new string [] { "Ctrl+3" }, set2.GetBindings (cmd3)); + } + + [Test] + public void TestKeyBindingSetEquals1 () + { + var cmd1 = new ActionCommand ("Command1", "Test Command 1"); + var cmd2 = new ActionCommand ("Command2", "Test Command 2"); + var cmd3 = new ActionCommand ("Command3", "Test Command 3"); + + var set1 = new KeyBindingSet (); + set1.SetBinding (cmd1, "Ctrl+1"); + set1.SetBinding (cmd2, "Ctrl+2"); + + var set2 = new KeyBindingSet (); + set2.SetBinding (cmd1, "Ctrl+1"); + set2.SetBinding (cmd2, "Ctrl+2"); + + Assert.IsTrue (set1.Equals (set2)); + Assert.IsTrue (set2.Equals (set1)); + + set2.SetBinding (cmd3, "Ctrl+3"); + + Assert.IsFalse (set2.Equals (set1)); + //UNDONE: a set equals an other set if its a subset, this may/shold change in the future + Assert.IsTrue (set1.Equals (set2)); + } + + [Test] + public void TestKeyBindingSetEquals2 () + { + var cmd1 = new ActionCommand ("Command1", "Test Command 1"); + var cmd2 = new ActionCommand ("Command2", "Test Command 2"); + + var set1 = new KeyBindingSet (); + set1.SetBinding (cmd1, "Ctrl+1"); + + var set2 = new KeyBindingSet (); + set2.SetBinding (cmd1, "Ctrl+1"); + + // add an empty binding to set2 which shouldn't change equality (bug #57111) + set2.SetBinding (cmd2, string.Empty); + + Assert.IsFalse (set2.Equals (set1)); + //UNDONE: a set equals an other set if its a subset, this may/shold change in the future + Assert.IsTrue (set1.Equals (set2)); + } + + [Test] + public void TestKeyBindingSetEqualsParent () + { + var cmd1 = new ActionCommand ("Command1", "Test Command 1"); + var cmd2 = new ActionCommand ("Command2", "Test Command 2"); + var cmd3 = new ActionCommand ("Command3", "Test Command 3"); + var parent = new KeyBindingSet (); + parent.SetBinding (cmd1, "Ctrl+1"); + + var set2 = new KeyBindingSet (parent); + var set3 = new KeyBindingSet (parent); + + //UNDONE: this is not a full IEquatable<KeyBindingSet> implementation + // an empty set must be equal to its parent + Assert.IsTrue (set2.Equals (parent)); + + set2.SetBinding (cmd2, "Ctrl+2"); + set3.SetBinding (cmd2, "Ctrl+2"); + + // sets sharing the same parent and declaring same bindings are equal + Assert.IsTrue (set3.Equals (set2)); + Assert.IsTrue (set2.Equals (set3)); + + // set defines an additional binding, hence not equal to its parent + Assert.IsFalse (set3.Equals (parent)); + + // sets with different binding and same parent are not equal + set3.SetBinding (cmd2, "Alt+2"); + Assert.IsFalse (set3.Equals (set2)); + } + } +} diff --git a/main/tests/UnitTests/MonoDevelop.Projects/MSBuildProjectTests.cs b/main/tests/UnitTests/MonoDevelop.Projects/MSBuildProjectTests.cs index 72e294f7f3..05f2fd3f37 100644 --- a/main/tests/UnitTests/MonoDevelop.Projects/MSBuildProjectTests.cs +++ b/main/tests/UnitTests/MonoDevelop.Projects/MSBuildProjectTests.cs @@ -32,6 +32,7 @@ using System.IO; using System.Linq; using System.Xml; using ValueSet = MonoDevelop.Projects.ConditionedPropertyCollection.ValueSet; +using System.Collections.Generic; namespace MonoDevelop.Projects { @@ -1460,6 +1461,59 @@ namespace MonoDevelop.Projects Assert.AreEqual (expectedXml, xml); p.Dispose (); } + + [Test] + public void GlobalPropertyProvider () + { + var prov = new CustomGlobalPropertyProvider ("Works!"); + MSBuildProjectService.RegisterGlobalPropertyProvider (prov); + try { + var p = LoadProject (); + p.Evaluate (); + + var pg = p.EvaluatedProperties; + Assert.AreEqual ("Works!", pg.GetValue ("TEST_GLOBAL")); + + } finally { + MSBuildProjectService.UnregisterGlobalPropertyProvider (prov); + } + } + + [Test] + public void MultipleGlobalPropertyProvider () + { + var prov1 = new CustomGlobalPropertyProvider ("First"); + var prov2 = new CustomGlobalPropertyProvider ("Second"); + MSBuildProjectService.RegisterGlobalPropertyProvider (prov1); + MSBuildProjectService.RegisterGlobalPropertyProvider (prov2); + try { + var p = LoadProject (); + p.Evaluate (); + + var pg = p.EvaluatedProperties; + Assert.AreEqual ("Second", pg.GetValue ("TEST_GLOBAL")); + + } finally { + MSBuildProjectService.UnregisterGlobalPropertyProvider (prov1); + MSBuildProjectService.UnregisterGlobalPropertyProvider (prov2); + } + } + } + + class CustomGlobalPropertyProvider : IMSBuildGlobalPropertyProvider + { + public event EventHandler GlobalPropertiesChanged; + + string result; + + public CustomGlobalPropertyProvider (string result) => this.result = result; + + public IDictionary<string, string> GetGlobalProperties () + { + var props = new Dictionary<string, string> (); + props ["TEST_GLOBAL"] = result; + return props; + } } } diff --git a/main/tests/UnitTests/MonoDevelop.Projects/ProjectTests.cs b/main/tests/UnitTests/MonoDevelop.Projects/ProjectTests.cs index 1eee00dde6..9862542c99 100644 --- a/main/tests/UnitTests/MonoDevelop.Projects/ProjectTests.cs +++ b/main/tests/UnitTests/MonoDevelop.Projects/ProjectTests.cs @@ -1154,6 +1154,69 @@ namespace MonoDevelop.Projects var asms = await p.GetReferencedAssemblies (p.Configurations [0].Selector); Assert.IsTrue (asms.Any (r => r.FilePath.FileName == "System.Runtime.dll")); } + + [Test] + public async Task FastCheckNeedsBuildWithContext () + { + string solFile = Util.GetSampleProject ("fast-build-test", "FastBuildTest.sln"); + Solution sol = (Solution)await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solFile); + var app = (DotNetProject)sol.Items [0]; + + var cs = new SolutionConfigurationSelector ("Debug"); + + var ctx = new TargetEvaluationContext (); + ctx.GlobalProperties.SetValue ("Foo", "Bar"); + + Assert.IsTrue (app.FastCheckNeedsBuild (cs, ctx)); + + ctx = new TargetEvaluationContext (); + ctx.GlobalProperties.SetValue ("Foo", "Bar"); + + var res = await sol.Build (Util.GetMonitor (), cs, ctx); + Assert.IsFalse (res.HasErrors); + + ctx = new TargetEvaluationContext (); + ctx.GlobalProperties.SetValue ("Foo", "Bar"); + Assert.IsFalse (app.FastCheckNeedsBuild (cs, ctx)); + + ctx = new TargetEvaluationContext (); + ctx.GlobalProperties.SetValue ("Foo", "Modified"); + Assert.IsTrue (app.FastCheckNeedsBuild (cs, ctx)); + + sol.Dispose (); + } + + [Test] + public async Task OnConfigureTargetEvaluationContext () + { + var node = new CustomItemNode<EvalContextCreationTestExtension> (); + WorkspaceObject.RegisterCustomExtension (node); + + try { + string solFile = Util.GetSampleProject ("fast-build-test", "FastBuildTest.sln"); + Solution sol = (Solution)await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solFile); + var app = (DotNetProject)sol.Items [0]; + + var cs = new SolutionConfigurationSelector ("Debug"); + + Assert.IsTrue (app.FastCheckNeedsBuild (cs)); + + var res = await sol.Build (Util.GetMonitor (), cs); + Assert.IsFalse (res.HasErrors); + Assert.IsFalse (app.FastCheckNeedsBuild (cs)); + + EvalContextCreationTestExtension.ControlValue = "Changed"; + Assert.IsTrue (app.FastCheckNeedsBuild (cs)); + + res = await sol.Build (Util.GetMonitor (), cs); + Assert.IsFalse (res.HasErrors); + Assert.IsFalse (app.FastCheckNeedsBuild (cs)); + + sol.Dispose (); + } finally { + WorkspaceObject.UnregisterCustomExtension (node); + } + } } class SerializedSaveTestExtension: SolutionItemExtension @@ -1172,4 +1235,16 @@ namespace MonoDevelop.Projects await base.OnSave (monitor); } } + + class EvalContextCreationTestExtension : ProjectExtension + { + public static string ControlValue = "First"; + + internal protected override TargetEvaluationContext OnConfigureTargetEvaluationContext (string target, ConfigurationSelector configuration, TargetEvaluationContext context) + { + var c = base.OnConfigureTargetEvaluationContext (target, configuration, context); + context.GlobalProperties.SetValue ("Foo", ControlValue); + return c; + } + } } diff --git a/main/tests/UnitTests/UnitTests.csproj b/main/tests/UnitTests/UnitTests.csproj index cb0430029c..fced567dbc 100644 --- a/main/tests/UnitTests/UnitTests.csproj +++ b/main/tests/UnitTests/UnitTests.csproj @@ -302,11 +302,13 @@ <Compile Include="MonoDevelop.Projects\MSBuildLoggerTests.cs" /> <Compile Include="MonoDevelop.Core\MonoExecutionParametersTests.cs" /> <Compile Include="MonoDevelop.Components.PropertyGrid\EditorManagerTests.cs" /> + <Compile Include="MonoDevelop.Ide\KeyBindingSetTests.cs" /> <Compile Include="MonoDevelop.Ide\TypeSystemServiceTests.cs" /> <Compile Include="MonoDevelop.Projects\MSBuildSearchPathTests.cs" /> <Compile Include="MonoDevelop.Projects\SdkVersionTests.cs" /> <Compile Include="MonoDevelop.Core.Assemblies\SystemAssemblyServiceTests.cs" /> <Compile Include="MonoDevelop.Core\StringParserServiceTests.cs" /> + <Compile Include="MonoDevelop.CSharpBinding.Refactoring\CSharpFindReferencesProviderTests.cs" /> </ItemGroup> <ItemGroup> <None Include="Makefile.am" /> |