diff --git a/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj index 8686318fe23ab517b34b42a7a208ab1055f74840..e83bc805c0053c15ac4f86e8e90bf2a46c55185e 100644 --- a/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj +++ b/fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj @@ -70,6 +70,9 @@ ProjectOptionsTests.fs + + StructureTests.fs + FSharp.Core.optdata PreserveNewest diff --git a/src/fsharp/vs/ServiceStructure.fs b/src/fsharp/vs/ServiceStructure.fs index 35e3d2383e4b5ccfcb84e44a9882705fbdbda778..ffe2461d95948fc3fd97abe366b7f46d73ac6dc8 100644 --- a/src/fsharp/vs/ServiceStructure.fs +++ b/src/fsharp/vs/ServiceStructure.fs @@ -228,8 +228,7 @@ module Structure = | SynExpr.DotIndexedGet (e,_,_,_) | SynExpr.DotIndexedSet (e,_,_,_,_,_) -> parseExpr e | SynExpr.New (_,_,expr,r) -> - let collapse = Range.endToEnd expr.Range r - rcheck Scope.New Collapse.Below r collapse + rcheck Scope.New Collapse.Below r expr.Range parseExpr expr | SynExpr.YieldOrReturn (_,e,r) -> rcheck Scope.YieldOrReturn Collapse.Below r r diff --git a/tests/service/StructureTests.fs b/tests/service/StructureTests.fs index 6e80a66bba227a231602c99e4d277873a4bd9218..cbfc937a384f3ddc61ea89bdc9fd36e2bb9fb7ef 100644 --- a/tests/service/StructureTests.fs +++ b/tests/service/StructureTests.fs @@ -9,15 +9,18 @@ module Tests.Service.StructureTests open System.IO open NUnit.Framework +open Microsoft.FSharp.Compiler.Range open Microsoft.FSharp.Compiler.SourceCodeServices +open Microsoft.FSharp.Compiler.SourceCodeServices.Structure open FSharp.Compiler.Service.Tests.Common open System.Text let fileName = Path.Combine (__SOURCE_DIRECTORY__, __SOURCE_FILE__) type Line = int type Col = int +type Range = Line * Col * Line * Col -let (=>) (source: string) (expectedRanges: (Line * Col * Line * Col) list) = +let (=>) (source: string) (expectedRanges: (Range * Range) list) = let lines = use reader = new StringReader(source) [| let line = ref (reader.ReadLine()) @@ -35,14 +38,17 @@ let (=>) (source: string) (expectedRanges: (Line * Col * Line * Col) list) = sb.AppendLine (sprintf "%A" r) |> ignore sprintf "%O ]" sb + let getRange (r: range) = (r.StartLine, r.StartColumn, r.EndLine, r.EndColumn) + let ast = parseSourceCode(fileName, source) + try match ast with | Some tree -> let actual = Structure.getOutliningRanges lines tree |> Seq.filter (fun sr -> sr.Range.StartLine <> sr.Range.EndLine) - |> Seq.map (fun r -> r.Range.StartLine, r.Range.StartColumn, r.Range.EndLine, r.Range.EndColumn) + |> Seq.map (fun sr -> getRange sr.Range, getRange sr.CollapseRange) |> Seq.sort |> List.ofSeq let expected = List.sort expectedRanges @@ -54,7 +60,7 @@ let (=>) (source: string) (expectedRanges: (Line * Col * Line * Col) list) = reraise() [] -let ``empty file``() = "" => [ (1, 0, 2, 0) ] +let ``empty file``() = "" => [ (1, 0, 2, 0), (1, 0, 2, 0) ] [] let ``nested module``() = @@ -62,8 +68,8 @@ let ``nested module``() = module MyModule = () """ - => [ (1, 0, 4, 0) - (2, 0, 3, 6) ] + => [ (1, 0, 4, 0), (1, 0, 4, 0) + (2, 0, 3, 6), (2, 15, 3, 6) ] [] let ``module with multiline function``() = @@ -72,10 +78,10 @@ module MyModule = let foo() = foo() """ - => [ (1, 0, 5, 0) - (2, 0, 4, 13) - (3, 4, 4, 13) - (3, 8, 4, 13) ] + => [ (1, 0, 5, 0), (1, 0, 5, 0) + (2, 0, 4, 13), (2, 15, 4, 13) + (3, 4, 4, 13), (3, 13, 4, 13) + (3, 8, 4, 13), (3, 13, 4, 13) ] [] let ``DU``() = @@ -85,9 +91,9 @@ type Color = | Green | Blue """ - => [ (1, 0, 6, 0) - (2, 5, 5, 10) - (3, 4, 5, 10) ] + => [ (1, 0, 6, 0), (1, 0, 6, 0) + (2, 5, 5, 10), (2, 11, 5, 10) + (3, 4, 5, 10), (3, 4, 5, 10) ] [] let ``DU with interface``() = @@ -101,12 +107,12 @@ type Color = member __.Dispose() = (docEventListener :> IDisposable).Dispose() """ - => [ (1, 0, 10, 0) - (2, 5, 9, 55) - (3, 4, 5, 10) - (7, 4, 9, 55) - (8, 15, 9, 55) - (8, 15, 9, 55) ] + => [ (1, 0, 10, 0), (1, 0, 10, 0) + (2, 5, 9, 55), (2, 11, 9, 55) + (3, 4, 5, 10), (3, 4, 5, 10) + (7, 4, 9, 55), (7, 25, 9, 55) + (8, 15, 9, 55), (8, 27, 9, 55) + (8, 15, 9, 55), (8, 27, 9, 55) ] [] let ``record with interface``() = @@ -122,13 +128,13 @@ type Color = (docEventListener :> IDisposable).Dispose() """ => - [ (1, 0, 11, 0) - (2, 5, 10, 55) - (3, 4, 4, 14) - (3, 6, 4, 13) - (8, 4, 10, 55) - (9, 15, 10, 55) - (9, 15, 10, 55) ] + [ (1, 0, 11, 0), (1, 0, 11, 0) + (2, 5, 10, 55), (2, 11, 10, 55) + (3, 4, 4, 14), (3, 4, 4, 14) + (3, 6, 4, 13), (3, 6, 4, 13) + (8, 4, 10, 55), (8, 25, 10, 55) + (9, 15, 10, 55), (9, 27, 10, 55) + (9, 15, 10, 55), (9, 27, 10, 55) ] [] let ``type with a do block``() = @@ -141,10 +147,10 @@ type Color() = // 2 foo() () // 8 """ - => [ (1, 0, 9, 0) - (2, 5, 8, 10) - (3, 8, 4, 10) - (6, 4, 8, 10) ] + => [ (1, 0, 9, 0), (1, 0, 9, 0) + (2, 5, 8, 10), (2, 11, 8, 10) + (3, 8, 4, 10), (3, 13, 4, 10) + (6, 4, 8, 10), (6, 6, 8, 10) ] [] let ``complex outlining test``() = @@ -176,21 +182,21 @@ module MyModule = // 2 member __.Dispose() = (docEventListener :> IDisposable).Dispose() """ - => [ (1, 0, 28, 0) - (2, 0, 27, 63) - (4, 4, 5, 10) - (4, 8, 5, 10) - (7, 9, 15, 59) - (8, 8, 11, 9) - (13, 8, 15, 59) - (14, 19, 15, 59) - (14, 19, 15, 59) - (17, 4, 27, 63) - (19, 13, 27, 63) - (20, 12, 23, 13) - (25, 12, 27, 63) - (26, 23, 27, 63) - (26, 23, 27, 63) ] + => [ (1, 0, 28, 0), (1, 0, 28, 0) + (2, 0, 27, 63), (2, 15, 27, 63) + (4, 4, 5, 10), (4, 13, 5, 10) + (4, 8, 5, 10), (4, 13, 5, 10) + (7, 9, 15, 59), (7, 15, 15, 59) + (8, 8, 11, 9), (8, 8, 11, 9) + (13, 8, 15, 59), (13, 29, 15, 59) + (14, 19, 15, 59), (14, 31, 15, 59) + (14, 19, 15, 59), (14, 31, 15, 59) + (17, 4, 27, 63), (17, 24, 27, 63) + (19, 13, 27, 63), (19, 25, 27, 63) + (20, 12, 23, 13), (20, 12, 23, 13) + (25, 12, 27, 63), (25, 33, 27, 63) + (26, 23, 27, 63), (26, 35, 27, 63) + (26, 23, 27, 63), (26, 35, 27, 63) ] [] @@ -222,14 +228,14 @@ open H open G open H """ - => [ (1, 0, 26, 6) - (2, 5, 3, 6) - (5, 0, 19, 17) - (8, 9, 9, 10) - (11, 4, 14, 17) - (16, 4, 19, 17) - (17, 13, 18, 14) - (21, 5, 26, 6) ] + => [ (1, 0, 26, 6), (1, 0, 26, 6) + (2, 5, 3, 6), (2, 5, 3, 6) + (5, 0, 19, 17), (5, 8, 19, 17) + (8, 9, 9, 10), (8, 9, 9, 10) + (11, 4, 14, 17), (11, 12, 14, 17) + (16, 4, 19, 17), (16, 12, 19, 17) + (17, 13, 18, 14), (17, 13, 18, 14) + (21, 5, 26, 6), (21, 5, 26, 6) ] [] let ``hash directives``() = @@ -257,9 +263,9 @@ let x = 1 "c" #r "d" """ - => [ (1, 0, 23, 6) - (2, 3, 8, 6) - (11, 3, 23, 6) ] + => [ (1, 0, 23, 6), (1, 0, 23, 6) + (2, 3, 8, 6), (2, 3, 8, 6) + (11, 3, 23, 6), (11, 3, 23, 6) ] [] let ``nested let bindings``() = @@ -271,11 +277,11 @@ let f x = // 2 () // 6 x // 7 """ - => [ (1, 0, 8, 0) - (2, 0, 7, 5) - (2, 4, 7, 5) - (3, 8, 6, 10) - (4, 12, 5, 14) ] + => [ (1, 0, 8, 0), (1, 0, 8, 0) + (2, 0, 7, 5), (2, 7, 7, 5) + (2, 4, 7, 5), (2, 7, 7, 5) + (3, 8, 6, 10), (3, 11, 6, 10) + (4, 12, 5, 14), (4, 13, 5, 14) ] [] let ``match``() = @@ -290,11 +296,11 @@ match None with // 2 let x = () // 9 () // 10 """ - => [ (1, 0, 11, 0) - (2, 0, 10, 10) - (6, 4, 10, 10) - (6, 4, 10, 10) - (9, 8, 10, 10) ] + => [ (1, 0, 11, 0), (1, 0, 11, 0) + (2, 0, 10, 10), (2, 15, 10, 10) + (6, 4, 10, 10), (5, 6, 10, 10) + (6, 4, 10, 10), (6, 19, 10, 10) + (9, 8, 10, 10), (8, 10, 10, 10) ] [] let ``computation expressions``() = @@ -307,11 +313,11 @@ seq { // 2 yield () } // 7 } // 8 """ - => [ (1, 0, 8, 1) - (2, 0, 8, 1) - (4, 8, 5, 10) - (6, 4, 7, 18) - (6, 11, 7, 18) ] + => [ (1, 0, 8, 1), (1, 0, 8, 1) + (2, 0, 8, 1), (2, 5, 8, 0) + (4, 8, 5, 10), (4, 11, 5, 10) + (6, 4, 7, 18), (6, 4, 7, 18) + (6, 11, 7, 18), (6, 16, 7, 17) ] [] let ``list``() = @@ -320,10 +326,10 @@ let _ = [ 1; 2 3 ] """ - => [ (1, 0, 5, 0) - (2, 0, 4, 9) - (2, 4, 4, 9) - (3, 4, 4, 9) ] + => [ (1, 0, 5, 0), (1, 0, 5, 0) + (2, 0, 4, 9), (2, 5, 4, 9) + (2, 4, 4, 9), (2, 5, 4, 9) + (3, 4, 4, 9), (3, 5, 4, 8) ] [] let ``object expressions``() = @@ -332,10 +338,10 @@ let _ = { new System.IDisposable with member __.Dispose() = () } """ - => [ (1, 0, 5, 0) - (2, 0, 4, 34) - (2, 4, 4, 34) - (3, 4, 4, 34) ] + => [ (1, 0, 5, 0), (1, 0, 5, 0) + (2, 0, 4, 34), (2, 5, 4, 34) + (2, 4, 4, 34), (2, 5, 4, 34) + (3, 4, 4, 34), (3, 28, 4, 34) ] [] let ``try - with``() = @@ -348,13 +354,13 @@ with _ -> // 5 () // 7 () // 8 """ - => [ (1, 0, 9, 0) - (2, 0, 5, 0) - (2, 0, 8, 6) - (3, 8, 4, 10) - (5, 0, 8, 6) - (6, 4, 8, 6) - (6, 8, 7, 10) ] + => [ (1, 0, 9, 0), (1, 0, 9, 0) + (2, 0, 5, 0), (2, 3, 5, 0) + (2, 0, 8, 6), (2, 3, 8, 6) + (3, 8, 4, 10), (3, 11, 4, 10) + (5, 0, 8, 6), (5, 4, 8, 6) + (6, 4, 8, 6), (5, 6, 8, 6) + (6, 8, 7, 10), (6, 11, 7, 10) ] [] let ``try - finally``() = @@ -367,11 +373,11 @@ finally // 5 () // 7 () // 8 """ - => [ (1, 0, 9, 0) - (2, 0, 8, 6) - (3, 8, 4, 10) - (5, 0, 8, 6) - (6, 8, 7, 10) ] + => [ (1, 0, 9, 0), (1, 0, 9, 0) + (2, 0, 8, 6), (2, 3, 8, 6) + (3, 8, 4, 10), (3, 11, 4, 10) + (5, 0, 8, 6), (5, 7, 8, 6) + (6, 8, 7, 10), (6, 11, 7, 10) ] [] let ``if - then - else``() = @@ -385,11 +391,11 @@ else () () """ - => [ (1, 0, 10, 0) - (2, 0, 9, 6) - (2, 8, 5, 6) - (3, 8, 4, 10) - (7, 8, 8, 10) ] + => [ (1, 0, 10, 0), (1, 0, 10, 0) + (2, 0, 9, 6), (2, 7, 9, 6) + (2, 8, 5, 6), (2, 12, 5, 6) + (3, 8, 4, 10), (3, 11, 4, 10) + (7, 8, 8, 10), (7, 11, 8, 10) ] [] let ``code quotation``() = @@ -398,8 +404,8 @@ let ``code quotation``() = "code" @> """ - => [ 1, 0, 4, 10 - 2, 0, 4, 10 ] + => [ (1, 0, 4, 10), (1, 0, 4, 10) + (2, 0, 4, 10), (2, 2, 4, 8) ] [] let ``raw code quotation``() = @@ -408,8 +414,8 @@ let ``raw code quotation``() = "code" @@> """ - => [ (1, 0, 4, 11) - (2, 0, 4, 11) ] + => [ (1, 0, 4, 11), (1, 0, 4, 11) + (2, 0, 4, 11), (2, 3, 4, 8) ] [] let ``match lambda aka function``() = @@ -418,9 +424,9 @@ function | 0 -> () () """ - => [ (1, 0, 5, 0) - (2, 0, 4, 10) - (3, 8, 4, 10) ] + => [ (1, 0, 5, 0), (1, 0, 5, 0) + (2, 0, 4, 10), (2, 8, 4, 10) + (3, 8, 4, 10), (3, 3, 4, 10) ] [] let ``match guarded clause``() = @@ -430,11 +436,11 @@ let matchwith num = | 0 -> () () """ - => [ (1, 0, 6, 0) - (2, 0, 5, 13) - (2, 4, 5, 13) - (3, 4, 5, 13) - (4, 11, 5, 13) ] + => [ (1, 0, 6, 0), (1, 0, 6, 0) + (2, 0, 5, 13), (2, 17, 5, 13) + (2, 4, 5, 13), (2, 17, 5, 13) + (3, 4, 5, 13), (3, 18, 5, 13) + (4, 11, 5, 13), (4, 7, 5, 13) ] [] let ``for loop``() = @@ -443,8 +449,8 @@ for x = 100 downto 10 do () () """ - => [ (1, 0, 5, 0) - (2, 0, 4, 6) ] + => [ (1, 0, 5, 0), (1, 0, 5, 0) + (2, 0, 4, 6), (2, 0, 4, 6) ] [] let ``for each``() = @@ -453,9 +459,9 @@ for x in 0 .. 100 -> () () """ - => [ (1, 0, 5, 0) - (2, 0, 4, 14) - (2, 18, 4, 14) ] + => [ (1, 0, 5, 0), (1, 0, 5, 0) + (2, 0, 4, 14), (2, 0, 4, 14) + (2, 18, 4, 14), (2, 18, 4, 14) ] [] let ``tuple``() = @@ -464,8 +470,8 @@ let ``tuple``() = , 322 , 123123 ) """ - => [ (1, 0, 4, 10) - (2, 2, 4, 8) ] + => [ (1, 0, 4, 10), (1, 0, 4, 10) + (2, 2, 4, 8), (2, 2, 4, 8) ] [] let ``do!``() = @@ -474,8 +480,8 @@ do! printfn "allo" printfn "allo" """ - => [(1, 0, 5, 0) - (2, 0, 4, 18)] + => [(1, 0, 5, 0), (1, 0, 5, 0) + (2, 0, 4, 18), (2, 3, 4, 18)] [] let ``cexpr yield yield!``() = @@ -489,11 +495,11 @@ cexpr{ } } """ - => [1, 0, 9, 5 - 2, 0, 9, 5 - 3, 4, 8, 17 - 4, 8, 8, 17 - 5, 20, 7, 26] + => [(1, 0, 9, 5), (1, 0, 9, 5) + (2, 0, 9, 5), (2, 6, 9, 4) + (3, 4, 8, 17), (3, 4, 8, 17) + (4, 8, 8, 17), (4, 14, 8, 16) + (5, 20, 7, 26), (5, 20, 7, 26)] [] let ``XML doc comments``() = @@ -511,12 +517,12 @@ module M = /// Single line comment let f x = x """ - => [ (1, 0, 14, 0) - (2, 0, 3, 10) - (4, 0, 13, 15) - (5, 4, 6, 14) - (7, 9, 11, 19) - (8, 8, 10, 18) ] + => [ (1, 0, 14, 0), (1, 0, 14, 0) + (2, 0, 3, 10), (2, 0, 3, 10) + (4, 0, 13, 15), (4, 8, 13, 15) + (5, 4, 6, 14), (5, 4, 6, 14) + (7, 9, 11, 19), (7, 11, 11, 19) + (8, 8, 10, 18), (8, 8, 10, 18) ] [] let ``regular comments``() = @@ -534,12 +540,12 @@ module M = // Single line comment let f x = x """ - => [ (1, 0, 14, 0) - (2, 0, 3, 9) - (4, 0, 13, 15) - (5, 4, 6, 13) - (7, 9, 11, 19) - (8, 8, 10, 17) ] + => [ (1, 0, 14, 0), (1, 0, 14, 0) + (2, 0, 3, 9), (2, 0, 3, 9) + (4, 0, 13, 15), (4, 8, 13, 15) + (5, 4, 6, 13), (5, 4, 6, 13) + (7, 9, 11, 19), (7, 11, 11, 19) + (8, 8, 10, 17), (8, 8, 10, 17) ] [] let ``XML doc and regular comments in one block``() = @@ -554,7 +560,23 @@ let ``XML doc and regular comments in one block``() = /// Line 8 /// Line 9 """ - => [ (1, 0, 11, 0) - (2, 0, 3, 9) - (4, 0, 5, 10) - (7, 0, 10, 10) ] \ No newline at end of file + => [ (1, 0, 11, 0), (1, 0, 11, 0) + (2, 0, 3, 9), (2, 0, 3, 9) + (4, 0, 5, 10), (4, 0, 5, 10) + (7, 0, 10, 10), (7, 0, 10, 10) ] + +[] +let ``constructor call``() = + """ +module M = + let s = + new System.String( + 'c', + 1) +""" + => [ (1, 0, 7, 0), (1, 0, 7, 0) + (2, 0, 6, 14), (2, 8, 6, 14) + (3, 4, 6, 14), (3, 9, 6, 14) + (3, 8, 6, 14), (3, 9, 6, 14) + (4, 8, 6, 14), (4, 25, 6, 14) + (5, 12, 6, 13), (5, 12, 6, 13) ]