Skip to content

Commit b27c211

Browse files
committed
fix 423, fix 235
1 parent 0334812 commit b27c211

File tree

4 files changed

+92
-38
lines changed

4 files changed

+92
-38
lines changed

src/fsharp/vs/Symbols.fs

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,9 +1115,37 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
11151115
| P m ->
11161116
let minfo = m.GetterMethod
11171117
FSharpMemberOrFunctionOrValue(cenv, M minfo, Item.MethodGroup (minfo.DisplayName,[minfo]))
1118-
| E _
1119-
| M _
1120-
| V _ -> invalidOp "the value or member doesn't have an associated getter method"
1118+
| E _ | M _ | V _ -> invalidOp "the value or member doesn't have an associated getter method"
1119+
1120+
member __.EventAddMethod =
1121+
checkIsResolved()
1122+
match d with
1123+
| E e ->
1124+
let minfo = e.GetAddMethod()
1125+
FSharpMemberOrFunctionOrValue(cenv, M minfo, Item.MethodGroup (minfo.DisplayName,[minfo]))
1126+
| P _ | M _ | V _ -> invalidOp "the value or member doesn't have an associated add method"
1127+
1128+
member __.EventRemoveMethod =
1129+
checkIsResolved()
1130+
match d with
1131+
| E e ->
1132+
let minfo = e.GetRemoveMethod()
1133+
FSharpMemberOrFunctionOrValue(cenv, M minfo, Item.MethodGroup (minfo.DisplayName,[minfo]))
1134+
| P _ | M _ | V _ -> invalidOp "the value or member doesn't have an associated remove method"
1135+
1136+
member __.EventDelegateType =
1137+
checkIsResolved()
1138+
match d with
1139+
| E e -> FSharpType(cenv, e.GetDelegateType(cenv.amap,range0))
1140+
| P _ | M _ | V _ -> invalidOp "the value or member doesn't have an associated event delegate type"
1141+
1142+
member __.EventIsStandard =
1143+
checkIsResolved()
1144+
match d with
1145+
| E e ->
1146+
let dty = e.GetDelegateType(cenv.amap,range0)
1147+
TryDestStandardDelegateTyp cenv.infoReader range0 AccessibleFromSomewhere dty |> isSome
1148+
| P _ | M _ | V _ -> invalidOp "the value or member is not an event"
11211149

11221150
member __.HasSetterMethod =
11231151
if isUnresolved() then false
@@ -1446,9 +1474,15 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
14461474
| E e ->
14471475
// INCOMPLETENESS: Attribs is empty here, so we can't look at return attributes for .NET or F# methods
14481476
let retInfo : ArgReprInfo = { Name=None; Attribs= [] }
1449-
let rty = PropTypOfEventInfo cenv.infoReader range0 AccessibleFromSomewhere e
1450-
let _,rty, _cxs = PrettyTypes.PrettifyTypes1 cenv.g rty
1477+
let rty =
1478+
try PropTypOfEventInfo cenv.infoReader range0 AccessibleFromSomewhere e
1479+
with _ ->
1480+
// For non-standard events, just use the delegate type as the ReturnParameter type
1481+
e.GetDelegateType(cenv.amap,range0)
1482+
1483+
let _, rty, _cxs = PrettyTypes.PrettifyTypes1 cenv.g rty
14511484
FSharpParameter(cenv, rty, retInfo, x.DeclarationLocationOpt, isParamArrayArg=false, isOutArg=false, isOptionalArg=false)
1485+
14521486
| P p ->
14531487
// INCOMPLETENESS: Attribs is empty here, so we can't look at return attributes for .NET or F# methods
14541488
let retInfo : ArgReprInfo = { Name=None; Attribs= [] }
@@ -1815,7 +1849,7 @@ and FSharpParameter(cenv, typ:TType, topArgInfo:ArgReprInfo, mOpt, isParamArrayA
18151849

18161850
and FSharpAssemblySignature internal (cenv, topAttribs: TypeChecker.TopAttribs option, mtyp: ModuleOrNamespaceType) =
18171851

1818-
new (g, thisCcu, tcImports, topAttribs, mtyp) = FSharpAssemblySignature(cenv(g,thisCcu,tcImports), topAttribs, mtyp)
1852+
new (g, thisCcu, tcImports, topAttribs, mtyp) = FSharpAssemblySignature(cenv(g, thisCcu, tcImports), topAttribs, mtyp)
18191853

18201854
member __.Entities =
18211855

@@ -1824,7 +1858,11 @@ and FSharpAssemblySignature internal (cenv, topAttribs: TypeChecker.TopAttribs o
18241858
if entity.IsNamespace then
18251859
yield! loop entity.ModuleOrNamespaceType
18261860
else
1827-
yield FSharpEntity(cenv, mkLocalEntityRef entity) |]
1861+
let entityRef =
1862+
match tryRescopeEntity cenv.thisCcu entity with
1863+
| None -> mkLocalEntityRef entity
1864+
| Some eref -> eref
1865+
yield FSharpEntity(cenv, entityRef) |]
18281866

18291867
loop mtyp |> makeReadOnlyCollection
18301868

@@ -1839,7 +1877,7 @@ and FSharpAssemblySignature internal (cenv, topAttribs: TypeChecker.TopAttribs o
18391877

18401878
and FSharpAssembly internal (cenv, ccu: CcuThunk) =
18411879

1842-
new (g, thisCcu, tcImports, ccu) = FSharpAssembly(cenv(g,thisCcu,tcImports), ccu)
1880+
new (g, tcImports, ccu) = FSharpAssembly(cenv(g, ccu, tcImports), ccu)
18431881

18441882
member __.RawCcuThunk = ccu
18451883
member __.QualifiedName = match ccu.QualifiedName with None -> "" | Some s -> s

src/fsharp/vs/Symbols.fsi

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ type [<Class>] FSharpSymbol =
8080
/// Represents an assembly as seen by the F# language
8181
and [<Class>] FSharpAssembly =
8282

83-
internal new : tcGlobals: TcGlobals * thisCcu: CcuThunk * tcImports: TcImports * ccu: CcuThunk -> FSharpAssembly
83+
internal new : tcGlobals: TcGlobals * tcImports: TcImports * ccu: CcuThunk -> FSharpAssembly
8484

8585
/// The qualified name of the assembly
8686
member QualifiedName: string
@@ -623,18 +623,32 @@ and [<Class>] FSharpMemberOrFunctionOrValue =
623623
/// Indicates if this is a property member
624624
member IsProperty : bool
625625

626-
/// Indicates if this is a property then there exists an associated getter method
626+
/// Indicates if this is a property and there exists an associated getter method
627627
member HasGetterMethod : bool
628628

629629
/// Get an associated getter method of the property
630630
member GetterMethod : FSharpMemberOrFunctionOrValue
631631

632-
/// Indicates if this is a property then there exists an associated setter method
632+
/// Indicates if this is a property and there exists an associated setter method
633633
member HasSetterMethod : bool
634634

635635
/// Get an associated setter method of the property
636636
member SetterMethod : FSharpMemberOrFunctionOrValue
637637

638+
/// Get an associated add method of an event
639+
member EventAddMethod : FSharpMemberOrFunctionOrValue
640+
641+
/// Get an associated remove method of an event
642+
member EventRemoveMethod : FSharpMemberOrFunctionOrValue
643+
644+
/// Get an associated delegate type of an event
645+
member EventDelegateType : FSharpType
646+
647+
/// Indicate if an event can be considered to be a property for the F# type system of type IEvent or IDelegateEvent.
648+
/// In this case ReturnParameter will have a type corresponding to the property type. For
649+
/// non-standard events, ReturnParameter will have a type corresponding to the delegate type.
650+
member EventIsStandard: bool
651+
638652
/// Indicates if this is an event member
639653
member IsEvent : bool
640654

src/fsharp/vs/service.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,7 +1473,7 @@ type TypeCheckInfo
14731473

14741474
member scope.GetReferencedAssemblies() =
14751475
[ for x in tcImports.GetImportedAssemblies() do
1476-
yield FSharpAssembly(g, thisCcu, tcImports, x.FSharpViewOfMetadata) ]
1476+
yield FSharpAssembly(g, tcImports, x.FSharpViewOfMetadata) ]
14771477

14781478
// Not, this does not have to be a SyncOp, it can be called from any thread
14791479
member scope.GetFormatSpecifierLocations() =
@@ -1928,7 +1928,7 @@ type FSharpCheckProjectResults(keepAssemblyContents, errors: FSharpErrorInfo[],
19281928
let (tcGlobals, tcImports, thisCcu, _ccuSig, _tcSymbolUses, _topAttribs, _tcAssemblyData, _ilAssemRef, ad, _tcAssemblyExpr) = getDetails()
19291929
let assemblies =
19301930
[ for x in tcImports.GetImportedAssemblies() do
1931-
yield FSharpAssembly(tcGlobals, thisCcu, tcImports, x.FSharpViewOfMetadata) ]
1931+
yield FSharpAssembly(tcGlobals, tcImports, x.FSharpViewOfMetadata) ]
19321932
FSharpProjectContext(thisCcu, assemblies, ad)
19331933

19341934
member info.RawFSharpAssemblyData =

tests/service/CSharpProjectAnalysis.fs

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -65,33 +65,35 @@ let ``Test that csharp references are recognized as such`` () =
6565
let csharpAssembly = typeof<CSharpClass>.Assembly.Location
6666
let _, table = getProjectReferences("""module M""", [csharpAssembly], None, None)
6767
let ass = table.["CSharp_Analysis"]
68-
match ass.Contents.Entities |> Seq.tryFind (fun e -> e.DisplayName = "CSharpClass") with
69-
| Some found ->
70-
// this is no F# thing
71-
found.IsFSharp |> shouldEqual false
68+
let search = ass.Contents.Entities |> Seq.tryFind (fun e -> e.DisplayName = "CSharpClass")
69+
Assert.True search.IsSome
70+
let found = search.Value
71+
// this is no F# thing
72+
found.IsFSharp |> shouldEqual false
7273

73-
// Check that we have members
74-
let members = found.MembersFunctionsAndValues |> Seq.map (fun e -> e.CompiledName, e) |> dict
75-
members.ContainsKey ".ctor" |> shouldEqual true
76-
members.ContainsKey "Method" |> shouldEqual true
77-
members.ContainsKey "Property" |> shouldEqual true
78-
members.ContainsKey "Event" |> shouldEqual true
79-
members.ContainsKey "InterfaceMethod" |> shouldEqual true
80-
members.ContainsKey "InterfaceProperty" |> shouldEqual true
81-
members.ContainsKey "InterfaceEvent" |> shouldEqual true
74+
// Check that we have members
75+
let members = found.MembersFunctionsAndValues |> Seq.map (fun e -> e.CompiledName, e) |> dict
76+
members.ContainsKey ".ctor" |> shouldEqual true
77+
members.ContainsKey "Method" |> shouldEqual true
78+
members.ContainsKey "Property" |> shouldEqual true
79+
members.ContainsKey "Event" |> shouldEqual true
80+
members.ContainsKey "InterfaceMethod" |> shouldEqual true
81+
members.ContainsKey "InterfaceProperty" |> shouldEqual true
82+
members.ContainsKey "InterfaceEvent" |> shouldEqual true
83+
members.["Event"].IsEvent |> shouldEqual true
84+
members.["Event"].EventIsStandard |> shouldEqual true
85+
members.["Event"].EventAddMethod.DisplayName |> shouldEqual "add_Event"
86+
members.["Event"].EventRemoveMethod.DisplayName |> shouldEqual "remove_Event"
87+
members.["Event"].EventDelegateType.ToString() |> shouldEqual "type System.EventHandler"
8288

83-
//// Check that we get xml docs
84-
//String.IsNullOrWhiteSpace(members.[".ctor"].XmlDocSig) |> shouldEqual false
85-
//String.IsNullOrWhiteSpace(members.["Method"].XmlDocSig) |> shouldEqual false
86-
//String.IsNullOrWhiteSpace(members.["Property"].XmlDocSig) |> shouldEqual false
87-
//String.IsNullOrWhiteSpace(members.["Event"].XmlDocSig) |> shouldEqual false
88-
//String.IsNullOrWhiteSpace(members.["InterfaceMethod"].XmlDocSig) |> shouldEqual false
89-
//String.IsNullOrWhiteSpace(members.["InterfaceProperty"].XmlDocSig) |> shouldEqual false
90-
//String.IsNullOrWhiteSpace(members.["InterfaceEvent"].XmlDocSig) |> shouldEqual false
91-
92-
()
93-
| None ->
94-
Assert.Fail ("CSharpClass was not found in CSharp_Analysis assembly!")
89+
//// Check that we get xml docs
90+
members.[".ctor"].XmlDocSig |> shouldEqual "M:FSharp.Compiler.Service.Tests.CSharpClass.#ctor(System.Int32,System.String)"
91+
members.["Method"].XmlDocSig |> shouldEqual "M:FSharp.Compiler.Service.Tests.CSharpClass.Method(System.String)"
92+
members.["Property"].XmlDocSig |> shouldEqual "P:FSharp.Compiler.Service.Tests.CSharpClass.Property"
93+
members.["Event"].XmlDocSig |> shouldEqual "E:FSharp.Compiler.Service.Tests.CSharpClass.Event"
94+
members.["InterfaceMethod"].XmlDocSig |> shouldEqual "M:FSharp.Compiler.Service.Tests.CSharpClass.InterfaceMethod(System.String)"
95+
members.["InterfaceProperty"].XmlDocSig |> shouldEqual "P:FSharp.Compiler.Service.Tests.CSharpClass.InterfaceProperty"
96+
members.["InterfaceEvent"].XmlDocSig |> shouldEqual "E:FSharp.Compiler.Service.Tests.CSharpClass.InterfaceEvent"
9597

9698
[<Test>]
9799
let ``Test that symbols of csharp inner classes/enums are reported`` () =

0 commit comments

Comments
 (0)