Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#### 2.0.0.1-beta
* Fix 452 - FSharpField.IsMutable = true for BCL enum cases
* Include fix from 1.4.2.2 for #488 - Performance problems with project references
* Fix 452 - FSharpField.IsMutable = true for BCL enum cases
* Fix 414 - Add IsInstanceMemberInCompiledCode

#### 2.0.0.0-beta
* Feature #470, #478, #479 - Move ProjectCracker to separate nuget package and DLL, used ProjectCrackerTool.exe to run
Expand Down
9 changes: 9 additions & 0 deletions src/fsharp/vs/Symbols.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1404,6 +1404,15 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
| M m -> m.IsInstance
| V v -> v.IsInstanceMember

member v.IsInstanceMemberInCompiledCode =
if isUnresolved() then false else
v.IsInstanceMember &&
match d with
| E e -> match e.ArbitraryValRef with Some vref -> ValRefIsCompiledAsInstanceMember cenv.g vref | None -> true
| P p -> match p.ArbitraryValRef with Some vref -> ValRefIsCompiledAsInstanceMember cenv.g vref | None -> true
| M m -> match m.ArbitraryValRef with Some vref -> ValRefIsCompiledAsInstanceMember cenv.g vref | None -> true
| V vref -> ValRefIsCompiledAsInstanceMember cenv.g vref

member __.IsExtensionMember =
if isUnresolved() then false else
match d with
Expand Down
6 changes: 6 additions & 0 deletions src/fsharp/vs/Symbols.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,12 @@ and [<Class>] FSharpMemberOrFunctionOrValue =
/// Indicates if this is an instance member, when seen from F#?
member IsInstanceMember : bool

/// Indicates if this is an instance member in compiled code.
///
/// Explanatory note: some members such as IsNone and IsSome on types with UseNullAsTrueValue appear
/// as instance members in F# code but are compiled as static members.
member IsInstanceMemberInCompiledCode : bool

/// Indicates if this is an implicit constructor?
member IsImplicitConstructor : bool

Expand Down
75 changes: 74 additions & 1 deletion tests/service/ProjectAnalysisTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ let attribsOfSymbol (s:FSharpSymbol) =
if v.IsImplicitConstructor then yield "ctor"
if v.IsMutable then yield "mutable"
if v.IsOverrideOrExplicitInterfaceImplementation then yield "overridemem"
if v.IsInstanceMember && not v.IsInstanceMemberInCompiledCode then yield "funky"
if v.IsExplicitInterfaceImplementation then yield "intfmem"
// if v.IsConstructorThisValue then yield "ctorthis"
// if v.IsMemberThisValue then yield "this"
Expand Down Expand Up @@ -202,7 +203,7 @@ let ``Test project1 whole project errors`` () =
wholeProjectResults.Errors.[0].EndColumn |> shouldEqual 44

[<Test>]
let ``Test project39 should have protected FullName and TryFullName return same results`` () =
let ``Test Project1 should have protected FullName and TryFullName return same results`` () =
let wholeProjectResults = checker.ParseAndCheckProject(Project1.options) |> Async.RunSynchronously
let rec getFullNameComparisons (entity: FSharpEntity) =
seq { if not entity.IsProvided && entity.Accessibility.IsPublic then
Expand Down Expand Up @@ -4630,6 +4631,9 @@ let ``Test project37 typeof and arrays in attribute constructor arguments`` () =
|> Seq.map (fun a -> a.AttributeType.CompiledName)
|> Array.ofSeq |> shouldEqual [| "AttrTestAttribute"; "AttrTest2Attribute" |]

//-----------------------------------------------------------


module Project38 =
open System.IO

Expand Down Expand Up @@ -4724,6 +4728,8 @@ let ``Test project38 abstract slot information`` () =
|]


//--------------------------------------------

module Project39 =
open System.IO

Expand Down Expand Up @@ -4802,3 +4808,70 @@ let ``Test project39 all symbols`` () =
[["'a"]; ["'a0"]; ["'a"; "'a0"]]),
("return", "'b"))]


//--------------------------------------------

module Project40 =
open System.IO

let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs")
let base2 = Path.GetTempFileName()
let dllName = Path.ChangeExtension(base2, ".dll")
let projFileName = Path.ChangeExtension(base2, ".fsproj")
let fileSource1 = """
module M

let f (x: option<_>) = x.IsSome, x.IsNone

[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
type C =
| A
| B of string
member x.IsItAnA = match x with A -> true | B _ -> false
member x.IsItAnAMethod() = match x with A -> true | B _ -> false

let g (x: C) = x.IsItAnA,x.IsItAnAMethod()
"""

File.WriteAllText(fileName1, fileSource1)
let fileNames = [fileName1]
let args = mkProjectCommandLineArgs (dllName, fileNames)
let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args)
let cleanFileName a = if a = fileName1 then "file1" else "??"

[<Test>]
let ``Test Project40 all symbols`` () =

let wholeProjectResults = checker.ParseAndCheckProject(Project40.options) |> Async.RunSynchronously
let allSymbolUses = wholeProjectResults.GetAllUsesOfAllSymbols() |> Async.RunSynchronously
let allSymbolUsesInfo = [ for s in allSymbolUses -> s.Symbol.DisplayName, tups s.RangeAlternate, attribsOfSymbol s.Symbol ]
allSymbolUsesInfo |> shouldEqual
[("option", ((4, 10), (4, 16)), ["abbrev"]); ("x", ((4, 7), (4, 8)), []);
("x", ((4, 23), (4, 24)), []);
("IsSome", ((4, 23), (4, 31)), ["member"; "prop"; "funky"]);
("x", ((4, 33), (4, 34)), []);
("IsNone", ((4, 33), (4, 41)), ["member"; "prop"; "funky"]);
("f", ((4, 4), (4, 5)), ["val"]);
("CompilationRepresentationAttribute", ((6, 2), (6, 27)), ["class"]);
("CompilationRepresentationAttribute", ((6, 2), (6, 27)), ["class"]);
("CompilationRepresentationAttribute", ((6, 2), (6, 27)), ["member"]);
("CompilationRepresentationFlags", ((6, 28), (6, 58)),
["enum"; "valuetype"]);
("UseNullAsTrueValue", ((6, 28), (6, 77)), ["field"; "static"; "8"]);
("string", ((9, 11), (9, 17)), ["abbrev"]);
("string", ((9, 11), (9, 17)), ["abbrev"]); ("A", ((8, 6), (8, 7)), []);
("B", ((9, 6), (9, 7)), []); ("C", ((7, 5), (7, 6)), ["union"]);
("IsItAnA", ((10, 13), (10, 20)), ["member"; "getter"; "funky"]);
("IsItAnAMethod", ((11, 13), (11, 26)), ["member"; "funky"]);
("x", ((10, 11), (10, 12)), []); ("x", ((10, 29), (10, 30)), []);
("A", ((10, 36), (10, 37)), []); ("B", ((10, 48), (10, 49)), []);
("x", ((11, 11), (11, 12)), []); ("x", ((11, 37), (11, 38)), []);
("A", ((11, 44), (11, 45)), []); ("B", ((11, 56), (11, 57)), []);
("C", ((13, 10), (13, 11)), ["union"]); ("x", ((13, 7), (13, 8)), []);
("x", ((13, 15), (13, 16)), []);
("IsItAnA", ((13, 15), (13, 24)), ["member"; "prop"; "funky"]);
("x", ((13, 25), (13, 26)), []);
("IsItAnAMethod", ((13, 25), (13, 40)), ["member"; "funky"]);
("g", ((13, 4), (13, 5)), ["val"]); ("M", ((2, 7), (2, 8)), ["module"])]