Skip to content

Signature file generation does not handle attributes above recursive types #13809

@nojaf

Description

@nojaf

When generating a signature file from a recursive type with an attribute, the generated code places the attribute above the and keyword.

Repro steps

namespace Foo.Types

open System.Collections.Generic

type FormatSelectionRequest =
    {
        SourceCode: string
        /// File path will be used to identify the .editorconfig options
        /// Unless the configuration is passed
        FilePath: string
        /// Overrides the found .editorconfig.
        Config: IReadOnlyDictionary<string, string> option
        /// Range follows the same semantics of the FSharp Compiler Range type.
        Range: FormatSelectionRange
    }

    member this.IsSignatureFile = this.FilePath.EndsWith(".fsi")

and FormatSelectionRange =
    struct
        val StartLine: int
        val StartColumn: int
        val EndLine: int
        val EndColumn: int

        new(startLine: int, startColumn: int, endLine: int, endColumn: int) =
            { StartLine = startLine
              StartColumn = startColumn
              EndLine = endLine
              EndColumn = endColumn }
    end

leads to

namespace Foo.Types
    
    type FormatSelectionRequest =
        {
          SourceCode: string
          
          /// File path will be used to identify the .editorconfig options
          /// Unless the configuration is passed
          FilePath: string
          
          /// Overrides the found .editorconfig.
          Config:
            System.Collections.Generic.IReadOnlyDictionary<string,string> option
          
          /// Range follows the same semantics of the FSharp Compiler Range type.
          Range: FormatSelectionRange
        }
        
        member IsSignatureFile: bool
    
    [<Struct>]
    and FormatSelectionRange =
        
        new: startLine: int * startColumn: int * endLine: int * endColumn: int ->
               FormatSelectionRange
        
        val StartLine: int
        
        val StartColumn: int
        
        val EndLine: int
        
        val EndColumn: int

Expected behaviour

The generated signature should be considered equivalent to the backing source file.

Actual behaviour

The generated code isn't valid:

image

Known workarounds

Edit signature file by hand.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions