Skip to content

Commit 4f2ed4f

Browse files
committed
Merge pull request #430 from Jand42/master
Exposing implemented abstract slots
2 parents 9b8bb77 + c892b4c commit 4f2ed4f

File tree

5 files changed

+235
-4
lines changed

5 files changed

+235
-4
lines changed

src/fsharp/infos.fs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,11 @@ type ValRef with
375375
| TSlotSig(_,oty,_,_,_,_) :: _ -> isInterfaceTy g oty
376376
| [] -> false)
377377

378+
member vref.ImplementedSlotSignatures =
379+
match vref.MemberInfo with
380+
| None -> []
381+
| Some membInfo -> membInfo.ImplementedSlotSigs
382+
378383
//-------------------------------------------------------------------------
379384
// Helper methods associated with using TAST metadata (F# members, values etc.)
380385
// as backing data for MethInfo, PropInfo etc.
@@ -1090,6 +1095,11 @@ type MethInfo =
10901095
| ProvidedMeth _ -> false
10911096
#endif
10921097

1098+
member x.ImplementedSlotSignatures =
1099+
match x with
1100+
| FSMeth(_,_,vref,_) -> vref.ImplementedSlotSignatures
1101+
| _ -> failwith "not supported"
1102+
10931103
/// Indicates if this is an extension member.
10941104
member x.IsExtensionMember = x.IsCSharpStyleExtensionMember || x.IsFSharpStyleExtensionMember
10951105

@@ -1796,6 +1806,9 @@ type PropInfo =
17961806
| Some vref -> vref.IsDefiniteFSharpOverrideMember
17971807
| None -> false
17981808

1809+
member x.ImplementedSlotSignatures =
1810+
x.ArbitraryValRef.Value.ImplementedSlotSignatures
1811+
17991812
member x.IsFSharpExplicitInterfaceImplementation =
18001813
match x.ArbitraryValRef with
18011814
| Some vref -> vref.IsFSharpExplicitInterfaceImplementation x.TcGlobals

src/fsharp/vs/IncrementalBuild.fs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1532,7 +1532,11 @@ module internal IncrementalFSharpBuild =
15321532
errorRecoveryNoRange e
15331533
mkSimpleAssRef assemblyName, None, None
15341534

1535-
let finalAccWithErrors = { finalAcc with tcErrors = finalAcc.tcErrors @ errorLogger.GetErrors() }
1535+
let finalAccWithErrors =
1536+
{ finalAcc with
1537+
tcErrors = finalAcc.tcErrors @ errorLogger.GetErrors()
1538+
topAttribs = Some topAttrs
1539+
}
15361540
ilAssemRef, tcAssemblyDataOpt, tcAssemblyExprOpt, finalAccWithErrors
15371541

15381542
// END OF BUILD TASK FUNCTIONS

src/fsharp/vs/Symbols.fs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,57 @@ and FSharpDelegateSignature(cenv, info : SlotSig) =
855855
| Some ty -> FSharpType(cenv, ty)
856856
override x.ToString() = "<delegate signature>"
857857

858+
and FSharpAbstractParameter(cenv, info : SlotParam) =
859+
860+
member __.Name =
861+
let (TSlotParam(name, _, _, _, _, _)) = info
862+
name
863+
864+
member __.Type = FSharpType(cenv, info.Type)
865+
866+
member __.IsInArg =
867+
let (TSlotParam(_, _, isIn, _, _, _)) = info
868+
isIn
869+
870+
member __.IsOutArg =
871+
let (TSlotParam(_, _, _, isOut, _, _)) = info
872+
isOut
873+
874+
member __.IsOptionalArg =
875+
let (TSlotParam(_, _, _, _, isOptional, _)) = info
876+
isOptional
877+
878+
member __.Attributes =
879+
let (TSlotParam(_, _, _, _, _, attribs)) = info
880+
attribs |> List.map (fun a -> FSharpAttribute(cenv, AttribInfo.FSAttribInfo(cenv.g, a)))
881+
|> makeReadOnlyCollection
882+
883+
and FSharpAbstractSignature(cenv, info : SlotSig) =
884+
885+
member __.AbstractArguments =
886+
info.FormalParams
887+
|> List.map (List.map (fun p -> FSharpAbstractParameter(cenv, p)) >> makeReadOnlyCollection)
888+
|> makeReadOnlyCollection
889+
890+
member __.AbstractReturnType =
891+
match info.FormalReturnType with
892+
| None -> FSharpType(cenv, cenv.g.unit_ty)
893+
| Some ty -> FSharpType(cenv, ty)
894+
895+
member __.DeclaringTypeGenericParameters =
896+
info.ClassTypars
897+
|> List.map (fun t -> FSharpGenericParameter(cenv, t))
898+
|> makeReadOnlyCollection
899+
900+
member __.MethodGenericParameters =
901+
info.MethodTypars
902+
|> List.map (fun t -> FSharpGenericParameter(cenv, t))
903+
|> makeReadOnlyCollection
904+
905+
member __.Name = info.Name
906+
907+
member __.DeclaringType = FSharpType(cenv, info.ImplementedType)
908+
858909
and FSharpGenericParameterMemberConstraint(cenv, info : TraitConstraintInfo) =
859910
let (TTrait(tys,nm,flags,atys,rty,_)) = info
860911
member __.MemberSources =
@@ -1338,6 +1389,17 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
13381389
| M m -> m.IsFSharpExplicitInterfaceImplementation
13391390
| V v -> v.IsFSharpExplicitInterfaceImplementation cenv.g
13401391

1392+
member __.ImplementedAbstractSignatures =
1393+
checkIsResolved()
1394+
let sigs =
1395+
match d with
1396+
| E e -> e.GetAddMethod().ImplementedSlotSignatures
1397+
| P p -> p.ImplementedSlotSignatures
1398+
| M m -> m.ImplementedSlotSignatures
1399+
| V v -> v.ImplementedSlotSignatures
1400+
sigs |> List.map (fun s -> FSharpAbstractSignature (cenv, s))
1401+
|> makeReadOnlyCollection
1402+
13411403
member __.IsImplicitConstructor =
13421404
if isUnresolved() then false else
13431405
match fsharpInfo() with

src/fsharp/vs/Symbols.fsi

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,48 @@ and [<Class>] FSharpDelegateSignature =
289289
/// Get the return type of the delegate signature
290290
member DelegateReturnType : FSharpType
291291

292+
/// Represents a parameter in an abstract method of a class or interface
293+
and [<Class>] FSharpAbstractParameter =
294+
295+
/// The optional name of the parameter
296+
member Name : string option
297+
298+
/// The declared or inferred type of the parameter
299+
member Type : FSharpType
300+
301+
/// Indicate this is an in argument
302+
member IsInArg : bool
303+
304+
/// Indicate this is an out argument
305+
member IsOutArg : bool
306+
307+
/// Indicate this is an optional argument
308+
member IsOptionalArg : bool
309+
310+
/// The declared attributes of the parameter
311+
member Attributes : IList<FSharpAttribute>
312+
313+
/// Represents the signature of an abstract slot of a class or interface
314+
and [<Class>] FSharpAbstractSignature =
315+
316+
/// Get the arguments of the abstract slot
317+
member AbstractArguments : IList<IList<FSharpAbstractParameter>>
318+
319+
/// Get the return type of the abstract slot
320+
member AbstractReturnType : FSharpType
321+
322+
/// Get the generic arguments of the type defining the abstract slot
323+
member DeclaringTypeGenericParameters : IList<FSharpGenericParameter>
324+
325+
/// Get the generic arguments of the abstract slot
326+
member MethodGenericParameters : IList<FSharpGenericParameter>
327+
328+
/// Get the name of the abstract slot
329+
member Name : string
330+
331+
/// Get the declaring type of the abstract slot
332+
member DeclaringType : FSharpType
333+
292334
/// A subtype of FSharpSymbol that represents a union case as seen by the F# language
293335
and [<Class>] FSharpUnionCase =
294336
inherit FSharpSymbol
@@ -617,6 +659,9 @@ and [<Class>] FSharpMemberOrFunctionOrValue =
617659
/// Indicates if this is an explicit implementation of an interface member
618660
member IsExplicitInterfaceImplementation : bool
619661

662+
/// Gets the list of the abstract slot signatures implemented by the member
663+
member ImplementedAbstractSignatures : IList<FSharpAbstractSignature>
664+
620665
/// Indicates if this is a member, including extension members?
621666
member IsMember : bool
622667

tests/service/ProjectAnalysisTests.fs

Lines changed: 110 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4502,17 +4502,24 @@ module Project37 =
45024502

45034503
let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs")
45044504
let base2 = Path.GetTempFileName()
4505+
let fileName2 = Path.ChangeExtension(base2, ".fs")
45054506
let dllName = Path.ChangeExtension(base2, ".dll")
45064507
let projFileName = Path.ChangeExtension(base2, ".fsproj")
45074508
let fileSource1 = """
4508-
[<System.AttributeUsage(System.AttributeTargets.Method ||| System.AttributeTargets.Assembly)>]
4509+
namespace AttrTests
4510+
4511+
[<System.AttributeUsage(System.AttributeTargets.Method ||| System.AttributeTargets.Assembly) >]
45094512
type AttrTestAttribute() =
45104513
inherit System.Attribute()
45114514
45124515
new (t: System.Type) = AttrTestAttribute()
45134516
new (t: System.Type[]) = AttrTestAttribute()
45144517
new (t: int[]) = AttrTestAttribute()
45154518
4519+
[<System.AttributeUsage(System.AttributeTargets.Assembly) >]
4520+
type AttrTest2Attribute() =
4521+
inherit System.Attribute()
4522+
45164523
type TestUnion = | A of string
45174524
type TestRecord = { B : int }
45184525
@@ -4534,7 +4541,14 @@ module Test =
45344541
do ()
45354542
"""
45364543
File.WriteAllText(fileName1, fileSource1)
4537-
let fileNames = [fileName1]
4544+
let fileSource2 = """
4545+
namespace AttrTests
4546+
4547+
[<assembly: AttrTest2()>]
4548+
do ()
4549+
"""
4550+
File.WriteAllText(fileName2, fileSource2)
4551+
let fileNames = [fileName1; fileName2]
45384552
let args = mkProjectCommandLineArgs (dllName, fileNames)
45394553
let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args)
45404554
let wholeProjectResults =
@@ -4581,4 +4595,97 @@ let ``Test project37 typeof and arrays in attribute constructor arguments`` () =
45814595
| _ -> ()
45824596
Project37.wholeProjectResults.AssemblySignature.Attributes
45834597
|> Seq.map (fun a -> a.AttributeType.CompiledName)
4584-
|> Array.ofSeq |> shouldEqual [| "AttrTestAttribute" |]
4598+
|> Array.ofSeq |> shouldEqual [| "AttrTestAttribute"; "AttrTest2Attribute" |]
4599+
4600+
module Project38 =
4601+
open System.IO
4602+
4603+
let fileName1 = Path.ChangeExtension(Path.GetTempFileName(), ".fs")
4604+
let base2 = Path.GetTempFileName()
4605+
let dllName = Path.ChangeExtension(base2, ".dll")
4606+
let projFileName = Path.ChangeExtension(base2, ".fsproj")
4607+
let fileSource1 = """
4608+
namespace OverrideTests
4609+
4610+
type I<'X> =
4611+
abstract Method : unit -> unit
4612+
abstract Generic : named:'X -> unit
4613+
abstract Generic<'Y> : 'X * 'Y -> unit
4614+
abstract Property : int
4615+
4616+
[<AbstractClass>]
4617+
type B<'Y>() =
4618+
abstract Method : unit -> unit
4619+
abstract Generic : 'Y -> unit
4620+
abstract Property : int
4621+
[<CLIEvent>]
4622+
abstract Event : IEvent<unit>
4623+
4624+
type A<'XX, 'YY>() =
4625+
inherit B<'YY>()
4626+
4627+
let ev = Event<unit>()
4628+
4629+
override this.Method() = ()
4630+
override this.Generic (a: 'YY) = ()
4631+
override this.Property = 0
4632+
[<CLIEvent>]
4633+
override this.Event = ev.Publish
4634+
4635+
member this.NotOverride() = ()
4636+
4637+
interface I<'XX> with
4638+
member this.Method() = ()
4639+
member this.Generic (a: 'XX) = ()
4640+
member this.Generic<'Y> (a: 'XX, b: 'Y) = ()
4641+
member this.Property = 1
4642+
"""
4643+
File.WriteAllText(fileName1, fileSource1)
4644+
let fileNames = [fileName1]
4645+
let args = mkProjectCommandLineArgs (dllName, fileNames)
4646+
let options = checker.GetProjectOptionsFromCommandLineArgs (projFileName, args)
4647+
let wholeProjectResults =
4648+
checker.ParseAndCheckProject(options)
4649+
|> Async.RunSynchronously
4650+
4651+
[<Test>]
4652+
let ``Test project38 abstract slot information`` () =
4653+
let printAbstractSignature (s: FSharpAbstractSignature) =
4654+
let printType (t: FSharpType) = (string t).[5 ..]
4655+
let args =
4656+
(s.AbstractArguments |> Seq.concat |> Seq.map (fun a ->
4657+
(match a.Name with Some n -> n + ":" | _ -> "") + printType a.Type) |> String.concat " * ")
4658+
|> function "" -> "()" | a -> a
4659+
let tgen =
4660+
match s.DeclaringTypeGenericParameters |> Seq.map (fun m -> "'" + m.Name) |> String.concat "," with
4661+
| "" -> ""
4662+
| g -> " original generics: <" + g + ">"
4663+
let mgen =
4664+
match s.MethodGenericParameters |> Seq.map (fun m -> "'" + m.Name) |> String.concat "," with
4665+
| "" -> ""
4666+
| g -> "<" + g + ">"
4667+
"type " + printType s.DeclaringType + tgen + " with member " + s.Name + mgen + " : " + args + " -> " +
4668+
printType s.AbstractReturnType
4669+
4670+
let a2ent = Project38.wholeProjectResults.AssemblySignature.Entities |> Seq.find (fun e -> e.FullName = "OverrideTests.A`2")
4671+
a2ent.MembersFunctionsAndValues |> Seq.map (fun m ->
4672+
m.CompiledName, (m.ImplementedAbstractSignatures |> Seq.map printAbstractSignature |> List.ofSeq)
4673+
)
4674+
|> Array.ofSeq
4675+
|> shouldEqual
4676+
[|
4677+
".ctor", []
4678+
"Generic", ["type OverrideTests.B<'YY> original generics: <'Y> with member Generic : 'Y -> Microsoft.FSharp.Core.unit"]
4679+
"OverrideTests-I`1-Generic", ["type OverrideTests.I<'XX> original generics: <'X> with member Generic : named:'X -> Microsoft.FSharp.Core.unit"]
4680+
"OverrideTests-I`1-Generic", ["type OverrideTests.I<'XX> original generics: <'X> with member Generic<'Y> : 'X * 'Y -> Microsoft.FSharp.Core.unit"]
4681+
"Method", ["type OverrideTests.B<'YY> original generics: <'Y> with member Method : () -> Microsoft.FSharp.Core.unit"]
4682+
"OverrideTests-I`1-Method", ["type OverrideTests.I<'XX> original generics: <'X> with member Method : () -> Microsoft.FSharp.Core.unit"]
4683+
"NotOverride", []
4684+
"add_Event", ["type OverrideTests.B<'YY> original generics: <'Y> with member add_Event : Microsoft.FSharp.Control.Handler<Microsoft.FSharp.Core.unit> -> Microsoft.FSharp.Core.unit"]
4685+
"get_Event", ["type OverrideTests.B<'YY> with member get_Event : () -> Microsoft.FSharp.Core.unit"]
4686+
"get_Property", ["type OverrideTests.B<'YY> original generics: <'Y> with member get_Property : () -> Microsoft.FSharp.Core.int"]
4687+
"OverrideTests-I`1-get_Property", ["type OverrideTests.I<'XX> original generics: <'X> with member get_Property : () -> Microsoft.FSharp.Core.int"]
4688+
"remove_Event", ["type OverrideTests.B<'YY> original generics: <'Y> with member remove_Event : Microsoft.FSharp.Control.Handler<Microsoft.FSharp.Core.unit> -> Microsoft.FSharp.Core.unit"]
4689+
"get_Property", ["type OverrideTests.B<'YY> original generics: <'Y> with member get_Property : () -> Microsoft.FSharp.Core.int"]
4690+
"get_Event", ["type OverrideTests.B<'YY> with member get_Event : () -> Microsoft.FSharp.Core.unit"]
4691+
|]

0 commit comments

Comments
 (0)