@@ -26,15 +26,15 @@ open FSharp.Compiler.TypeHierarchy
2626open FSharp.Compiler .TypeRelations
2727
2828/// Use the given function to select some of the member values from the members of an F# type
29- let SelectImmediateMemberVals g optFilter f ( tcref : TyconRef ) =
29+ let SelectImmediateMemberVals g optFilter f withExplicitImpl ( tcref : TyconRef ) =
3030 let chooser ( vref : ValRef ) =
3131 match vref.MemberInfo with
3232 // The 'when' condition is a workaround for the fact that values providing
3333 // override and interface implementations are published in inferred module types
3434 // These cannot be selected directly via the "." notation.
3535 // However, it certainly is useful to be able to publish these values, as we can in theory
3636 // optimize code to make direct calls to these methods.
37- | Some membInfo when not ( ValRefIsExplicitImpl g vref) ->
37+ | Some membInfo when withExplicitImpl || not ( ValRefIsExplicitImpl g vref) ->
3838 f membInfo vref
3939 | _ ->
4040 None
@@ -53,7 +53,7 @@ let TrySelectMemberVal g optFilter ty pri _membInfo (vref: ValRef) =
5353 else
5454 None
5555
56- let rec GetImmediateIntrinsicMethInfosOfTypeAux ( optFilter , ad ) g amap m origTy metadataTy =
56+ let rec GetImmediateIntrinsicMethInfosOfTypeAux ( optFilter , ad ) g amap m withExplicitImpl origTy metadataTy =
5757
5858 let minfos =
5959 match metadataOfTy g metadataTy with
@@ -77,25 +77,28 @@ let rec GetImmediateIntrinsicMethInfosOfTypeAux (optFilter, ad) g amap m origTy
7777 // In this case convert to the .NET Tuple type that carries metadata and try again
7878 if isAnyTupleTy g metadataTy then
7979 let betterMetadataTy = convertToTypeWithMetadataIfPossible g metadataTy
80- GetImmediateIntrinsicMethInfosOfTypeAux ( optFilter, ad) g amap m origTy betterMetadataTy
80+ GetImmediateIntrinsicMethInfosOfTypeAux ( optFilter, ad) g amap m withExplicitImpl origTy betterMetadataTy
8181 // Function types support methods FSharpFunc<_, _>.FromConverter and friends from .NET metadata,
8282 // but not instance methods (you can't write "f.Invoke(x)", you have to write "f x")
8383 elif isFunTy g metadataTy then
8484 let betterMetadataTy = convertToTypeWithMetadataIfPossible g metadataTy
85- GetImmediateIntrinsicMethInfosOfTypeAux ( optFilter, ad) g amap m origTy betterMetadataTy
85+ GetImmediateIntrinsicMethInfosOfTypeAux ( optFilter, ad) g amap m withExplicitImpl origTy betterMetadataTy
8686 |> List.filter ( fun minfo -> not minfo.IsInstance)
8787 else
8888 match tryTcrefOfAppTy g metadataTy with
8989 | ValueNone -> []
9090 | ValueSome tcref ->
91- SelectImmediateMemberVals g optFilter ( TrySelectMemberVal g optFilter origTy None) tcref
91+ SelectImmediateMemberVals g optFilter ( TrySelectMemberVal g optFilter origTy None) withExplicitImpl tcref
9292 let minfos = minfos |> List.filter ( IsMethInfoAccessible amap m ad)
9393 minfos
9494
9595/// Query the immediate methods of an F# type, not taking into account inherited methods. The optFilter
9696/// parameter is an optional name to restrict the set of properties returned.
9797let GetImmediateIntrinsicMethInfosOfType ( optFilter , ad ) g amap m ty =
98- GetImmediateIntrinsicMethInfosOfTypeAux ( optFilter, ad) g amap m ty ty
98+ GetImmediateIntrinsicMethInfosOfTypeAux ( optFilter, ad) g amap m false ty ty
99+
100+ let GetImmediateIntrinsicMethInfosWithExplicitImplOfType ( optFilter , ad ) g amap m ty =
101+ GetImmediateIntrinsicMethInfosOfTypeAux ( optFilter, ad) g amap m true ty ty
99102
100103/// Query the immediate methods of an F# type, not taking into account inherited methods. The optFilter
101104/// parameter is an optional name to restrict the set of properties returned.
@@ -185,7 +188,7 @@ type PropertyCollector(g, amap, m, ty, optFilter, ad) =
185188
186189 member _.Close () = [ for KeyValue(_, pinfo) in props -> pinfo ]
187190
188- let rec GetImmediateIntrinsicPropInfosOfTypeAux ( optFilter , ad ) g amap m origTy metadataTy =
191+ let rec GetImmediateIntrinsicPropInfosOfTypeAux ( optFilter , ad ) g amap m withExplicitImpl origTy metadataTy =
189192
190193 let pinfos =
191194 match metadataOfTy g metadataTy with
@@ -216,22 +219,25 @@ let rec GetImmediateIntrinsicPropInfosOfTypeAux (optFilter, ad) g amap m origTy
216219 // In this case convert to the .NET Tuple type that carries metadata and try again
217220 if isAnyTupleTy g metadataTy || isFunTy g metadataTy then
218221 let betterMetadataTy = convertToTypeWithMetadataIfPossible g metadataTy
219- GetImmediateIntrinsicPropInfosOfTypeAux ( optFilter, ad) g amap m origTy betterMetadataTy
222+ GetImmediateIntrinsicPropInfosOfTypeAux ( optFilter, ad) g amap m withExplicitImpl origTy betterMetadataTy
220223 else
221224 match tryTcrefOfAppTy g metadataTy with
222225 | ValueNone -> []
223226 | ValueSome tcref ->
224227 let propCollector = PropertyCollector( g, amap, m, origTy, optFilter, ad)
225- SelectImmediateMemberVals g None ( fun membInfo vref -> propCollector.Collect( membInfo, vref); None) tcref |> ignore
228+ SelectImmediateMemberVals g None ( fun membInfo vref -> propCollector.Collect( membInfo, vref); None) withExplicitImpl tcref |> ignore
226229 propCollector.Close()
227230
228231 let pinfos = pinfos |> List.filter ( IsPropInfoAccessible g amap m ad)
229232 pinfos
230233
231234/// Query the immediate properties of an F# type, not taking into account inherited properties. The optFilter
232235/// parameter is an optional name to restrict the set of properties returned.
233- let rec GetImmediateIntrinsicPropInfosOfType ( optFilter , ad ) g amap m ty =
234- GetImmediateIntrinsicPropInfosOfTypeAux ( optFilter, ad) g amap m ty ty
236+ let GetImmediateIntrinsicPropInfosOfType ( optFilter , ad ) g amap m ty =
237+ GetImmediateIntrinsicPropInfosOfTypeAux ( optFilter, ad) g amap m false ty ty
238+
239+ let GetImmediateIntrinsicPropInfosWithExplicitImplOfType ( optFilter , ad ) g amap m ty =
240+ GetImmediateIntrinsicPropInfosOfTypeAux ( optFilter, ad) g amap m true ty ty
235241
236242// Checks whether the given type has an indexer property.
237243let IsIndexerType g amap ty =
@@ -655,6 +661,44 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) as this =
655661 PropInfosEquivByNameAndSig EraseNone g amap m,
656662 ( fun pinfo -> pinfo.PropertyName))
657663
664+ //type A() =
665+ // abstract E: int with get, set
666+ // default val E = 0 with get
667+ // Will get (A::E with get, A::E with get, set)
668+ // -----
669+ //type A() =
670+ // member val A = 0 with get, set
671+ //type B() =
672+ // inherit A()
673+ // static member val A = 0
674+ // Will get (static B::A, None)
675+ static let FilterOverridesOfPropInfosWithOverridenProp findFlag g amap m props =
676+ let checkProp prop prop2 =
677+ not ( obj.ReferenceEquals( prop, prop2)) &&
678+ PropInfosEquivByNameAndSig EraseNone g amap m prop prop2 &&
679+ if prop.HasGetter && prop.HasSetter then false
680+ elif prop.HasGetter then prop2.HasSetter
681+ elif prop.HasSetter then prop2.HasGetter
682+ else false
683+
684+ let rec findPropBefore prop hasMetTheProp =
685+ function
686+ | props :: t when hasMetTheProp ->
687+ match props |> List.tryFind ( checkProp prop) with
688+ | Some p -> ValueSome p
689+ | None -> findPropBefore prop true t
690+ | props :: t ->
691+ if props |> List.exists ( fun i -> obj.ReferenceEquals( prop, i)) then
692+ match props |> List.tryFind ( checkProp prop) with
693+ | Some p -> ValueSome p
694+ | None -> findPropBefore prop true t
695+ else findPropBefore prop false t
696+ | _ -> ValueNone
697+
698+ props
699+ |> FilterOverridesOfPropInfos findFlag g amap m
700+ |> List.map ( List.map ( fun prop -> struct ( prop, if findFlag = FindMemberFlag.IgnoreOverrides || prop.IsNewSlot then ValueNone else findPropBefore prop false props)))
701+
658702 /// Exclude methods from super types which have the same signature as a method in a more specific type.
659703 static let ExcludeHiddenOfMethInfosImpl g amap m ( minfos : MethInfo list list ) =
660704 minfos
@@ -905,6 +949,12 @@ type InfoReader(g: TcGlobals, amap: Import.ImportMap) as this =
905949 member infoReader.GetIntrinsicPropInfosOfType optFilter ad allowMultiIntfInst findFlag m ty =
906950 infoReader.GetIntrinsicPropInfoSetsOfType optFilter ad allowMultiIntfInst findFlag m ty |> List.concat
907951
952+ /// Get the flattened list of intrinsic properties in the hierarchy
953+ member infoReader.GetIntrinsicPropInfoWithOverriddenPropOfType optFilter ad allowMultiIntfInst findFlag m ty =
954+ infoReader.GetRawIntrinsicPropertySetsOfType( optFilter, ad, allowMultiIntfInst, m, ty)
955+ |> FilterOverridesOfPropInfosWithOverridenProp findFlag infoReader.g infoReader.amap m
956+ |> List.concat
957+
908958 member _.GetTraitInfosInType optFilter ty =
909959 GetImmediateTraitsInfosOfType optFilter g ty
910960
@@ -958,6 +1008,9 @@ let GetIntrinsicMethInfosOfType (infoReader: InfoReader) optFilter ad allowMulti
9581008let GetIntrinsicPropInfosOfType ( infoReader : InfoReader ) optFilter ad allowMultiIntfInst findFlag m ty =
9591009 infoReader.GetIntrinsicPropInfosOfType optFilter ad allowMultiIntfInst findFlag m ty
9601010
1011+ let GetIntrinsicPropInfoWithOverriddenPropOfType ( infoReader : InfoReader ) optFilter ad allowMultiIntfInst findFlag m ty =
1012+ infoReader.GetIntrinsicPropInfoWithOverriddenPropOfType optFilter ad allowMultiIntfInst findFlag m ty
1013+
9611014let TryFindIntrinsicNamedItemOfType ( infoReader : InfoReader ) ( nm , ad , includeConstraints ) findFlag m ty =
9621015 infoReader.TryFindIntrinsicNamedItemOfType ( nm, ad, includeConstraints) findFlag m ty
9631016
0 commit comments