Skip to content

Range of signature module includes attribute for signature but not for implementation file. #11381

@nojaf

Description

@nojaf

Please provide a succinct description of the issue.

Consider the following code and matching AST:

[<  Foo  >]
module Bar

let s : string = "s"

Implementation AST

ImplFile
  (ParsedImplFileInput
     ("tmp.fsx", true, QualifiedNameOfFile Bar$fsx, [], [],
      [SynModuleOrNamespace
         ([Bar], false, NamedModule,
          [Let(...)],
          PreXmlDoc ((2,6), FSharp.Compiler.XmlDoc+XmlDocCollector),
          [{ Attributes =
              [{ TypeName = LongIdentWithDots ([Foo], [])
                 ArgExpr = Const (Unit, tmp.fsx (1,4--1,7) IsSynthetic=false)
                 Target = None
                 AppliesToGetterAndSetter = false
                 Range = tmp.fsx (1,4--1,7) IsSynthetic=false }]
             Range = tmp.fsx (1,0--1,11) IsSynthetic=false }], None,
          tmp.fsx (2,0--4,20) IsSynthetic=false)], (true, true)))

and

[<  Foo  >]
module Bar

val s : string

Signature file

SigFile
  (ParsedSigFileInput
     ("tmp.fsi", QualifiedNameOfFile Bar, [], [],
      [SynModuleOrNamespaceSig
         ([Bar], false, NamedModule,
          [Val(...)],
          PreXmlDoc ((2,6), FSharp.Compiler.XmlDoc+XmlDocCollector),
          [{ Attributes =
              [{ TypeName = LongIdentWithDots ([Foo], [])
                 ArgExpr = Const (Unit, tmp.fsi (1,4--1,7) IsSynthetic=false)
                 Target = None
                 AppliesToGetterAndSetter = false
                 Range = tmp.fsi (1,4--1,7) IsSynthetic=false }]
             Range = tmp.fsi (1,0--1,11) IsSynthetic=false }], None,
          tmp.fsi (1,0--4,14) IsSynthetic=false)]))

Expected behavior

I'm not sure what the expected behavior should be in this case.
SynModuleOrNamespace starts at line 2 while SynModuleOrNamespaceSig starts at line 1.

Actual behavior

The range of the attributes is not included in SynModuleOrNamespace yet it is for SynModuleOrNamespaceSig.

Known workarounds

I calculate the full range using an extension:

type SynModuleOrNamespace with
    member mn.FullRange : Range =
        match mn with
        | SynModuleOrNamespace(attribs = h::_) ->
            Range.mkRange mn.Range.FileName h.Range.Start mn.Range.End
        | _ -> mn.Range

I'm ok with this workaround but would like both AST nodes to show the exact same behaviour.
Please let me know what is expected in this case. I'm interested in submitting a PR.

Related information

FCS 39.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions