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
4 changes: 2 additions & 2 deletions src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4035,7 +4035,7 @@ module TcDeclarations =
let mLetPortion = synExpr.Range
let fldId = ident (CompilerGeneratedName id.idText, mLetPortion)
let headPat = SynPat.LongIdent (SynLongIdent([fldId], [], [None]), None, Some noInferredTypars, SynArgPats.Pats [], None, mLetPortion)
let retInfo = match tyOpt with None -> None | Some ty -> Some (SynReturnInfo((ty, SynInfo.unnamedRetVal), ty.Range))
let retInfo = match tyOpt with None -> None | Some ty -> Some (None, SynReturnInfo((ty, SynInfo.unnamedRetVal), ty.Range))
let isMutable =
match propKind with
| SynMemberKind.PropertySet
Expand Down Expand Up @@ -4077,7 +4077,7 @@ module TcDeclarations =
| SynMemberKind.PropertyGetSet ->
let getter =
let rhsExpr = SynExpr.Ident fldId
let retInfo = match tyOpt with None -> None | Some ty -> Some (SynReturnInfo((ty, SynInfo.unnamedRetVal), ty.Range))
let retInfo = match tyOpt with None -> None | Some ty -> Some (None, SynReturnInfo((ty, SynInfo.unnamedRetVal), ty.Range))
let attribs = mkAttributeList attribs mMemberPortion
let binding = mkSynBinding (xmlDoc, headPat) (access, false, false, mMemberPortion, DebugPointAtBinding.NoneAtInvisible, retInfo, rhsExpr, rhsExpr.Range, [], attribs, Some memberFlags, SynBindingTrivia.Zero)
SynMemberDefn.Member (binding, mMemberPortion)
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10246,7 +10246,7 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt
|> fun (r, v) -> (List.map fst r, List.map snd r, List.map snd v)
let retAttribs =
match rtyOpt with
| Some (SynBindingReturnInfo(_, _, Attributes retAttrs)) ->
| Some (SynBindingReturnInfo(attributes = Attributes retAttrs)) ->
rotRetAttribs @ TcAttrs AttributeTargets.ReturnValue true retAttrs
| None -> rotRetAttribs
let valSynData =
Expand Down Expand Up @@ -10894,7 +10894,7 @@ and ApplyTypesFromArgumentPatterns (cenv: cenv, env, optionalArgsOK, ty, m, tpen
| [] ->
match retInfoOpt with
| None -> ()
| Some (SynBindingReturnInfo (retInfoTy, m, _)) ->
| Some (SynBindingReturnInfo (typeName = retInfoTy; range = m)) ->
let retInfoTy, _ = TcTypeAndRecover cenv NewTyparsOK CheckCxs ItemOccurence.UseInType WarnOnIWSAM.Yes env tpenv retInfoTy
UnifyTypes cenv env m ty retInfoTy
// Property setters always have "unit" return type
Expand Down
6 changes: 4 additions & 2 deletions src/Compiler/Service/ServiceParsedInputOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ module ParsedInput =
|> Option.orElseWith (fun () -> walkExpr e)
|> Option.orElseWith (fun () ->
match returnInfo with
| Some (SynBindingReturnInfo (t, _, _)) -> walkType t
| Some (SynBindingReturnInfo (typeName = t)) -> walkType t
| None -> None)

and walkInterfaceImpl (SynInterfaceImpl (bindings = bindings)) = List.tryPick walkBinding bindings
Expand Down Expand Up @@ -1662,7 +1662,9 @@ module ParsedInput =
List.iter walkAttribute attrs
walkPat pat
walkExpr e
returnInfo |> Option.iter (fun (SynBindingReturnInfo (t, _, _)) -> walkType t)

returnInfo
|> Option.iter (fun (SynBindingReturnInfo (typeName = t)) -> walkType t)

and walkInterfaceImpl (SynInterfaceImpl (bindings = bindings)) = List.iter walkBinding bindings

Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/SyntaxTree/ParseHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -422,11 +422,11 @@ let mkSynMemberDefnGetSet
(parseState: IParseState)
(opt_inline: bool)
(mWith: range)
(classDefnMemberGetSetElements: (bool * SynAttributeList list * (SynPat * range) * SynReturnInfo option * range option * SynExpr * range) list)
(classDefnMemberGetSetElements: (bool * SynAttributeList list * (SynPat * range) * (range option * SynReturnInfo) option * range option * SynExpr * range) list)
(mAnd: range option)
(mWhole: range)
(propertyNameBindingPat: SynPat)
(optPropertyType: SynReturnInfo option)
(optPropertyType: (range option * SynReturnInfo) option)
(visNoLongerUsed: SynAccess option)
flagsBuilderAndLeadingKeyword
(attrs: SynAttributeList list)
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/SyntaxTree/ParseHelpers.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,11 @@ val mkSynMemberDefnGetSet:
parseState: IParseState ->
opt_inline: bool ->
mWith: range ->
classDefnMemberGetSetElements: (bool * SynAttributeList list * (SynPat * range) * SynReturnInfo option * range option * SynExpr * range) list ->
classDefnMemberGetSetElements: (bool * SynAttributeList list * (SynPat * range) * (range option * SynReturnInfo) option * range option * SynExpr * range) list ->
mAnd: range option ->
mWhole: range ->
propertyNameBindingPat: SynPat ->
optPropertyType: SynReturnInfo option ->
optPropertyType: (range option * SynReturnInfo) option ->
visNoLongerUsed: SynAccess option ->
flagsBuilderAndLeadingKeyword: (SynMemberKind -> SynMemberFlags) * SynLeadingKeyword ->
attrs: SynAttributeList list ->
Expand Down
3 changes: 2 additions & 1 deletion src/Compiler/SyntaxTree/SyntaxTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,8 @@ type SynBinding =
member x.RangeOfHeadPattern = let (SynBinding (headPat = headPat)) = x in headPat.Range

[<NoEquality; NoComparison>]
type SynBindingReturnInfo = SynBindingReturnInfo of typeName: SynType * range: range * attributes: SynAttributes
type SynBindingReturnInfo =
| SynBindingReturnInfo of typeName: SynType * range: range * attributes: SynAttributes * trivia: SynBindingReturnInfoTrivia

[<NoComparison; RequireQualifiedAccess; CustomEquality>]
type SynMemberFlags =
Expand Down
7 changes: 6 additions & 1 deletion src/Compiler/SyntaxTree/SyntaxTree.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -1209,7 +1209,12 @@ type SynBinding =

/// Represents the return information in a binding for a 'let' or 'member' declaration
[<NoEquality; NoComparison>]
type SynBindingReturnInfo = SynBindingReturnInfo of typeName: SynType * range: range * attributes: SynAttributes
type SynBindingReturnInfo =
| SynBindingReturnInfo of
typeName: SynType *
range: range *
attributes: SynAttributes *
trivia: SynBindingReturnInfoTrivia

/// Represents the flags for a 'member' declaration
[<NoComparison; RequireQualifiedAccess; CustomEquality>]
Expand Down
6 changes: 3 additions & 3 deletions src/Compiler/SyntaxTree/SyntaxTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -673,8 +673,8 @@ let mkSynBindingRhs staticOptimizations rhsExpr mRhs retInfo =

let rhsExpr, retTyOpt =
match retInfo with
| Some (SynReturnInfo ((ty, SynArgInfo (rAttribs, _, _)), tym)) ->
SynExpr.Typed(rhsExpr, ty, rhsExpr.Range), Some(SynBindingReturnInfo(ty, tym, rAttribs))
| Some (mColon, SynReturnInfo ((ty, SynArgInfo (rAttribs, _, _)), tym)) ->
SynExpr.Typed(rhsExpr, ty, rhsExpr.Range), Some(SynBindingReturnInfo(ty, tym, rAttribs, { ColonRange = mColon }))
| None -> rhsExpr, None

rhsExpr, retTyOpt
Expand All @@ -684,7 +684,7 @@ let mkSynBinding
(vis, isInline, isMutable, mBind, spBind, retInfo, origRhsExpr, mRhs, staticOptimizations, attrs, memberFlagsOpt, trivia)
=
let info =
SynInfo.InferSynValData(memberFlagsOpt, Some headPat, retInfo, origRhsExpr)
SynInfo.InferSynValData(memberFlagsOpt, Some headPat, Option.map snd retInfo, origRhsExpr)

let rhsExpr, retTyOpt = mkSynBindingRhs staticOptimizations origRhsExpr mRhs retInfo
let mBind = unionRangeWithXmlDoc xmlDoc mBind
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/SyntaxTree/SyntaxTreeOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ val mkSynBindingRhs:
staticOptimizations: (SynStaticOptimizationConstraint list * SynExpr) list ->
rhsExpr: SynExpr ->
mRhs: range ->
retInfo: SynReturnInfo option ->
retInfo: (range option * SynReturnInfo) option ->
SynExpr * SynBindingReturnInfo option

val mkSynBinding:
Expand All @@ -279,7 +279,7 @@ val mkSynBinding:
isMutable: bool *
mBind: range *
spBind: DebugPointAtBinding *
retInfo: SynReturnInfo option *
retInfo: (range option * SynReturnInfo) option *
origRhsExpr: SynExpr *
mRhs: range *
staticOptimizations: (SynStaticOptimizationConstraint list * SynExpr) list *
Expand Down
4 changes: 4 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTrivia.fs
Original file line number Diff line number Diff line change
Expand Up @@ -320,4 +320,8 @@ type SynFieldTrivia =

static member Zero: SynFieldTrivia = { LeadingKeyword = None }

[<NoEquality; NoComparison>]
type SynTypeOrTrivia = { OrKeyword: range }

[<NoEquality; NoComparison>]
type SynBindingReturnInfoTrivia = { ColonRange: range option }
8 changes: 8 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTrivia.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -428,3 +428,11 @@ type SynTypeOrTrivia =
/// The syntax range of the `or` keyword
OrKeyword: range
}

/// Represents additional information for SynBindingReturnInfo
[<NoEquality; NoComparison>]
type SynBindingReturnInfoTrivia =
{
/// The syntax range of the `:` token
ColonRange: range option
}
7 changes: 4 additions & 3 deletions src/Compiler/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -2647,7 +2647,7 @@ cPrototype:
let binding =
mkSynBinding
(xmlDoc, bindingPat)
(vis, false, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, Some rty, rhsExpr, mRhs, [], attrs, None, trivia)
(vis, false, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, Some (None, rty), rhsExpr, mRhs, [], attrs, None, trivia)
[], [binding]) }

/* A list of arguments in an 'extern' DllImport function definition */
Expand Down Expand Up @@ -4995,9 +4995,10 @@ opt_topReturnTypeWithTypeConstraints:
{ None }

| COLON topTypeWithTypeConstraints
{ let ty, arity = $2
{ let mColon = rhs parseState 1
let ty, arity = $2
let arity = (match arity with SynValInfo([], rmdata)-> rmdata | _ -> SynInfo.unnamedRetVal)
Some (SynReturnInfo((ty, arity), rhs parseState 2)) }
Some (Some mColon, SynReturnInfo((ty, arity), rhs parseState 2)) }

topType:
| topTupleType RARROW topType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5925,9 +5925,11 @@ FSharp.Compiler.Syntax.SynBindingKind: Int32 Tag
FSharp.Compiler.Syntax.SynBindingKind: Int32 get_Tag()
FSharp.Compiler.Syntax.SynBindingKind: System.String ToString()
FSharp.Compiler.Syntax.SynBindingReturnInfo
FSharp.Compiler.Syntax.SynBindingReturnInfo: FSharp.Compiler.Syntax.SynBindingReturnInfo NewSynBindingReturnInfo(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList])
FSharp.Compiler.Syntax.SynBindingReturnInfo: FSharp.Compiler.Syntax.SynBindingReturnInfo NewSynBindingReturnInfo(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], FSharp.Compiler.SyntaxTrivia.SynBindingReturnInfoTrivia)
FSharp.Compiler.Syntax.SynBindingReturnInfo: FSharp.Compiler.Syntax.SynType get_typeName()
FSharp.Compiler.Syntax.SynBindingReturnInfo: FSharp.Compiler.Syntax.SynType typeName
FSharp.Compiler.Syntax.SynBindingReturnInfo: FSharp.Compiler.SyntaxTrivia.SynBindingReturnInfoTrivia get_trivia()
FSharp.Compiler.Syntax.SynBindingReturnInfo: FSharp.Compiler.SyntaxTrivia.SynBindingReturnInfoTrivia trivia
FSharp.Compiler.Syntax.SynBindingReturnInfo: FSharp.Compiler.Text.Range get_range()
FSharp.Compiler.Syntax.SynBindingReturnInfo: FSharp.Compiler.Text.Range range
FSharp.Compiler.Syntax.SynBindingReturnInfo: Int32 Tag
Expand Down Expand Up @@ -9410,6 +9412,11 @@ FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia: FSharp.Compiler.Text.
FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia: FSharp.Compiler.Text.Range get_ParenRange()
FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia: System.String ToString()
FSharp.Compiler.SyntaxTrivia.SynArgPatsNamePatPairsTrivia: Void .ctor(FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTrivia.SynBindingReturnInfoTrivia
FSharp.Compiler.SyntaxTrivia.SynBindingReturnInfoTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] ColonRange
FSharp.Compiler.SyntaxTrivia.SynBindingReturnInfoTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_ColonRange()
FSharp.Compiler.SyntaxTrivia.SynBindingReturnInfoTrivia: System.String ToString()
FSharp.Compiler.SyntaxTrivia.SynBindingReturnInfoTrivia: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range])
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: FSharp.Compiler.SyntaxTrivia.SynBindingTrivia Zero
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: FSharp.Compiler.SyntaxTrivia.SynBindingTrivia get_Zero()
Expand Down Expand Up @@ -9826,13 +9833,8 @@ FSharp.Compiler.SyntaxTrivia.SynTypeFunTrivia: FSharp.Compiler.Text.Range get_Ar
FSharp.Compiler.SyntaxTrivia.SynTypeFunTrivia: System.String ToString()
FSharp.Compiler.SyntaxTrivia.SynTypeFunTrivia: Void .ctor(FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTrivia.SynTypeOrTrivia
FSharp.Compiler.SyntaxTrivia.SynTypeOrTrivia: Boolean Equals(FSharp.Compiler.SyntaxTrivia.SynTypeOrTrivia)
FSharp.Compiler.SyntaxTrivia.SynTypeOrTrivia: Boolean Equals(System.Object)
FSharp.Compiler.SyntaxTrivia.SynTypeOrTrivia: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
FSharp.Compiler.SyntaxTrivia.SynTypeOrTrivia: FSharp.Compiler.Text.Range OrKeyword
FSharp.Compiler.SyntaxTrivia.SynTypeOrTrivia: FSharp.Compiler.Text.Range get_OrKeyword()
FSharp.Compiler.SyntaxTrivia.SynTypeOrTrivia: Int32 GetHashCode()
FSharp.Compiler.SyntaxTrivia.SynTypeOrTrivia: Int32 GetHashCode(System.Collections.IEqualityComparer)
FSharp.Compiler.SyntaxTrivia.SynTypeOrTrivia: System.String ToString()
FSharp.Compiler.SyntaxTrivia.SynTypeOrTrivia: Void .ctor(FSharp.Compiler.Text.Range)
FSharp.Compiler.SyntaxTrivia.SynUnionCaseTrivia
Expand Down
40 changes: 40 additions & 0 deletions tests/service/SyntaxTreeTests/BindingTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -399,3 +399,43 @@ let b : int * string * bool = 1, "", false
]) ])) ->
Assert.Pass ()
| _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"

[<Test>]
let ``Colon before return type is part of trivia`` () =
let parseResults =
getParseResults """
let x y : int = failwith "todo"
"""

match parseResults with
| ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
SynModuleDecl.Let(bindings = [
SynBinding(returnInfo =
Some (SynBindingReturnInfo(trivia = { ColonRange = Some mColon })))
])
]) ])) ->
assertRange (2,8) (2,9) mColon
| _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"

[<Test>]
let ``Colon before return type is part of trivia in properties`` () =
let parseResults =
getParseResults """
type X =
member this.Y with get():int = 1 and set (_:int):unit = ()
"""

match parseResults with
| ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [
SynModuleDecl.Types(typeDefns = [
SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [
SynMemberDefn.GetSetMember(
memberDefnForGet = Some(SynBinding(returnInfo = Some (SynBindingReturnInfo(trivia = { ColonRange = Some mColon1 }))))
memberDefnForSet = Some(SynBinding(returnInfo = Some (SynBindingReturnInfo(trivia = { ColonRange = Some mColon2 }))))
)
]))
])
]) ])) ->
assertRange (3,28) (3,29) mColon1
assertRange (3,52) (3,53) mColon2
| _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"