diff --git a/docs/release-notes/.FSharp.Compiler.Service/10.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/10.0.300.md index 471abbfb98..772deb8618 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/10.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/10.0.300.md @@ -19,5 +19,7 @@ ### Changed * Centralized product TFM (Target Framework Moniker) into MSBuild props file `eng/TargetFrameworks.props`. Changing the target framework now only requires editing one file, and it integrates with MSBuild's `--getProperty` for scripts. +* Symbols: safer qualified name getting ([PR #19298](https://github.com/dotnet/fsharp/pull/19298)) + ### Breaking Changes diff --git a/src/Compiler/Symbols/Symbols.fs b/src/Compiler/Symbols/Symbols.fs index 6a234db702..d7db3ecd19 100644 --- a/src/Compiler/Symbols/Symbols.fs +++ b/src/Compiler/Symbols/Symbols.fs @@ -442,25 +442,22 @@ type FSharpEntity(cenv: SymbolEnv, entity: EntityRef, tyargs: TType list) = | Some _ -> None member x.CompiledRepresentation = - checkIsResolved() - - let fail () = - invalidOp $"the type '{x.LogicalName}' does not have a qualified name" + if isUnresolved () then None else #if !NO_TYPEPROVIDERS - if entity.IsTypeAbbrev || entity.IsProvidedErasedTycon || entity.IsNamespace then fail () + if entity.IsTypeAbbrev || entity.IsProvidedErasedTycon || entity.IsNamespace then None else #else - if entity.IsTypeAbbrev || entity.IsNamespace then fail () + if entity.IsTypeAbbrev || entity.IsNamespace then None else #endif match entity.CompiledRepresentation with - | CompiledTypeRepr.ILAsmNamed(tref, _, _) -> tref - | CompiledTypeRepr.ILAsmOpen _ -> fail () + | CompiledTypeRepr.ILAsmNamed(tref, _, _) -> Some tref + | CompiledTypeRepr.ILAsmOpen _ -> None member x.QualifiedName = - x.CompiledRepresentation.QualifiedName + x.CompiledRepresentation |> Option.map _.QualifiedName member x.BasicQualifiedName = - x.CompiledRepresentation.BasicQualifiedName + x.CompiledRepresentation |> Option.map _.BasicQualifiedName member x.FullName = checkIsResolved() @@ -2683,16 +2680,13 @@ type FSharpType(cenv, ty:TType) = FSharpType(cenv, stripTyEqnsWrtErasure EraseAll cenv.g ty) member x.BasicQualifiedName = - let fail () = - invalidOp $"the type '{x}' does not have a qualified name" - protect <| fun () -> match stripTyparEqns ty with | TType_app(tcref, _, _) -> match tcref.CompiledRepresentation with - | CompiledTypeRepr.ILAsmNamed(tref, _, _) -> tref.BasicQualifiedName - | CompiledTypeRepr.ILAsmOpen _ -> fail () - | _ -> fail () + | CompiledTypeRepr.ILAsmNamed(tref, _, _) -> Some tref.BasicQualifiedName + | CompiledTypeRepr.ILAsmOpen _ -> None + | _ -> None member _.Instantiate(instantiation:(FSharpGenericParameter * FSharpType) list) = let resTy = instType (instantiation |> List.map (fun (tyv, ty) -> tyv.TypeParameter, ty.Type)) ty diff --git a/src/Compiler/Symbols/Symbols.fsi b/src/Compiler/Symbols/Symbols.fsi index 8d5499e857..c416016583 100644 --- a/src/Compiler/Symbols/Symbols.fsi +++ b/src/Compiler/Symbols/Symbols.fsi @@ -224,10 +224,10 @@ type FSharpEntity = member Namespace: string option /// Get the fully qualified name of the type or module - member QualifiedName: string + member QualifiedName: string option /// The fully qualified name of the type or module without strong assembly name. - member BasicQualifiedName: string + member BasicQualifiedName: string option /// Get the full name of the type or module member FullName: string @@ -1165,7 +1165,7 @@ type FSharpType = member ErasedType: FSharpType /// The fully qualified name of the type or module without strong assembly name. - member BasicQualifiedName: string + member BasicQualifiedName: string option /// Adjust the type by removing any occurrences of type inference variables, replacing them /// systematically with lower-case type inference variables such as 'a. diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl index 1954ef2367..a4b97b5fe6 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl @@ -5267,12 +5267,16 @@ FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[FShar FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] BaseType FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] get_BaseType() FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.ISourceText] TryGetMetadataText() +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] BasicQualifiedName FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] Namespace +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] QualifiedName FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] TryFullName FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] TryGetFullCompiledName() FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] TryGetFullDisplayName() FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] TryGetFullName() +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_BasicQualifiedName() FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_Namespace() +FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_QualifiedName() FSharp.Compiler.Symbols.FSharpEntity: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_TryFullName() FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IEnumerable`1[FSharp.Compiler.Symbols.FSharpEntity] GetPublicNestedEntities() FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] Attributes @@ -5297,21 +5301,17 @@ FSharp.Compiler.Symbols.FSharpEntity: System.Collections.Generic.IList`1[FSharp. 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 -FSharp.Compiler.Symbols.FSharpEntity: System.String BasicQualifiedName FSharp.Compiler.Symbols.FSharpEntity: System.String CompiledName FSharp.Compiler.Symbols.FSharpEntity: System.String DisplayName FSharp.Compiler.Symbols.FSharpEntity: System.String FullName FSharp.Compiler.Symbols.FSharpEntity: System.String LogicalName -FSharp.Compiler.Symbols.FSharpEntity: System.String QualifiedName FSharp.Compiler.Symbols.FSharpEntity: System.String ToString() FSharp.Compiler.Symbols.FSharpEntity: System.String XmlDocSig FSharp.Compiler.Symbols.FSharpEntity: System.String get_AccessPath() -FSharp.Compiler.Symbols.FSharpEntity: System.String get_BasicQualifiedName() FSharp.Compiler.Symbols.FSharpEntity: System.String get_CompiledName() FSharp.Compiler.Symbols.FSharpEntity: System.String get_DisplayName() FSharp.Compiler.Symbols.FSharpEntity: System.String get_FullName() FSharp.Compiler.Symbols.FSharpEntity: System.String get_LogicalName() -FSharp.Compiler.Symbols.FSharpEntity: System.String get_QualifiedName() FSharp.Compiler.Symbols.FSharpEntity: System.String get_XmlDocSig() FSharp.Compiler.Symbols.FSharpExpr: FSharp.Compiler.Symbols.FSharpType Type FSharp.Compiler.Symbols.FSharpExpr: FSharp.Compiler.Symbols.FSharpType get_Type() @@ -5871,6 +5871,8 @@ FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Text.TaggedText[] FormatLayo FSharp.Compiler.Symbols.FSharpType: Int32 GetHashCode() FSharp.Compiler.Symbols.FSharpType: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] BaseType FSharp.Compiler.Symbols.FSharpType: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] get_BaseType() +FSharp.Compiler.Symbols.FSharpType: Microsoft.FSharp.Core.FSharpOption`1[System.String] BasicQualifiedName +FSharp.Compiler.Symbols.FSharpType: Microsoft.FSharp.Core.FSharpOption`1[System.String] get_BasicQualifiedName() FSharp.Compiler.Symbols.FSharpType: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter] Prettify(System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter]) FSharp.Compiler.Symbols.FSharpType: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] AllInterfaces FSharp.Compiler.Symbols.FSharpType: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] GenericArguments @@ -5878,11 +5880,9 @@ FSharp.Compiler.Symbols.FSharpType: System.Collections.Generic.IList`1[FSharp.Co FSharp.Compiler.Symbols.FSharpType: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] get_AllInterfaces() FSharp.Compiler.Symbols.FSharpType: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpType] get_GenericArguments() FSharp.Compiler.Symbols.FSharpType: System.Collections.Generic.IList`1[System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter]] Prettify(System.Collections.Generic.IList`1[System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter]]) -FSharp.Compiler.Symbols.FSharpType: System.String BasicQualifiedName FSharp.Compiler.Symbols.FSharpType: System.String Format(FSharp.Compiler.Symbols.FSharpDisplayContext) FSharp.Compiler.Symbols.FSharpType: System.String FormatWithConstraints(FSharp.Compiler.Symbols.FSharpDisplayContext) FSharp.Compiler.Symbols.FSharpType: System.String ToString() -FSharp.Compiler.Symbols.FSharpType: System.String get_BasicQualifiedName() FSharp.Compiler.Symbols.FSharpType: System.Tuple`2[System.Collections.Generic.IList`1[System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter]],FSharp.Compiler.Symbols.FSharpParameter] Prettify(System.Collections.Generic.IList`1[System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter]], FSharp.Compiler.Symbols.FSharpParameter) FSharp.Compiler.Symbols.FSharpUnionCase: Boolean Equals(System.Object) FSharp.Compiler.Symbols.FSharpUnionCase: Boolean HasFields