Skip to content
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
2 changes: 2 additions & 0 deletions docs/release-notes/.FSharp.Compiler.Service/10.0.100.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Add support for tail calls in computation expressions ([PR #18804](https://github.com/dotnet/fsharp/pull/18804))
* Add `--typecheck-only` flag support for F# Interactive (FSI) scripts to type-check without execution. ([Issue #18686](https://github.com/dotnet/fsharp/issues/18686))
* Diagnostics: add extended data for 'No constructors' error ([PR #18863](https://github.com/dotnet/fsharp/pull/18863))
* FSharpType.Format: support top-level prefix generic types style. ([PR #18897](https://github.com/dotnet/fsharp/pull/18897))
* FCS: allow getting captured types ([PR $18878](https://github.com/dotnet/fsharp/pull/18878))

### Fixed
Expand All @@ -25,6 +26,7 @@
* Fix Show XML doc for enum fields in external metadata ([Issue #17939](https://github.com/dotnet/fsharp/issues/17939#issuecomment-3137410105), [PR #18800](https://github.com/dotnet/fsharp/pull/18800))
* Fix nullable types formatting in `FSharpType.Format` and tooltips to include parentheses. ([PR #18842](https://github.com/dotnet/fsharp/pull/18842))
* TypeMismatchDiagnosticExtendedData: fix expected and actual types calculation. ([Issue ](https://github.com/dotnet/fsharp/pull/18851))
* Format top-level generic types using a prefix style in inherit/interface declarations and flexible type annotations. ([PR #18897](https://github.com/dotnet/fsharp/pull/18897))
* Parser: fix range for computed binding expressions ([PR #18903](https://github.com/dotnet/fsharp/pull/18903))

### Changed
Expand Down
25 changes: 12 additions & 13 deletions src/Compiler/Checking/NicePrint.fs
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,10 @@ module internal PrintUtilities =

let usePrefix (denv: DisplayEnv) (tcref: TyconRef) =
match denv.genericParameterStyle with
| GenericParameterStyle.Implicit -> tcref.IsPrefixDisplay
| GenericParameterStyle.Prefix -> true
| GenericParameterStyle.Suffix -> false
| GenericParameterStyle.Implicit -> tcref.IsPrefixDisplay, denv
| GenericParameterStyle.Prefix -> true, denv
| GenericParameterStyle.Suffix -> false, denv
| GenericParameterStyle.TopLevelPrefix nested -> true, denv.UseGenericParameterStyle(nested)

/// <summary>
/// Creates a layout for TyconRef.
Expand All @@ -187,7 +188,7 @@ module internal PrintUtilities =
/// </param>
let layoutTyconRefImpl isAttribute (denv: DisplayEnv) (tcref: TyconRef) (demangledPath: string list option) =

let prefix = usePrefix denv tcref
let prefix, denv = usePrefix denv tcref
let isArray = not prefix && isArrayTyconRef denv.g tcref
let demangled =
if isArray then
Expand Down Expand Up @@ -744,12 +745,8 @@ module PrintTypes =
| Some typarConstraintTy ->
if Zset.contains typar env.singletons then
let tyLayout =
match typarConstraintTy with
| TType_app (tyconRef = tc; typeInstantiation = ti)
when ti.Length > 0 && not (usePrefix denv tc) ->
layoutTypeWithInfo denv env typarConstraintTy
|> bracketL
| _ -> layoutTypeWithInfo denv env typarConstraintTy
let denv = denv.UseTopLevelPrefixGenericParameterStyle()
layoutTypeWithInfo denv env typarConstraintTy

leftL (tagPunctuation "#") ^^ tyLayout
else
Expand Down Expand Up @@ -975,10 +972,10 @@ module PrintTypes =

// Layout a type application
| TType_ucase (UnionCaseRef(tc, _), args) ->
let prefix = usePrefix denv tc
let prefix, denv = usePrefix denv tc
layoutTypeAppWithInfoAndPrec denv env (layoutTyconRefImpl false denv tc None) prec prefix args
| TType_app (tc, args, nullness) ->
let prefix = usePrefix denv tc
let prefix, denv = usePrefix denv tc
let demangledCompilationPathOpt, args =
if not denv.includeStaticParametersInTypeNames then
None, args
Expand Down Expand Up @@ -2047,6 +2044,7 @@ module TastDefinitionPrinting =
GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g amap m ty

let iimplsLs =
let denv = denv.UseTopLevelPrefixGenericParameterStyle()
iimpls
|> List.map (fun intfTy -> (if isInterfaceTy g ty then WordL.keywordInherit else WordL.keywordInterface) -* layoutType denv intfTy)

Expand Down Expand Up @@ -2181,7 +2179,8 @@ module TastDefinitionPrinting =
| _ -> ()
]

let inheritsL =
let inheritsL =
let denv = denv.UseTopLevelPrefixGenericParameterStyle()
inherits
|> List.map (fun super -> WordL.keywordInherit ^^ (layoutType denv super))

Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/Symbols/Symbols.fs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ type FSharpDisplayContext(denv: TcGlobals -> DisplayEnv) =
member _.WithSuffixGenericParameters () =
FSharpDisplayContext(fun g -> { denv g with genericParameterStyle = GenericParameterStyle.Suffix } )

member x.WithTopLevelPrefixGenericParameters () =
FSharpDisplayContext(fun g -> (denv g).UseTopLevelPrefixGenericParameterStyle())

// delay the realization of 'item' in case it is unresolved
type FSharpSymbol(cenv: SymbolEnv, item: unit -> Item, access: FSharpSymbol -> CcuThunk -> AccessorDomain -> bool) =

Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/Symbols/Symbols.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ type FSharpDisplayContext =
/// for example `int list`
member WithSuffixGenericParameters: unit -> FSharpDisplayContext

/// Causes type signatures to be formatted with prefix-style generic parameters for a top level type
/// while nested types inherit generic parameters style from the current `FSharpDisplayContext` instance,
/// for example, `int list seq` becomes `seq<int list>`
member WithTopLevelPrefixGenericParameters: unit -> FSharpDisplayContext

/// Represents a symbol in checked F# source code or a compiled .NET component.
///
/// The subtype of the symbol may reveal further information and can be one of FSharpEntity, FSharpUnionCase
Expand Down
9 changes: 9 additions & 0 deletions src/Compiler/TypedTree/TypedTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3171,6 +3171,7 @@ type GenericParameterStyle =
| Implicit
| Prefix
| Suffix
| TopLevelPrefix of nested: GenericParameterStyle

[<NoEquality; NoComparison>]
type DisplayEnv =
Expand Down Expand Up @@ -3255,6 +3256,14 @@ type DisplayEnv =

member denv.UseGenericParameterStyle style =
{ denv with genericParameterStyle = style }

member denv.UseTopLevelPrefixGenericParameterStyle() =
let nestedStyle =
match denv.genericParameterStyle with
| TopLevelPrefix(nested) -> nested
| style -> style

{ denv with genericParameterStyle = TopLevelPrefix(nestedStyle) }

static member InitialForSigFileGeneration g =
let denv =
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/TypedTree/TypedTreeOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -1061,6 +1061,9 @@ type GenericParameterStyle =
| Prefix
/// Force the suffix style: int List
| Suffix
/// Force the prefix style for a top-level type,
/// for example, `seq<int list>` instead of `int list seq`
| TopLevelPrefix of nested: GenericParameterStyle

[<NoEquality; NoComparison>]
type DisplayEnv =
Expand Down Expand Up @@ -1111,6 +1114,8 @@ type DisplayEnv =

member UseGenericParameterStyle: GenericParameterStyle -> DisplayEnv

member UseTopLevelPrefixGenericParameterStyle: unit -> DisplayEnv

static member InitialForSigFileGeneration: TcGlobals -> DisplayEnv

val tagEntityRefName: xref: EntityRef -> name: string -> TaggedText
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5166,6 +5166,7 @@ FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisp
FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext WithPrefixGenericParameters()
FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext WithShortTypeNames(Boolean)
FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext WithSuffixGenericParameters()
FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext WithTopLevelPrefixGenericParameters()
FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext get_Empty()
FSharp.Compiler.Symbols.FSharpEntity: Boolean Equals(System.Object)
FSharp.Compiler.Symbols.FSharpEntity: Boolean HasAssemblyCodeRepresentation
Expand Down
28 changes: 28 additions & 0 deletions tests/FSharp.Compiler.Service.Tests/Symbols.fs
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,34 @@ let tester2: int Group = []

| other -> failwithf "myArr was supposed to be a value, but is %A" other

[<Fact>]
let ``FSharpType.Format with top-level prefix generic parameters style`` () =
let _, checkResults = getParseAndCheckResults """
let f (x: int list seq) = ()
"""
let symbolUse = findSymbolUseByName "x" checkResults
let symbol = symbolUse.Symbol :?> FSharpMemberOrFunctionOrValue
let typeArg = symbol.FullType
let displayContext = symbolUse.DisplayContext

let topLevelPrefixStyle =
displayContext.WithTopLevelPrefixGenericParameters()

let topLevelPrefixWithNestedPrefixStyle1 =
displayContext.WithPrefixGenericParameters().WithTopLevelPrefixGenericParameters()

// Should be idempotent
let topLevelPrefixWithNestedPrefixStyle2 =
topLevelPrefixWithNestedPrefixStyle1.WithTopLevelPrefixGenericParameters()

[ typeArg.Format(topLevelPrefixStyle)
typeArg.Format(topLevelPrefixWithNestedPrefixStyle1)
typeArg.Format(topLevelPrefixWithNestedPrefixStyle2) ]
|> shouldBe [
"seq<int list>"
"seq<list<int>>"
"seq<list<int>>" ]

[<Fact>]
let ``Unfinished long ident type `` () =
let _, checkResults = getParseAndCheckResults """
Expand Down
34 changes: 33 additions & 1 deletion tests/FSharp.Compiler.Service.Tests/TooltipTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -535,4 +535,36 @@ open System
let doIt(myAction : Action<int>) = myAc{caret}tion.Invoke(42)
"""
|> assertAndGetSingleToolTipText
|> Assert.shouldBeEquivalentTo ("""val myAction: Action<int>""" |> normalize)
|> Assert.shouldBeEquivalentTo ("""val myAction: Action<int>""" |> normalize)

[<Fact>]
let ``Super type should be formatted in the prefix style`` () =
Checker.getTooltip """
namespace Foo

type A{caret} =
inherit seq<int list>
"""
|> assertAndGetSingleToolTipText
|> Assert.shouldBeEquivalentTo "type A =\n inherit seq<int list>"

[<Fact>]
let ``Interface impl should be formatted in the prefix style`` () =
Checker.getTooltip """
namespace Foo

type A{caret} =
interface seq<int list> with
"""
|> assertAndGetSingleToolTipText
|> Assert.shouldBeEquivalentTo "type A =\n interface seq<int list>"

[<Fact>]
let ``Flexible generic type should be formatted in the prefix style`` () =
Checker.getTooltip """
module Foo

let f (x{caret}: #seq<int list>) = ()
"""
|> assertAndGetSingleToolTipText
|> Assert.shouldBeEquivalentTo "val x: #seq<int list>"
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@924-516::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@924-516::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x0000008B][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@924-516::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000094][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Symbols+fullName@2498-1::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000015][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Symbols+fullName@2501-1::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000015][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CreateILModule+MainModuleBuilder::ConvertProductVersionToILVersionInfo(string)][offset 0x00000011][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.StaticLinking+TypeForwarding::followTypeForwardForILTypeRef([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.IL+ILTypeRef)][offset 0x00000010][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions::getCompilerOption([FSharp.Compiler.Service]FSharp.Compiler.CompilerOptions+CompilerOption, [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<int32>)][offset 0x000000E6][found Char] Unexpected type on the stack.
Expand All @@ -60,7 +60,7 @@
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x00000634][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.PatternMatchCompilation::isProblematicClause([FSharp.Compiler.Service]FSharp.Compiler.PatternMatchCompilation+MatchClause)][offset 0x00000065][found Byte] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.PatternMatchCompilation::.cctor()][offset 0x00000015][found Boolean] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2078-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000BE][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2076-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000BE][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+PrintUtilities::layoutXmlDoc([FSharp.Compiler.Service]FSharp.Compiler.TypedTreeOps+DisplayEnv, bool, [FSharp.Compiler.Service]FSharp.Compiler.Xml.XmlDoc, [FSharp.Compiler.Service]FSharp.Compiler.Text.Layout)][offset 0x00000033][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateNamespaceName(string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1<Microsoft.FSharp.Core.CompilerServices.ITypeProvider>, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string)][offset 0x00000063][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateExpectedName([FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string[], string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1<FSharp.Compiler.TypeProviders+ProvidedType>)][offset 0x000000AD][found Char] Unexpected type on the stack.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@924-531::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000064][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@924-531::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x0000006D][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$ServiceLexing+clo@924-531::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`3<FSharp.Compiler.Parser+token,int32,int32>,Microsoft.FSharp.Core.Unit>)][offset 0x00000076][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Symbols+fullName@2498-3::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000030][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$Symbols+fullName@2501-3::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000030][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.Driver+ProcessCommandLineFlags@286-1::Invoke(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.Driver+ProcessCommandLineFlags@286-1::Invoke(string)][offset 0x00000014][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CreateILModule+MainModuleBuilder::ConvertProductVersionToILVersionInfo(string)][offset 0x00000010][found Char] Unexpected type on the stack.
Expand All @@ -65,7 +65,7 @@
[IL]: Error [StackUnexpected]: : FSharp.Compiler.IlxGen::HashRangeSorted([S.P.CoreLib]System.Collections.Generic.IDictionary`2<!!0,System.Tuple`2<int32,!!1>>)][offset 0x00000012][found ref '[FSharp.Compiler.Service]FSharp.Compiler.IlxGen+HashRangeSorted@1875<T1>'][expected ref '[FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<System.Tuple`2<int32,T0>,T0>'] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.PatternMatchCompilation::isProblematicClause([FSharp.Compiler.Service]FSharp.Compiler.PatternMatchCompilation+MatchClause)][offset 0x00000040][found Byte] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : <StartupCode$FSharp-Compiler-Service>.$FSharp.Compiler.PatternMatchCompilation::.cctor()][offset 0x0000000B][found Boolean] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2078-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000B3][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2076-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000B3][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+PrintUtilities::layoutXmlDoc([FSharp.Compiler.Service]FSharp.Compiler.TypedTreeOps+DisplayEnv, bool, [FSharp.Compiler.Service]FSharp.Compiler.Xml.XmlDoc, [FSharp.Compiler.Service]FSharp.Compiler.Text.Layout)][offset 0x00000034][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateNamespaceName(string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1<Microsoft.FSharp.Core.CompilerServices.ITypeProvider>, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string)][offset 0x00000074][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateExpectedName([FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string[], string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1<FSharp.Compiler.TypeProviders+ProvidedType>)][offset 0x000000A8][found Char] Unexpected type on the stack.
Expand Down
Loading