From 8cb7ec2cc6c7a6921a23ce192278c72336a60160 Mon Sep 17 00:00:00 2001 From: Vasily Kirichenko Date: Thu, 31 May 2018 13:34:04 +0300 Subject: [PATCH 1/6] make matched brace highlighting work exactly as in C# editor --- .../src/FSharp.Editor/Formatting/BraceMatchingService.fs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs b/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs index 7b795f0cc8..be3b17a64b 100644 --- a/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs +++ b/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs @@ -24,9 +24,7 @@ type internal FSharpBraceMatchingService let isPositionInRange range = match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range) with | None -> false - | Some range -> - let length = position - range.Start - length >= 0 && length <= range.Length + | Some span -> span.Contains position return matchedBraces |> Array.tryFind(fun (left, right) -> isPositionInRange left || isPositionInRange right) } From 987850bb4b0c9dc88f137a11222904ab356a99ca Mon Sep 17 00:00:00 2001 From: Vasily Kirichenko Date: Thu, 31 May 2018 14:07:42 +0300 Subject: [PATCH 2/6] fix tests --- .../Formatting/BraceMatchingService.fs | 2 -- .../UnitTests/BraceMatchingServiceTests.fs | 25 ++++++++----------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs b/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs index be3b17a64b..46759ddee0 100644 --- a/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs +++ b/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs @@ -2,7 +2,6 @@ namespace Microsoft.VisualStudio.FSharp.Editor -open System open System.ComponentModel.Composition open Microsoft.CodeAnalysis.Editor open Microsoft.FSharp.Compiler.SourceCodeServices @@ -14,7 +13,6 @@ type internal FSharpBraceMatchingService checkerProvider: FSharpCheckerProvider, projectInfoManager: FSharpProjectOptionsManager ) = - static let defaultUserOpName = "BraceMatching" diff --git a/vsintegration/tests/UnitTests/BraceMatchingServiceTests.fs b/vsintegration/tests/UnitTests/BraceMatchingServiceTests.fs index 3ec9c9e0be..e323cc8db2 100644 --- a/vsintegration/tests/UnitTests/BraceMatchingServiceTests.fs +++ b/vsintegration/tests/UnitTests/BraceMatchingServiceTests.fs @@ -161,26 +161,23 @@ let main argv = 0 // return an integer exit code""" this.VerifyBraceMatch(code, "(printfn", ")endBrace") - [] - [] - [", [|9;10;11;14;15;16|])>] - [", [|9;10;11;12;15;15;16;17|])>] - [] - []\nlet a7 = 70", [|0;1;2;21;22;23|])>] - [] - member this.BraceMatchingBothSides_Bug2092(fileContents: string, matchingPositions: int[]) = - // https://github.com/Microsoft/visualfsharp/issues/2092 + [] + [] + [", [|9;10;15|])>] + [", [|9;10;11;15;16|])>] + [] + []\nlet a7 = 70", [|0;1;22|])>] + [] + member this.DoNotMatchOnInnerSide(fileContents: string, matchingPositions: int[]) = let sourceText = SourceText.From(fileContents) - let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions - matchingPositions - |> Array.iter (fun position -> + + for position in matchingPositions do match FSharpBraceMatchingService.GetBraceMatchingResult(checker, sourceText, fileName, parsingOptions, position, "UnitTest") |> Async.RunSynchronously with | Some _ -> () | None -> match position with | 0 -> "" | _ -> fileContents.[position - 1] |> sprintf " (previous character '%c')" - |> sprintf "Didn't find a matching brace at position '%d', character '%c'%s" position fileContents.[position] + |> sprintf "Didn't find a matching brace at position '%d' %s" position |> Assert.Fail - ) \ No newline at end of file From 94c0f3f2c3ff50cd90f5209e8ce6537aae78ce72 Mon Sep 17 00:00:00 2001 From: Phillip Carter Date: Thu, 31 May 2018 10:19:46 -0700 Subject: [PATCH 3/6] Add optional param for formatting --- .../FSharp.Editor/Formatting/BraceMatchingService.fs | 10 ++++++++-- .../Formatting/EditorFormattingService.fs | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs b/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs index 46759ddee0..511988985a 100644 --- a/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs +++ b/vsintegration/src/FSharp.Editor/Formatting/BraceMatchingService.fs @@ -5,6 +5,7 @@ namespace Microsoft.VisualStudio.FSharp.Editor open System.ComponentModel.Composition open Microsoft.CodeAnalysis.Editor open Microsoft.FSharp.Compiler.SourceCodeServices +open System.Runtime.InteropServices [] type internal FSharpBraceMatchingService @@ -16,13 +17,18 @@ type internal FSharpBraceMatchingService static let defaultUserOpName = "BraceMatching" - static member GetBraceMatchingResult(checker: FSharpChecker, sourceText, fileName, parsingOptions: FSharpParsingOptions, position: int, userOpName: string) = + static member GetBraceMatchingResult(checker: FSharpChecker, sourceText, fileName, parsingOptions: FSharpParsingOptions, position: int, userOpName: string, [] forFormatting: bool) = async { let! matchedBraces = checker.MatchBraces(fileName, sourceText.ToString(), parsingOptions, userOpName) let isPositionInRange range = match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range) with | None -> false - | Some span -> span.Contains position + | Some span -> + if forFormatting then + let length = position - span.Start + length >= 0 && length <= span.Length + else + span.Contains position return matchedBraces |> Array.tryFind(fun (left, right) -> isPositionInRange left || isPositionInRange right) } diff --git a/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs b/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs index f5fdc45016..03061fa350 100644 --- a/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs +++ b/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs @@ -50,7 +50,7 @@ type internal FSharpEditorFormattingService x.Tag <> FSharpTokenTag.LINE_COMMENT) let! (left, right) = - FSharpBraceMatchingService.GetBraceMatchingResult(checker, sourceText, filePath, parsingOptions, position, "FormattingService") + FSharpBraceMatchingService.GetBraceMatchingResult(checker, sourceText, filePath, parsingOptions, position, "FormattingService", forFormatting=true) if right.StartColumn = firstMeaningfulToken.LeftColumn then // Replace the indentation on this line with the indentation of the left bracket From 5ddaba3a5433967bdb7ff67e77bfd312717b198e Mon Sep 17 00:00:00 2001 From: Vasily Kirichenko Date: Thu, 31 May 2018 20:22:06 +0300 Subject: [PATCH 4/6] revert matching braces logic in FSharpEditorFormattingService --- .../Formatting/EditorFormattingService.fs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs b/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs index f5fdc45016..d5d161ab96 100644 --- a/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs +++ b/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs @@ -49,8 +49,16 @@ type internal FSharpEditorFormattingService x.Tag <> FSharpTokenTag.COMMENT && x.Tag <> FSharpTokenTag.LINE_COMMENT) - let! (left, right) = - FSharpBraceMatchingService.GetBraceMatchingResult(checker, sourceText, filePath, parsingOptions, position, "FormattingService") + let! matchedBraces = checker.MatchBraces(filePath, sourceText.ToString(), parsingOptions, "FormattingService") |> liftAsync + + let isPositionInRange range = + match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range) with + | None -> false + | Some span -> + let length = position - span.Start + length >= 0 && length <= span.Length + + let! left, right = matchedBraces |> Array.tryFind(fun (left, right) -> isPositionInRange left || isPositionInRange right) if right.StartColumn = firstMeaningfulToken.LeftColumn then // Replace the indentation on this line with the indentation of the left bracket From 5cda4b6302cacdaea2b56e0eb359f837390b04af Mon Sep 17 00:00:00 2001 From: Vasily Kirichenko Date: Thu, 31 May 2018 20:26:45 +0300 Subject: [PATCH 5/6] add missing test attributes --- vsintegration/tests/UnitTests/IndentationServiceTests.fs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vsintegration/tests/UnitTests/IndentationServiceTests.fs b/vsintegration/tests/UnitTests/IndentationServiceTests.fs index 83ce946655..5139e313a4 100644 --- a/vsintegration/tests/UnitTests/IndentationServiceTests.fs +++ b/vsintegration/tests/UnitTests/IndentationServiceTests.fs @@ -170,6 +170,7 @@ while true do |> Array.map (fun (lineNumber, expectedIndentation) -> ( Some(expectedIndentation), lineNumber, autoIndentTemplate )) + [] member this.TestIndentation() = for (expectedIndentation, lineNumber, template) in testCases do let sourceText = SourceText.From(template) @@ -179,7 +180,8 @@ while true do match expectedIndentation with | None -> Assert.IsTrue(actualIndentation.IsNone, "No indentation was expected at line {0}", lineNumber) | Some indentation -> Assert.AreEqual(expectedIndentation.Value, actualIndentation.Value, "Indentation on line {0} doesn't match", lineNumber) - + + [] member this.TestAutoIndentation() = for (expectedIndentation, lineNumber, template) in autoIndentTestCases do From 136dd524aa13c080764edfbce32cbbaea4e8d530 Mon Sep 17 00:00:00 2001 From: Vasily Kirichenko Date: Thu, 31 May 2018 20:27:31 +0300 Subject: [PATCH 6/6] Revert "revert matching braces logic in FSharpEditorFormattingService" This reverts commit 5ddaba3a5433967bdb7ff67e77bfd312717b198e. --- .../Formatting/EditorFormattingService.fs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs b/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs index d5d161ab96..f5fdc45016 100644 --- a/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs +++ b/vsintegration/src/FSharp.Editor/Formatting/EditorFormattingService.fs @@ -49,16 +49,8 @@ type internal FSharpEditorFormattingService x.Tag <> FSharpTokenTag.COMMENT && x.Tag <> FSharpTokenTag.LINE_COMMENT) - let! matchedBraces = checker.MatchBraces(filePath, sourceText.ToString(), parsingOptions, "FormattingService") |> liftAsync - - let isPositionInRange range = - match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range) with - | None -> false - | Some span -> - let length = position - span.Start - length >= 0 && length <= span.Length - - let! left, right = matchedBraces |> Array.tryFind(fun (left, right) -> isPositionInRange left || isPositionInRange right) + let! (left, right) = + FSharpBraceMatchingService.GetBraceMatchingResult(checker, sourceText, filePath, parsingOptions, position, "FormattingService") if right.StartColumn = firstMeaningfulToken.LeftColumn then // Replace the indentation on this line with the indentation of the left bracket