Skip to content

Commit b2afd2e

Browse files
committed
Merge branch 'master' of https://github.com/fsharp/FSharp.Compiler.Service into fsharp4
2 parents abd6169 + 192beb8 commit b2afd2e

File tree

4 files changed

+139
-39
lines changed

4 files changed

+139
-39
lines changed

docs/content/interactive.fsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ One reason is that there is no way to handle `StackOverflowException` and so a p
1717
script can terminate the host process. **Remember that while calling F# Interactive through .NET API,
1818
` --shadowcopyreferences` option will be ignored**. For detailed discussion, please take a look at
1919
[this thread](https://github.com/fsharp/FSharp.Compiler.Service/issues/292).
20+
> **NOTE:** If `FsiEvaluationSession.Create` fails with an error saying that `FSharp.Core.dll` cannot be found,
21+
add the `FSharp.Core.sigdata` and `FSharp.Core.optdata` files. More info [here](https://fsharp.github.io/FSharp.Compiler.Service/corelib.html).
2022
2123
However, the F# interactive service is still useful, because you might want to wrap it in your
2224
own executable that is then executed (and communicates with the rest of your application), or

src/fsharp/vs/Symbols.fs

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,28 @@ module Impl =
118118
| FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata ->
119119
entity.Accessibility
120120

121-
121+
let getLiteralValue = function
122+
| Some lv ->
123+
match lv with
124+
| Const.Bool v -> Some(box v)
125+
| Const.SByte v -> Some(box v)
126+
| Const.Byte v -> Some(box v)
127+
| Const.Int16 v -> Some(box v)
128+
| Const.UInt16 v -> Some(box v)
129+
| Const.Int32 v -> Some(box v)
130+
| Const.UInt32 v -> Some(box v)
131+
| Const.Int64 v -> Some(box v)
132+
| Const.UInt64 v -> Some(box v)
133+
| Const.IntPtr v -> Some(box v)
134+
| Const.UIntPtr v -> Some(box v)
135+
| Const.Single v -> Some(box v)
136+
| Const.Double v -> Some(box v)
137+
| Const.Char v -> Some(box v)
138+
| Const.String v -> Some(box v)
139+
| Const.Decimal v -> Some(box v)
140+
| Const.Unit
141+
| Const.Zero -> None
142+
| None -> None
122143

123144

124145
type cenv(g:TcGlobals, thisCcu: CcuThunk , tcImports: TcImports) =
@@ -638,29 +659,9 @@ and FSharpField(cenv, d: FSharpFieldData) =
638659
d.RecdField.LiteralValue.IsSome
639660

640661
member __.LiteralValue =
641-
if isUnresolved() then None else
642-
match d.RecdField.LiteralValue with
643-
| Some lv ->
644-
match lv with
645-
| Const.Bool v -> Some(box v)
646-
| Const.SByte v -> Some(box v)
647-
| Const.Byte v -> Some(box v)
648-
| Const.Int16 v -> Some(box v)
649-
| Const.UInt16 v -> Some(box v)
650-
| Const.Int32 v -> Some(box v)
651-
| Const.UInt32 v -> Some(box v)
652-
| Const.Int64 v -> Some(box v)
653-
| Const.UInt64 v -> Some(box v)
654-
| Const.IntPtr v -> Some(box v)
655-
| Const.UIntPtr v -> Some(box v)
656-
| Const.Single v -> Some(box v)
657-
| Const.Double v -> Some(box v)
658-
| Const.Char v -> Some(box v)
659-
| Const.String v -> Some(box v)
660-
| Const.Decimal v -> Some(box v)
661-
| Const.Unit
662-
| Const.Zero -> None
663-
| None -> None
662+
if isUnresolved()
663+
then None
664+
else getLiteralValue d.RecdField.LiteralValue
664665

665666
member __.IsVolatile =
666667
if isUnresolved() then false else
@@ -1489,20 +1490,33 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
14891490
v.Attribs |> List.map (fun a -> FSharpAttribute(cenv, AttribInfo.FSAttribInfo(cenv.g, a)))
14901491
|> makeReadOnlyCollection
14911492

1492-
(*
14931493
/// Is this "base" in "base.M(...)"
1494-
member __.IsBaseValue : bool
1494+
member __.IsBaseValue =
1495+
if isUnresolved() then false else
1496+
match d with
1497+
| M _ | P _ | E _ -> false
1498+
| V v -> v.BaseOrThisInfo = BaseVal
14951499

14961500
/// Is this the "x" in "type C() as x = ..."
1497-
member __.IsConstructorThisValue : bool
1498-
1499-
/// Is this the "x" in "member __.M = ..."
1500-
member __.IsMemberThisValue : bool
1501+
member __.IsConstructorThisValue =
1502+
if isUnresolved() then false else
1503+
match d with
1504+
| M _ | P _ | E _ -> false
1505+
| V v -> v.BaseOrThisInfo = CtorThisVal
15011506

1502-
/// Is this a [<Literal>] value, and if so what value?
1503-
member __.LiteralValue : obj // may be null
1507+
/// Is this the "x" in "member x.M = ..."
1508+
member __.IsMemberThisValue =
1509+
if isUnresolved() then false else
1510+
match d with
1511+
| M _ | P _ | E _ -> false
1512+
| V v -> v.BaseOrThisInfo = MemberThisVal
15041513

1505-
*)
1514+
/// Is this a [<Literal>] value, and if so what value? (may be null)
1515+
member __.LiteralValue =
1516+
if isUnresolved() then None else
1517+
match d with
1518+
| M _ | P _ | E _ -> None
1519+
| V v -> getLiteralValue v.LiteralValue
15061520

15071521
/// How visible is this?
15081522
member this.Accessibility : FSharpAccessibility =

src/fsharp/vs/Symbols.fsi

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -698,8 +698,6 @@ and [<Class>] FSharpMemberOrFunctionOrValue =
698698
/// XML documentation signature for the value, used for .xml file lookup for compiled code
699699
member XmlDocSig: string
700700

701-
702-
#if TODO
703701
/// Indicates if this is "base" in "base.M(...)"
704702
member IsBaseValue : bool
705703

@@ -709,10 +707,8 @@ and [<Class>] FSharpMemberOrFunctionOrValue =
709707
/// Indicates if this is the "x" in "member x.M = ..."
710708
member IsMemberThisValue : bool
711709

712-
/// Indicates if this is a [<Literal>] value, and if so what value?
713-
member LiteralValue : obj // may be null
714-
715-
#endif
710+
/// Indicates if this is a [<Literal>] value, and if so what value? (may be null)
711+
member LiteralValue : obj option
716712

717713
/// Get the accessibility information for the member, function or value
718714
member Accessibility : FSharpAccessibility

tests/service/ProjectAnalysisTests.fs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ let attribsOfSymbol (s:FSharpSymbol) =
8888
if v.IsMutable then yield "mutable"
8989
if v.IsOverrideOrExplicitInterfaceImplementation then yield "overridemem"
9090
if v.IsExplicitInterfaceImplementation then yield "intfmem"
91+
// if v.IsConstructorThisValue then yield "ctorthis"
92+
// if v.IsMemberThisValue then yield "this"
93+
// if v.LiteralValue.IsSome then yield "literal"
9194
| _ -> () ]
9295

9396
module Project1 =
@@ -4408,3 +4411,88 @@ let ``Test project35 CurriedParameterGroups should be available for nested funct
44084411

44094412
| _ -> failwith "Unexpected symbol type"
44104413

4414+
module Project36 =
4415+
open System.IO
4416+
4417+
let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs")
4418+
let base2 = Path.GetTempFileName()
4419+
let dllName = Path.ChangeExtension(base2, ".dll")
4420+
let projFileName = Path.ChangeExtension(base2, ".fsproj")
4421+
let fileSource1 = """
4422+
type A(i:int) =
4423+
member x.Value = i
4424+
4425+
type B(i:int) as b =
4426+
inherit A(i*2)
4427+
let a = b.Overload(i)
4428+
member x.Overload() = a
4429+
member x.Overload(y: int) = y + y
4430+
member x.BaseValue = base.Value
4431+
4432+
let [<Literal>] lit = 1.0
4433+
let notLit = 1.0
4434+
let callToOverload = B(5).Overload(4)
4435+
"""
4436+
File.WriteAllText(fileName1, fileSource1)
4437+
let cleanFileName a = if a = fileName1 then "file1" else "??"
4438+
4439+
let fileNames = [fileName1]
4440+
let args = mkProjectCommandLineArgs (dllName, fileNames)
4441+
let keepAssemblyContentsChecker = FSharpChecker.Create(keepAssemblyContents=true)
4442+
let options = keepAssemblyContentsChecker.GetProjectOptionsFromCommandLineArgs (projFileName, args)
4443+
let wholeProjectResults =
4444+
keepAssemblyContentsChecker.ParseAndCheckProject(options)
4445+
|> Async.RunSynchronously
4446+
let declarations =
4447+
let checkedFile = wholeProjectResults.AssemblyContents.ImplementationFiles.[0]
4448+
match checkedFile.Declarations.[0] with
4449+
| FSharpImplementationFileDeclaration.Entity (_, subDecls) -> subDecls
4450+
| _ -> failwith "unexpected declaration"
4451+
let getExpr exprIndex =
4452+
match declarations.[exprIndex] with
4453+
| FSharpImplementationFileDeclaration.MemberOrFunctionOrValue(_,_,e) -> e
4454+
| FSharpImplementationFileDeclaration.InitAction e -> e
4455+
| _ -> failwith "unexpected declaration"
4456+
4457+
[<Test>]
4458+
let ``Test project36 FSharpMemberOrFunctionOrValue.IsBaseValue`` () =
4459+
Project36.wholeProjectResults.GetAllUsesOfAllSymbols()
4460+
|> Async.RunSynchronously
4461+
|> Array.pick (fun (su:FSharpSymbolUse) ->
4462+
if su.Symbol.DisplayName = "base"
4463+
then Some (su.Symbol :?> FSharpMemberOrFunctionOrValue)
4464+
else None)
4465+
|> fun baseSymbol -> shouldEqual true baseSymbol.IsBaseValue
4466+
4467+
[<Test>]
4468+
let ``Test project36 FSharpMemberOrFunctionOrValue.IsConstructorThisValue & IsMemberThisValue`` () =
4469+
// Instead of checking the symbol uses directly, walk the typed tree to check
4470+
// the correct values are also visible from there. Also note you cannot use
4471+
// BasicPatterns.ThisValue in these cases, this is only used when the symbol
4472+
// is implicit in the constructor
4473+
match Project36.getExpr 4 with
4474+
| BasicPatterns.Let((b,_),_) ->
4475+
b.IsConstructorThisValue && not b.IsMemberThisValue
4476+
| _ -> failwith "unexpected expression"
4477+
|> shouldEqual true
4478+
4479+
match Project36.getExpr 5 with
4480+
| BasicPatterns.FSharpFieldGet(Some(BasicPatterns.Value x),_,_) ->
4481+
x.IsMemberThisValue && not x.IsConstructorThisValue
4482+
| _ -> failwith "unexpected expression"
4483+
|> shouldEqual true
4484+
4485+
match Project36.getExpr 6 with
4486+
| BasicPatterns.Call(_,_,_,_,[BasicPatterns.Value s;_]) ->
4487+
not s.IsMemberThisValue && not s.IsConstructorThisValue
4488+
| _ -> failwith "unexpected expression"
4489+
|> shouldEqual true
4490+
4491+
[<Test>]
4492+
let ``Test project36 FSharpMemberOrFunctionOrValue.LiteralValue`` () =
4493+
let project36Module = Project36.wholeProjectResults.AssemblySignature.Entities.[0]
4494+
let lit = project36Module.MembersFunctionsAndValues.[0]
4495+
shouldEqual true (lit.LiteralValue.Value |> unbox |> (=) 1.)
4496+
4497+
let notLit = project36Module.MembersFunctionsAndValues.[1]
4498+
shouldEqual true notLit.LiteralValue.IsNone

0 commit comments

Comments
 (0)