Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Symbols: Add GenericArguments to FSharpEntity #16470

Merged
merged 4 commits into from
Feb 7, 2024
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
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/8.0.300.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* Name resolution: keep type vars in subsequent checks ([PR #16456](https://github.com/dotnet/fsharp/pull/16456))
* Higher-order-function-based API for working with the untyped abstract syntax tree. ([PR #16462](https://github.com/dotnet/fsharp/pull/16462))
* Allow returning bool instead of unit option for partial active patterns. ([Language suggestion #1041](https://github.com/fsharp/fslang-suggestions/issues/1041), [PR #16473](https://github.com/dotnet/fsharp/pull/16473))
* Symbols: Add GenericArguments to FSharpEntity ([PR #16470](https://github.com/dotnet/fsharp/pull/16470))

### Changed

Expand Down
12 changes: 6 additions & 6 deletions src/Compiler/Checking/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ type Item =
| Item.CtorGroup(nm, _) -> nm |> DemangleGenericTypeName
| Item.DelegateCtor ty ->
match ty with
| AbbrevOrAppTy tcref -> tcref.DisplayNameCore
| AbbrevOrAppTy(tcref, _) -> tcref.DisplayNameCore
// This case is not expected
| _ -> ""
| Item.UnqualifiedType(tcref :: _) -> tcref.DisplayNameCore
Expand Down Expand Up @@ -309,7 +309,7 @@ type Item =
| Item.Property(info = pinfo :: _) -> pinfo.DisplayName
| Item.Event einfo -> einfo.DisplayName
| Item.MethodGroup(_, minfo :: _, _) -> minfo.DisplayName
| Item.DelegateCtor (AbbrevOrAppTy tcref) -> tcref.DisplayName
| Item.DelegateCtor (AbbrevOrAppTy(tcref, _)) -> tcref.DisplayName
| Item.UnqualifiedType(tcref :: _) -> tcref.DisplayName
| Item.ModuleOrNamespaces(modref :: _) -> modref.DisplayName
| Item.TypeVar (nm, _) -> nm |> ConvertLogicalNameToDisplayName
Expand Down Expand Up @@ -1872,11 +1872,11 @@ let (|EntityUse|_|) (item: Item) =
match item with
| Item.UnqualifiedType (tcref :: _) -> ValueSome tcref
| Item.ExnCase tcref -> ValueSome tcref
| Item.Types(_, [AbbrevOrAppTy tcref])
| Item.DelegateCtor(AbbrevOrAppTy tcref) -> ValueSome tcref
| Item.Types(_, [AbbrevOrAppTy(tcref, _)])
| Item.DelegateCtor(AbbrevOrAppTy(tcref, _)) -> ValueSome tcref
| Item.CtorGroup(_, ctor :: _) ->
match ctor.ApparentEnclosingType with
| AbbrevOrAppTy tcref -> ValueSome tcref
| AbbrevOrAppTy(tcref, _) -> ValueSome tcref
| _ -> ValueNone
| _ -> ValueNone

Expand Down Expand Up @@ -1958,7 +1958,7 @@ let ItemsAreEffectivelyEqual g orig other =
not tp1.IsCompilerGenerated && not tp1.IsFromError &&
not tp2.IsCompilerGenerated && not tp2.IsFromError &&
equals tp1.Range tp2.Range
| AbbrevOrAppTy tcref1, AbbrevOrAppTy tcref2 ->
| AbbrevOrAppTy(tcref1, _), AbbrevOrAppTy(tcref2, _) ->
tyconRefDefnEq g tcref1 tcref2
| _ -> false)

Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Checking/infos.fs
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ type MethInfo =
member x.DebuggerDisplayName =
match x with
| ILMeth(_, y, _) -> y.DeclaringTyconRef.DisplayNameWithStaticParametersAndUnderscoreTypars + "::" + y.ILName
| FSMeth(_, AbbrevOrAppTy tcref, vref, _) -> tcref.DisplayNameWithStaticParametersAndUnderscoreTypars + "::" + vref.LogicalName
| FSMeth(_, AbbrevOrAppTy(tcref, _), vref, _) -> tcref.DisplayNameWithStaticParametersAndUnderscoreTypars + "::" + vref.LogicalName
| FSMeth(_, _, vref, _) -> "??::" + vref.LogicalName
#if !NO_TYPEPROVIDERS
| ProvidedMeth(_, mi, _, m) -> "ProvidedMeth: " + mi.PUntaint((fun mi -> mi.Name), m)
Expand Down
8 changes: 4 additions & 4 deletions src/Compiler/Service/FSharpCheckerResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1805,9 +1805,9 @@ type internal TypeCheckInfo
|> List.sortBy (fun d ->
let n =
match d.Item with
| Item.Types(_, AbbrevOrAppTy tcref :: _) -> 1 + tcref.TyparsNoRange.Length
| Item.Types(_, AbbrevOrAppTy(tcref, _) :: _) -> 1 + tcref.TyparsNoRange.Length
// Put delegate ctors after types, sorted by #typars. RemoveDuplicateItems will remove FakeInterfaceCtor and DelegateCtor if an earlier type is also reported with this name
| Item.DelegateCtor(AbbrevOrAppTy tcref) -> 1000 + tcref.TyparsNoRange.Length
| Item.DelegateCtor(AbbrevOrAppTy(tcref, _)) -> 1000 + tcref.TyparsNoRange.Length
// Put type ctors after types, sorted by #typars. RemoveDuplicateItems will remove DefaultStructCtors if a type is also reported with this name
| Item.CtorGroup(_, cinfo :: _) -> 1000 + 10 * cinfo.DeclaringTyconRef.TyparsNoRange.Length
| _ -> 0
Expand All @@ -1823,10 +1823,10 @@ type internal TypeCheckInfo
items
|> List.groupBy (fun d ->
match d.Item with
| Item.Types(_, AbbrevOrAppTy tcref :: _)
| Item.Types(_, AbbrevOrAppTy(tcref, _) :: _)
| Item.ExnCase tcref -> tcref.LogicalName
| Item.UnqualifiedType(tcref :: _)
| Item.DelegateCtor(AbbrevOrAppTy tcref) -> tcref.CompiledName
| Item.DelegateCtor(AbbrevOrAppTy(tcref, _)) -> tcref.CompiledName
| Item.CtorGroup(_, cinfo :: _) -> cinfo.ApparentEnclosingTyconRef.CompiledName
| _ -> d.Item.DisplayName)

Expand Down
8 changes: 4 additions & 4 deletions src/Compiler/Symbols/SymbolHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ module internal SymbolHelpers =
| Item.DelegateCtor ty
| Item.Types(_, ty :: _) ->
match ty with
| AbbrevOrAppTy tcref ->
| AbbrevOrAppTy(tcref, _) ->
mkXmlComment (GetXmlDocSigOfEntityRef infoReader m tcref)
| _ -> FSharpXmlDoc.None

Expand Down Expand Up @@ -462,8 +462,8 @@ module internal SymbolHelpers =
| Item.UnqualifiedType tcrefs1, Item.UnqualifiedType tcrefs2 ->
(tcrefs1, tcrefs2)
||> List.forall2 (fun tcref1 tcref2 -> tyconRefEq g tcref1 tcref2)
| Item.Types(_, [AbbrevOrAppTy tcref1]), Item.UnqualifiedType([tcref2]) -> tyconRefEq g tcref1 tcref2
| Item.UnqualifiedType([tcref1]), Item.Types(_, [AbbrevOrAppTy tcref2]) -> tyconRefEq g tcref1 tcref2
| Item.Types(_, [AbbrevOrAppTy(tcref1, _)]), Item.UnqualifiedType([tcref2]) -> tyconRefEq g tcref1 tcref2
| Item.UnqualifiedType([tcref1]), Item.Types(_, [AbbrevOrAppTy(tcref2, _)]) -> tyconRefEq g tcref1 tcref2
| _ -> false)

member x.GetHashCode item =
Expand Down Expand Up @@ -648,7 +648,7 @@ module internal SymbolHelpers =
| Item.Types(_, tys) ->
let doc =
match tys with
| AbbrevOrAppTy tcref :: _ ->
| AbbrevOrAppTy(tcref, _) :: _ ->
if tyconRefUsesLocalXmlDoc g.compilingFSharpCore tcref || tcref.XmlDoc.NonEmpty then
Some tcref.XmlDoc
else
Expand Down
40 changes: 26 additions & 14 deletions src/Compiler/Symbols/Symbols.fs
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,12 @@ type FSharpSymbol(cenv: SymbolEnv, item: unit -> Item, access: FSharpSymbol -> C
| Item.CtorGroup(_, cinfo :: _) ->
FSharpMemberOrFunctionOrValue(cenv, C cinfo, item) :> _

| Item.DelegateCtor (AbbrevOrAppTy tcref) ->
FSharpEntity(cenv, tcref) :>_
| Item.DelegateCtor (AbbrevOrAppTy(tcref, tyargs))
| Item.Types(_, AbbrevOrAppTy(tcref, tyargs) :: _) ->
FSharpEntity(cenv, tcref, tyargs) :>_

| Item.UnqualifiedType(tcref :: _)
| Item.Types(_, AbbrevOrAppTy tcref :: _) ->
FSharpEntity(cenv, tcref) :>_
| Item.UnqualifiedType(tcref :: _) ->
FSharpEntity(cenv, tcref) :> _

| Item.ModuleOrNamespaces(modref :: _) ->
FSharpEntity(cenv, modref) :> _
Expand Down Expand Up @@ -355,7 +355,7 @@ type FSharpSymbol(cenv: SymbolEnv, item: unit -> Item, access: FSharpSymbol -> C
member sym.TryGetAttribute<'T>() =
sym.Attributes |> Seq.tryFind (fun attr -> attr.IsAttribute<'T>())

type FSharpEntity(cenv: SymbolEnv, entity: EntityRef) =
type FSharpEntity(cenv: SymbolEnv, entity: EntityRef, tyargs: TType list) =
inherit FSharpSymbol(cenv,
(fun () ->
checkEntityIsResolved entity
Expand Down Expand Up @@ -383,6 +383,10 @@ type FSharpEntity(cenv: SymbolEnv, entity: EntityRef) =
| None -> false
| Some ccu -> ccuEq ccu cenv.g.fslibCcu

new(cenv: SymbolEnv, tcref: TyconRef) =
let _, _, tyargs = FreshenTypeInst cenv.g range0 (tcref.Typars range0)
FSharpEntity(cenv, tcref, tyargs)

member _.Entity = entity

member _.LogicalName =
Expand Down Expand Up @@ -480,6 +484,10 @@ type FSharpEntity(cenv: SymbolEnv, entity: EntityRef) =
checkIsResolved()
entity.TyparsNoRange |> List.map (fun tp -> FSharpGenericParameter(cenv, tp)) |> makeReadOnlyCollection

member _.GenericArguments =
checkIsResolved()
tyargs |> List.map (fun ty -> FSharpType(cenv, ty)) |> makeReadOnlyCollection

member _.IsMeasure =
isResolvedAndFSharp() && (entity.TypeOrMeasureKind = TyparKind.Measure)

Expand Down Expand Up @@ -718,7 +726,7 @@ type FSharpEntity(cenv: SymbolEnv, entity: EntityRef) =
if isUnresolved() then makeReadOnlyCollection [] else
entity.ModuleOrNamespaceType.AllEntities
|> QueueList.toList
|> List.map (fun x -> FSharpEntity(cenv, entity.NestedTyconRef x))
|> List.map (fun x -> FSharpEntity(cenv, entity.NestedTyconRef x, tyargs))
|> makeReadOnlyCollection

member _.UnionCases =
Expand Down Expand Up @@ -1688,7 +1696,7 @@ type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
| Some v -> v
| None -> failwith "DeclarationLocation property not available"

member _.DeclaringEntity =
member _.DeclaringEntity: FSharpEntity option =
checkIsResolved()
match d with
| E e -> FSharpEntity(cenv, e.DeclaringTyconRef) |> Some
Expand All @@ -1699,12 +1707,16 @@ type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
| ParentNone -> None
| Parent p -> FSharpEntity(cenv, p) |> Some

member _.ApparentEnclosingEntity =
member _.ApparentEnclosingEntity: FSharpEntity =
let createEntity (ttype: TType) =
let tcref, tyargs = destAppTy cenv.g ttype
FSharpEntity(cenv, tcref, tyargs)

checkIsResolved()
match d with
| E e -> FSharpEntity(cenv, e.ApparentEnclosingTyconRef)
| P p -> FSharpEntity(cenv, p.ApparentEnclosingTyconRef)
| M m | C m -> FSharpEntity(cenv, m.ApparentEnclosingTyconRef)
| E e -> createEntity e.ApparentEnclosingType
| P p -> createEntity p.ApparentEnclosingType
| M m | C m -> createEntity m.ApparentEnclosingType
| V v ->
match v.ApparentEnclosingEntity with
| ParentNone -> invalidOp "the value or member doesn't have a logical parent"
Expand Down Expand Up @@ -2453,7 +2465,7 @@ type FSharpType(cenv, ty:TType) =
let isUnresolved() =
DiagnosticsLogger.protectAssemblyExploration true <| fun () ->
match stripTyparEqns ty with
| TType_app (tcref, _, _) -> FSharpEntity(cenv, tcref).IsUnresolved
| TType_app (tcref, tyargs, _) -> FSharpEntity(cenv, tcref, tyargs).IsUnresolved
| TType_measure (Measure.Const tcref) -> FSharpEntity(cenv, tcref).IsUnresolved
| TType_measure (Measure.Prod _) -> FSharpEntity(cenv, cenv.g.measureproduct_tcr).IsUnresolved
| TType_measure Measure.One -> FSharpEntity(cenv, cenv.g.measureone_tcr).IsUnresolved
Expand Down Expand Up @@ -2497,7 +2509,7 @@ type FSharpType(cenv, ty:TType) =
member _.TypeDefinition =
protect <| fun () ->
match stripTyparEqns ty with
| TType_app (tcref, _, _) -> FSharpEntity(cenv, tcref)
| TType_app (tcref, tyargs, _) -> FSharpEntity(cenv, tcref, tyargs)
| TType_measure (Measure.Const tcref) -> FSharpEntity(cenv, tcref)
| TType_measure (Measure.Prod _) -> FSharpEntity(cenv, cenv.g.measureproduct_tcr)
| TType_measure Measure.One -> FSharpEntity(cenv, cenv.g.measureone_tcr)
Expand Down
4 changes: 4 additions & 0 deletions src/Compiler/Symbols/Symbols.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ type FSharpEntity =

/// Get the generic parameters, possibly including unit-of-measure parameters
member GenericParameters: IList<FSharpGenericParameter>

/// Get the generic parameters, possibly including unit-of-measure parameters
member GenericArguments: IList<FSharpType>

#if !NO_TYPEPROVIDERS
/// Get the static parameters for a provided type
member StaticParameters: IList<FSharpStaticParameter>
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/TypedTree/TypedTreeBasics.fs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ let stripUnitEqns unt = stripUnitEqnsAux false unt
/// Detect a use of a nominal type, including type abbreviations.
let (|AbbrevOrAppTy|_|) (ty: TType) =
match stripTyparEqns ty with
| TType_app (tcref, _, _) -> Some tcref
| TType_app (tcref, tinst, _) -> Some(tcref, tinst)
| _ -> None

//---------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/TypedTree/TypedTreeBasics.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ val stripTyparEqns: ty: TType -> TType
val stripUnitEqns: unt: Measure -> Measure

/// Detect a use of a nominal type, including type abbreviations.
val (|AbbrevOrAppTy|_|): ty: TType -> TyconRef option
val (|AbbrevOrAppTy|_|): ty: TType -> (TyconRef * TypeInst) option

val mkLocalValRef: v: Val -> ValRef

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4868,8 +4868,10 @@ FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpStaticParameter] get_StaticParameters()
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] AllInterfaces
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] DeclaredInterfaces
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] GenericArguments
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] get_AllInterfaces()
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] get_DeclaredInterfaces()
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] get_GenericArguments()
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpUnionCase] UnionCases
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpUnionCase] get_UnionCases()
FSharp.Compiler.Symbols.FSharpEntity: System.String AccessPath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4868,8 +4868,10 @@ FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpStaticParameter] get_StaticParameters()
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] AllInterfaces
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] DeclaredInterfaces
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] GenericArguments
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] get_AllInterfaces()
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] get_DeclaredInterfaces()
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] get_GenericArguments()
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpUnionCase] UnionCases
FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpUnionCase] get_UnionCases()
FSharp.Compiler.Symbols.FSharpEntity: System.String AccessPath
Expand Down
19 changes: 15 additions & 4 deletions tests/service/Symbols.fs
Original file line number Diff line number Diff line change
Expand Up @@ -327,15 +327,16 @@ open System
findSymbolUseByName "IDisposable" checkResults |> ignore


[<Test; Explicit>]
[<Test>]
let ``Interface 04 - Type arg`` () =
let _, checkResults = getParseAndCheckResults """
open System.Collections.Generic
IList<int>
"""
let symbolUse = findSymbolUseByName "IList`1" checkResults
let _, typeArg = symbolUse.GenericArguments[0]
let symbol = symbolUse.Symbol :?> FSharpEntity
let typeArg = symbol.GenericArguments[0]
typeArg.Format(symbolUse.DisplayContext) |> shouldEqual "int"

[<Test>]
Expand All @@ -351,7 +352,8 @@ type I<'T> =
getSymbolUses checkResults
|> Seq.findBack (fun symbolUse -> symbolUse.Symbol.DisplayName = "I")

let _, typeArg = symbolUse.GenericArguments[0]
let symbol = symbolUse.Symbol :?> FSharpEntity
let typeArg = symbol.GenericArguments[0]
typeArg.Format(symbolUse.DisplayContext) |> shouldEqual "int"

[<Test>]
Expand All @@ -367,9 +369,18 @@ type I<'T> =
getSymbolUses checkResults
|> Seq.findBack (fun symbolUse -> symbolUse.Symbol.DisplayName = "I")

let _, typeArg = symbolUse.GenericArguments[0]
let symbol = symbolUse.Symbol :?> FSharpEntity
let typeArg = symbol.GenericArguments[0]
typeArg.Format(symbolUse.DisplayContext) |> shouldEqual "int"

[<Test>]
let ``Operator 01 - Type arg`` () =
let _, checkResults = getParseAndCheckResults """
[1] |> ignore
"""
let symbolUses = checkResults.GetAllUsesOfAllSymbolsInFile()
()

[<Test>]
let ``FSharpType.Format can use prefix representations`` () =
let _, checkResults = getParseAndCheckResults """
Expand Down
Loading