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
8 changes: 8 additions & 0 deletions src/fsharp/SyntaxTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,14 @@ type SynMemberSig =
nestedType: SynTypeDefnSig *
range: range

member d.Range =
match d with
| SynMemberSig.Member (range=m)
| SynMemberSig.Interface (range=m)
| SynMemberSig.Inherit (range=m)
| SynMemberSig.ValField (range=m)
| SynMemberSig.NestedType (range=m) -> m

[<NoEquality; NoComparison; RequireQualifiedAccess>]
type SynTypeDefnKind =
| Unspecified
Expand Down
3 changes: 3 additions & 0 deletions src/fsharp/SyntaxTree.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,9 @@ type SynMemberSig =
nestedType: SynTypeDefnSig *
range: range

/// Gets the syntax range of this construct
member Range: range

/// Represents the kind of a type definition whether explicit or inferred
[<NoEquality; NoComparison; RequireQualifiedAccess>]
type SynTypeDefnKind =
Expand Down
17 changes: 11 additions & 6 deletions src/fsharp/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -908,25 +908,30 @@ tyconSpfnRhsBlock:
/* The right-hand-side of a type definition in a signature */
tyconSpfnRhs:
| tyconDefnOrSpfnSimpleRepr
{ let m = $1.Range
(fun lhsm nameInfo augmentation ->
SynTypeDefnSig(nameInfo, SynTypeDefnSigRepr.Simple ($1, m), augmentation, m)) }
{ (fun lhsm nameInfo augmentation ->
let declRange = unionRanges lhsm $1.Range
let mWhole = (declRange, augmentation) ||> unionRangeWithListBy (fun (mem: SynMemberSig) -> mem.Range)
SynTypeDefnSig(nameInfo, SynTypeDefnSigRepr.Simple ($1, $1.Range), augmentation, mWhole)) }

| tyconClassSpfn
{ let m = lhs parseState
{ let objectModelRange = lhs parseState
let needsCheck, (kind, decls) = $1
(fun nameRange nameInfo augmentation ->
if needsCheck && isNil decls then
reportParseErrorAt nameRange (FSComp.SR.parsEmptyTypeDefinition())
SynTypeDefnSig(nameInfo, SynTypeDefnSigRepr.ObjectModel (kind, decls, m), augmentation, m)) }

let declRange = unionRanges nameRange objectModelRange
let mWhole = (declRange, augmentation) ||> unionRangeWithListBy (fun (mem: SynMemberSig) -> mem.Range)
SynTypeDefnSig(nameInfo, SynTypeDefnSigRepr.ObjectModel (kind, decls, objectModelRange), augmentation, mWhole)) }

| DELEGATE OF topType
{ let m = lhs parseState
let ty, arity = $3
let invoke = SynMemberSig.Member(SynValSig([], mkSynId m "Invoke", inferredTyparDecls, ty, arity, false, false, PreXmlDoc.Empty, None, None, m), AbstractMemberFlags SynMemberKind.Member, m)
(fun nameRange nameInfo augmentation ->
if not (isNil augmentation) then raiseParseErrorAt m (FSComp.SR.parsAugmentationsIllegalOnDelegateType())
SynTypeDefnSig(nameInfo, SynTypeDefnSigRepr.ObjectModel (SynTypeDefnKind.Delegate (ty, arity), [invoke], m), [], m)) }
let mWhole = unionRanges nameRange m
SynTypeDefnSig(nameInfo, SynTypeDefnSigRepr.ObjectModel (SynTypeDefnKind.Delegate (ty, arity), [invoke], m), [], mWhole)) }


/* The right-hand-side of an object type definition in a signature */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7253,6 +7253,8 @@ FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Syntax.SynMemberSig+Member
FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Syntax.SynMemberSig+NestedType
FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Syntax.SynMemberSig+Tags
FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Syntax.SynMemberSig+ValField
FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Text.Range Range
FSharp.Compiler.Syntax.SynMemberSig: FSharp.Compiler.Text.Range get_Range()
FSharp.Compiler.Syntax.SynMemberSig: Int32 Tag
FSharp.Compiler.Syntax.SynMemberSig: Int32 get_Tag()
FSharp.Compiler.Syntax.SynMemberSig: System.String ToString()
Expand Down
60 changes: 60 additions & 0 deletions tests/service/Symbols.fs
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,66 @@ type Meh =
assertRange (3, 0) (5,11) r
| _ -> Assert.Fail "Could not get valid AST"

[<Test>]
let ``Range of TypeDefnSig record should end at last member`` () =
let parseResults =
getParseResultsOfSignatureFile
"""namespace X
type MyRecord =
{ Level: int }
member Score : unit -> int"""

match parseResults with
| ParsedInput.SigFile (ParsedSigFileInput (modules = [
SynModuleOrNamespaceSig(decls = [SynModuleSigDecl.Types(types = [SynTypeDefnSig.SynTypeDefnSig(range = r)])]) ])) ->
assertRange (2, 5) (4, 30) r
| _ -> Assert.Fail "Could not get valid AST"

[<Test>]
let ``Range of TypeDefnSig object model should end at last member`` () =
let parseResults =
getParseResultsOfSignatureFile
"""namespace X
type MyRecord =
class
end
member Score : unit -> int"""

match parseResults with
| ParsedInput.SigFile (ParsedSigFileInput (modules = [
SynModuleOrNamespaceSig(decls = [SynModuleSigDecl.Types(types = [SynTypeDefnSig.SynTypeDefnSig(range = r)])]) ])) ->
assertRange (2, 5) (5, 30) r
| _ -> Assert.Fail "Could not get valid AST"

[<Test>]
let ``Range of TypeDefnSig delegate of should start from name`` () =
let parseResults =
getParseResultsOfSignatureFile
"""namespace Y
type MyFunction =
delegate of int -> string"""

match parseResults with
| ParsedInput.SigFile (ParsedSigFileInput (modules = [
SynModuleOrNamespaceSig(decls = [SynModuleSigDecl.Types(types = [SynTypeDefnSig.SynTypeDefnSig(range = r)])]) ])) ->
assertRange (2, 5) (3, 29) r
| _ -> Assert.Fail "Could not get valid AST"

[<Test>]
let ``Range of TypeDefnSig simple should end at last val`` () =
let parseResults =
getParseResultsOfSignatureFile
"""namespace Z
type SomeCollection with
val LastIndex : int
val SomeThingElse : int -> string"""

match parseResults with
| ParsedInput.SigFile (ParsedSigFileInput (modules = [
SynModuleOrNamespaceSig(decls = [SynModuleSigDecl.Types(types = [SynTypeDefnSig.SynTypeDefnSig(range = r)])]) ])) ->
assertRange (2, 5) (4, 37) r
| _ -> Assert.Fail "Could not get valid AST"

module SynMatchClause =
[<Test>]
let ``Range of single SynMatchClause`` () =
Expand Down