diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs index fee75795e33..e181801324d 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fs +++ b/src/Compiler/SyntaxTree/ParseHelpers.fs @@ -420,9 +420,9 @@ let (|GetIdent|SetIdent|OtherIdent|) (ident: Ident option) = let mkSynMemberDefnGetSet (parseState: IParseState) - (opt_inline: bool) + (opt_inline: range option) (mWith: range) - (classDefnMemberGetSetElements: (bool * SynAttributeList list * (SynPat * range) * (range option * SynReturnInfo) option * range option * SynExpr * range) list) + (classDefnMemberGetSetElements: (range option * SynAttributeList list * (SynPat * range) * (range option * SynReturnInfo) option * range option * SynExpr * range) list) (mAnd: range option) (mWhole: range) (propertyNameBindingPat: SynPat) @@ -441,7 +441,7 @@ let mkSynMemberDefnGetSet let tryMkSynMemberDefnMember ( - optInline, + mOptInline: range option, optAttrs: SynAttributeList list, (bindingPat, mBindLhs), optReturnType, @@ -449,7 +449,7 @@ let mkSynMemberDefnGetSet expr, mExpr ) : (SynMemberDefn * Ident option) option = - let optInline = opt_inline || optInline + let optInline = Option.isSome opt_inline || Option.isSome mOptInline // optional attributes are only applied to getters and setters // the "top level" attrs will be applied to both let optAttrs = @@ -469,6 +469,7 @@ let mkSynMemberDefnGetSet let trivia: SynBindingTrivia = { LeadingKeyword = leadingKeyword + InlineKeyword = mOptInline EqualsRange = mEquals } @@ -729,6 +730,7 @@ let mkSynMemberDefnGetSet if getOrSet.idText = "get" then let trivia = { + InlineKeyword = opt_inline WithKeyword = mWith GetKeyword = Some getOrSet.idRange AndKeyword = None @@ -739,6 +741,7 @@ let mkSynMemberDefnGetSet else let trivia = { + InlineKeyword = opt_inline WithKeyword = mWith GetKeyword = None AndKeyword = None @@ -759,6 +762,7 @@ let mkSynMemberDefnGetSet let trivia = { + InlineKeyword = opt_inline WithKeyword = mWith GetKeyword = Some mGet AndKeyword = mAnd @@ -772,6 +776,7 @@ let mkSynMemberDefnGetSet match getOrSet with | GetIdent mGet -> { + InlineKeyword = opt_inline WithKeyword = mWith GetKeyword = Some mGet AndKeyword = mAnd @@ -779,6 +784,7 @@ let mkSynMemberDefnGetSet } | SetIdent mSet -> { + InlineKeyword = opt_inline WithKeyword = mWith GetKeyword = None AndKeyword = mAnd @@ -786,6 +792,7 @@ let mkSynMemberDefnGetSet } | OtherIdent -> { + InlineKeyword = opt_inline WithKeyword = mWith AndKeyword = mAnd GetKeyword = None @@ -899,6 +906,7 @@ let mkSynDoBinding (vis: SynAccess option, mDo, expr, m) = DebugPointAtBinding.NoneAtDo, { LeadingKeyword = SynLeadingKeyword.Do mDo + InlineKeyword = None EqualsRange = None } ) diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fsi b/src/Compiler/SyntaxTree/ParseHelpers.fsi index 353d8c973c6..46ae73f1ab0 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fsi +++ b/src/Compiler/SyntaxTree/ParseHelpers.fsi @@ -164,9 +164,9 @@ val raiseParseErrorAt: range -> (int * string) -> 'a val mkSynMemberDefnGetSet: parseState: IParseState -> - opt_inline: bool -> + opt_inline: range option -> mWith: range -> - classDefnMemberGetSetElements: (bool * SynAttributeList list * (SynPat * range) * (range option * SynReturnInfo) option * range option * SynExpr * range) list -> + classDefnMemberGetSetElements: (range option * SynAttributeList list * (SynPat * range) * (range option * SynReturnInfo) option * range option * SynExpr * range) list -> mAnd: range option -> mWhole: range -> propertyNameBindingPat: SynPat -> diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fs b/src/Compiler/SyntaxTree/SyntaxTrivia.fs index 160569564a3..dea3bfbc31a 100644 --- a/src/Compiler/SyntaxTree/SyntaxTrivia.fs +++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fs @@ -224,12 +224,14 @@ type SynLeadingKeyword = type SynBindingTrivia = { LeadingKeyword: SynLeadingKeyword + InlineKeyword: range option EqualsRange: range option } static member Zero: SynBindingTrivia = { LeadingKeyword = SynLeadingKeyword.Synthetic + InlineKeyword = None EqualsRange = None } @@ -288,6 +290,7 @@ type SynModuleOrNamespaceSigTrivia = type SynValSigTrivia = { LeadingKeyword: SynLeadingKeyword + InlineKeyword: range option WithKeyword: range option EqualsRange: range option } @@ -295,6 +298,7 @@ type SynValSigTrivia = static member Zero: SynValSigTrivia = { LeadingKeyword = SynLeadingKeyword.Synthetic + InlineKeyword = None WithKeyword = None EqualsRange = None } @@ -305,6 +309,7 @@ type SynTypeFunTrivia = { ArrowRange: range } [] type SynMemberGetSetTrivia = { + InlineKeyword: range option WithKeyword: range GetKeyword: range option AndKeyword: range option diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi index 555af5520ed..c76e3e99534 100644 --- a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi @@ -287,6 +287,9 @@ type SynBindingTrivia = /// Used leading keyword of SynBinding LeadingKeyword: SynLeadingKeyword + /// The syntax range of the `inline` keyword + InlineKeyword: range option + /// The syntax range of the `=` token. EqualsRange: range option } @@ -362,6 +365,9 @@ type SynValSigTrivia = /// but in case of `SynMemberDefn.AutoProperty` or `SynMemberDefn.AbstractSlot` it could be something else. LeadingKeyword: SynLeadingKeyword + /// The syntax range of the `inline` keyword + InlineKeyword: range option + /// The syntax range of the `with` keyword WithKeyword: range option @@ -383,6 +389,9 @@ type SynTypeFunTrivia = [] type SynMemberGetSetTrivia = { + /// The syntax range of the `inline` keyword + InlineKeyword: range option + /// The syntax range of the `with` keyword WithKeyword: range diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index a18fb02fbb1..dbbf70dcab0 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -695,7 +695,7 @@ moduleSpfn: valSpfn: | opt_attributes opt_access VAL opt_attributes opt_inline opt_mutable opt_access nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints optLiteralValueSpfn { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) - let attr1, attr2, isInline, isMutable, vis2, id, doc, explicitValTyparDecls, (ty, arity), (mEquals, konst: SynExpr option) = ($1), ($4), ($5), ($6), ($7), ($8), grabXmlDoc(parseState, $1, 1), ($9), ($11), ($12) + let attr1, attr2, isInline, isMutable, vis2, id, doc, explicitValTyparDecls, (ty, arity), (mEquals, konst: SynExpr option) = ($1), ($4), (Option.isSome $5), ($6), ($7), ($8), grabXmlDoc(parseState, $1, 1), ($9), ($11), ($12) if not (isNil attr2) then errorR(Deprecated(FSComp.SR.parsAttributesMustComeBeforeVal(), rhs parseState 4)) let m = rhs2 parseState 1 11 @@ -705,7 +705,7 @@ valSpfn: | None -> m | Some e -> unionRanges m e.Range let mVal = rhs parseState 3 - let trivia: SynValSigTrivia = { LeadingKeyword = SynLeadingKeyword.Val mVal; WithKeyword = None; EqualsRange = mEquals } + let trivia: SynValSigTrivia = { LeadingKeyword = SynLeadingKeyword.Val mVal; InlineKeyword = $5; WithKeyword = None; EqualsRange = mEquals } let valSpfn = SynValSig((attr1@attr2), id, explicitValTyparDecls, ty, arity, isInline, isMutable, doc, vis2, konst, m, trivia) SynModuleSigDecl.Val(valSpfn, m) } @@ -913,7 +913,7 @@ classSpfnMembersAtLeastOne: classMemberSpfn: | opt_attributes opt_access memberSpecFlags opt_inline opt_access nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints classMemberSpfnGetSet optLiteralValueSpfn { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) - let isInline, doc, vis2, id, explicitValTyparDecls, (ty, arity), (mEquals, optLiteralValue) = $4, grabXmlDoc(parseState, $1, 1), $5, $6, $7, $9, $11 + let isInline, doc, vis2, id, explicitValTyparDecls, (ty, arity), (mEquals, optLiteralValue) = (Option.isSome $4), grabXmlDoc(parseState, $1, 1), $5, $6, $7, $9, $11 let mWith, (getSet, getSetRangeOpt) = $10 let getSetAdjuster arity = match arity, getSet with SynValInfo([], _), SynMemberKind.Member -> SynMemberKind.PropertyGet | _ -> getSet let mWhole = @@ -930,7 +930,7 @@ classMemberSpfn: let flags, leadingKeyword = $3 let flags = flags (getSetAdjuster arity) - let trivia = { LeadingKeyword = leadingKeyword; WithKeyword = mWith; EqualsRange = mEquals } + let trivia = { LeadingKeyword = leadingKeyword; InlineKeyword = $4; WithKeyword = mWith; EqualsRange = mEquals } let valSpfn = SynValSig($1, id, explicitValTyparDecls, ty, arity, isInline, false, doc, vis2, optLiteralValue, mWhole, trivia) let trivia: SynMemberSigMemberTrivia = { GetSetKeywords = getSetRangeOpt } SynMemberSig.Member(valSpfn, flags, mWhole, trivia) } @@ -970,7 +970,7 @@ classMemberSpfn: let mNew = rhs parseState 3 let m = unionRanges (rhs parseState 1) ty.Range |> unionRangeWithXmlDoc doc let isInline = false - let trivia: SynValSigTrivia = { LeadingKeyword = SynLeadingKeyword.New mNew; WithKeyword = None; EqualsRange = None } + let trivia: SynValSigTrivia = { LeadingKeyword = SynLeadingKeyword.New mNew; InlineKeyword = None; WithKeyword = None; EqualsRange = None } let valSpfn = SynValSig ($1, (SynIdent(mkSynId (rhs parseState 3) "new", None)), noInferredTypars, ty, valSynInfo, isInline, false, doc, vis, None, m, trivia) SynMemberSig.Member(valSpfn, CtorMemberFlags, m, SynMemberSigMemberTrivia.Zero) } @@ -1740,8 +1740,8 @@ memberCore: let memFlagsBuilder, leadingKeyword = flagsBuilderAndLeadingKeyword let memberFlags = memFlagsBuilder SynMemberKind.Member let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) - let trivia: SynBindingTrivia = { LeadingKeyword = leadingKeyword; EqualsRange = Some mEquals } - let binding = mkSynBinding (xmlDoc, bindingPat) (vis, $1, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, $5, mRhs, [], attrs, Some memberFlags, trivia) + let trivia: SynBindingTrivia = { LeadingKeyword = leadingKeyword; InlineKeyword = $1; EqualsRange = Some mEquals } + let binding = mkSynBinding (xmlDoc, bindingPat) (vis, (Option.isSome $1), false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, $5, mRhs, [], attrs, Some memberFlags, trivia) let memberRange = unionRanges rangeStart mRhs |> unionRangeWithXmlDoc xmlDoc [ SynMemberDefn.Member (binding, memberRange) ]) } @@ -1819,7 +1819,7 @@ classDefnMember: | opt_attributes opt_access abstractMemberFlags opt_inline nameop opt_explicitValTyparDecls COLON topTypeWithTypeConstraints classMemberSpfnGetSet opt_ODECLEND { let ty, arity = $8 - let isInline, doc, id, explicitValTyparDecls = $4, grabXmlDoc(parseState, $1, 1), $5, $6 + let isInline, doc, id, explicitValTyparDecls = (Option.isSome $4), grabXmlDoc(parseState, $1, 1), $5, $6 let mWith, (getSet, getSetRangeOpt) = $9 let getSetAdjuster arity = match arity, getSet with SynValInfo([], _), SynMemberKind.Member -> SynMemberKind.PropertyGet | _ -> getSet let mWhole = @@ -1830,7 +1830,7 @@ classDefnMember: |> unionRangeWithXmlDoc doc if Option.isSome $2 then errorR(Error(FSComp.SR.parsAccessibilityModsIllegalForAbstract(), mWhole)) let mkFlags, leadingKeyword = $3 - let trivia = { LeadingKeyword = leadingKeyword; WithKeyword = mWith; EqualsRange = None } + let trivia = { LeadingKeyword = leadingKeyword; InlineKeyword = $4; WithKeyword = mWith; EqualsRange = None } let valSpfn = SynValSig($1, id, explicitValTyparDecls, ty, arity, isInline, false, doc, None, None, mWhole, trivia) let trivia: SynMemberDefnAbstractSlotTrivia = { GetSetKeywords = getSetRangeOpt } [ SynMemberDefn.AbstractSlot(valSpfn, mkFlags (getSetAdjuster arity), mWhole, trivia) ] } @@ -1870,7 +1870,7 @@ classDefnMember: let declPat = SynPat.LongIdent (SynLongIdent([mkSynId (rhs parseState 3) "new"], [], [None]), None, Some noInferredTypars, SynArgPats.Pats [$4], vis, rhs parseState 3) // Check that 'SynPatForConstructorDecl' matches this correctly assert (match declPat with SynPatForConstructorDecl _ -> true | _ -> false) - let synBindingTrivia: SynBindingTrivia = { LeadingKeyword = SynLeadingKeyword.New mNew; EqualsRange = Some mEquals } + let synBindingTrivia: SynBindingTrivia = { LeadingKeyword = SynLeadingKeyword.New mNew; InlineKeyword = None; EqualsRange = Some mEquals } [ SynMemberDefn.Member(SynBinding (None, SynBindingKind.Normal, false, false, $1, xmlDoc, valSynData, declPat, None, expr, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, synBindingTrivia), m) ] } | opt_attributes opt_access STATIC typeKeyword tyconDefn @@ -2669,7 +2669,7 @@ cPrototype: let bindingPat = SynPat.LongIdent (SynLongIdent([nm], [], [None]), None, Some noInferredTypars, SynArgPats.Pats [SynPat.Tuple(false, args, argsm)], vis, nmm) let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) let xmlDoc = grabXmlDoc(parseState, attrs, 1) - let trivia = { LeadingKeyword = SynLeadingKeyword.Extern mExtern; EqualsRange = None } + let trivia = { LeadingKeyword = SynLeadingKeyword.Extern mExtern; InlineKeyword = None; EqualsRange = None } let binding = mkSynBinding (xmlDoc, bindingPat) @@ -2792,8 +2792,8 @@ localBinding: let mWhole = (unionRanges leadingKeyword.Range mRhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) let spBind = if IsDebugPointBinding bindingPat expr then DebugPointAtBinding.Yes mWhole else DebugPointAtBinding.NoneAtLet let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range) - let trivia: SynBindingTrivia = { LeadingKeyword = leadingKeyword; EqualsRange = Some mEquals } - mkSynBinding (xmlDoc, bindingPat) (vis, $1, $2, mWholeBindLhs, spBind, optReturnType, expr, mRhs, opts, attrs, None, trivia)) + let trivia: SynBindingTrivia = { LeadingKeyword = leadingKeyword; InlineKeyword = $1; EqualsRange = Some mEquals } + mkSynBinding (xmlDoc, bindingPat) (vis, Option.isSome $1, $2, mWholeBindLhs, spBind, optReturnType, expr, mRhs, opts, attrs, None, trivia)) localBindingRange, localBindingBuilder } | opt_inline opt_mutable bindingPattern opt_topReturnTypeWithTypeConstraints EQUALS error @@ -2807,8 +2807,8 @@ localBinding: let zeroWidthAtEnd = mEquals.EndRange let rhsExpr = arbExpr("localBinding1", zeroWidthAtEnd) let spBind = if IsDebugPointBinding bindingPat rhsExpr then DebugPointAtBinding.Yes mWhole else DebugPointAtBinding.NoneAtLet - let trivia: SynBindingTrivia = { LeadingKeyword = leadingKeyword; EqualsRange = Some mEquals } - mkSynBinding (xmlDoc, bindingPat) (vis, $1, $2, mBindLhs, spBind, optReturnType, rhsExpr, mRhs, [], attrs, None, trivia)) + let trivia: SynBindingTrivia = { LeadingKeyword = leadingKeyword; InlineKeyword = $1; EqualsRange = Some mEquals } + mkSynBinding (xmlDoc, bindingPat) (vis, Option.isSome $1, $2, mBindLhs, spBind, optReturnType, rhsExpr, mRhs, [], attrs, None, trivia)) mWhole, localBindingBuilder } | opt_inline opt_mutable bindingPattern opt_topReturnTypeWithTypeConstraints recover @@ -2820,9 +2820,9 @@ localBinding: let localBindingBuilder = (fun xmlDoc attrs vis (leadingKeyword: SynLeadingKeyword) -> let spBind = DebugPointAtBinding.Yes (unionRanges leadingKeyword.Range mRhs) - let trivia = { LeadingKeyword = leadingKeyword; EqualsRange = None } + let trivia = { LeadingKeyword = leadingKeyword; InlineKeyword = $1; EqualsRange = None } let rhsExpr = arbExpr("localBinding2", mRhs) - mkSynBinding (xmlDoc, bindingPat) (vis, $1, $2, mBindLhs, spBind, optReturnType, rhsExpr, mRhs, [], attrs, None, trivia)) + mkSynBinding (xmlDoc, bindingPat) (vis, Option.isSome $1, $2, mBindLhs, spBind, optReturnType, rhsExpr, mRhs, [], attrs, None, trivia)) mWhole, localBindingBuilder } /* A single expression with an optional type annotation, and an optional static optimization block */ @@ -5816,8 +5816,8 @@ opt_bar: | /* EMPTY */ { } opt_inline: - | INLINE { true } - | /* EMPTY */ { false } + | INLINE { Some (rhs parseState 1) } + | /* EMPTY */ { None } opt_mutable: | MUTABLE { true } diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj index 279296ec02c..4259be3890a 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj @@ -131,6 +131,9 @@ SyntaxTree\LeadingKeywordTests.fs + + SyntaxTree\ValTests.fs + FileSystemTests.fs diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected index 65f6aa81b24..10aabc3dcc4 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected @@ -2162,8 +2162,8 @@ FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromDispatchSlotImplemen FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromOpenStatement FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromPattern FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromType -FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsPrivateToFile FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsFromUse +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean IsPrivateToFile FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromAttribute() FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromComputationExpression() FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromDefinition() @@ -2171,8 +2171,8 @@ FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromDispatchSlotImpl FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromOpenStatement() FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromPattern() FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromType() -FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsPrivateToFile() FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsFromUse() +FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: Boolean get_IsPrivateToFile() FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: FSharp.Compiler.Symbols.FSharpDisplayContext DisplayContext FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: FSharp.Compiler.Symbols.FSharpDisplayContext get_DisplayContext() FSharp.Compiler.CodeAnalysis.FSharpSymbolUse: FSharp.Compiler.Symbols.FSharpSymbol Symbol @@ -5170,10 +5170,10 @@ FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpGenericParamet FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpGenericParameter get_GenericParameter() FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpParameter Prettify(FSharp.Compiler.Symbols.FSharpParameter) FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpType AbbreviatedType +FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpType ErasedType FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpType Instantiate(Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[FSharp.Compiler.Symbols.FSharpGenericParameter,FSharp.Compiler.Symbols.FSharpType]]) FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpType Prettify(FSharp.Compiler.Symbols.FSharpType) FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpType StripAbbreviations() -FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpType ErasedType FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpType get_AbbreviatedType() FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Symbols.FSharpType get_ErasedType() FSharp.Compiler.Symbols.FSharpType: FSharp.Compiler.Text.TaggedText[] FormatLayout(FSharp.Compiler.Symbols.FSharpDisplayContext) @@ -9518,9 +9518,11 @@ FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: FSharp.Compiler.SyntaxTrivia.SynB FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: FSharp.Compiler.SyntaxTrivia.SynLeadingKeyword LeadingKeyword FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: FSharp.Compiler.SyntaxTrivia.SynLeadingKeyword get_LeadingKeyword() FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] EqualsRange +FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] InlineKeyword FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_EqualsRange() +FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_InlineKeyword() FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: System.String ToString() -FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Void .ctor(FSharp.Compiler.SyntaxTrivia.SynLeadingKeyword, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range]) +FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Void .ctor(FSharp.Compiler.SyntaxTrivia.SynLeadingKeyword, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range]) FSharp.Compiler.SyntaxTrivia.SynEnumCaseTrivia FSharp.Compiler.SyntaxTrivia.SynEnumCaseTrivia: FSharp.Compiler.Text.Range EqualsRange FSharp.Compiler.SyntaxTrivia.SynEnumCaseTrivia: FSharp.Compiler.Text.Range get_EqualsRange() @@ -9859,12 +9861,14 @@ FSharp.Compiler.SyntaxTrivia.SynMemberGetSetTrivia: FSharp.Compiler.Text.Range W FSharp.Compiler.SyntaxTrivia.SynMemberGetSetTrivia: FSharp.Compiler.Text.Range get_WithKeyword() FSharp.Compiler.SyntaxTrivia.SynMemberGetSetTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] AndKeyword FSharp.Compiler.SyntaxTrivia.SynMemberGetSetTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] GetKeyword +FSharp.Compiler.SyntaxTrivia.SynMemberGetSetTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] InlineKeyword FSharp.Compiler.SyntaxTrivia.SynMemberGetSetTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] SetKeyword FSharp.Compiler.SyntaxTrivia.SynMemberGetSetTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_AndKeyword() FSharp.Compiler.SyntaxTrivia.SynMemberGetSetTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_GetKeyword() +FSharp.Compiler.SyntaxTrivia.SynMemberGetSetTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_InlineKeyword() FSharp.Compiler.SyntaxTrivia.SynMemberGetSetTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_SetKeyword() FSharp.Compiler.SyntaxTrivia.SynMemberGetSetTrivia: System.String ToString() -FSharp.Compiler.SyntaxTrivia.SynMemberGetSetTrivia: Void .ctor(FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range]) +FSharp.Compiler.SyntaxTrivia.SynMemberGetSetTrivia: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range]) FSharp.Compiler.SyntaxTrivia.SynMemberSigMemberTrivia FSharp.Compiler.SyntaxTrivia.SynMemberSigMemberTrivia: FSharp.Compiler.SyntaxTrivia.SynMemberSigMemberTrivia Zero FSharp.Compiler.SyntaxTrivia.SynMemberSigMemberTrivia: FSharp.Compiler.SyntaxTrivia.SynMemberSigMemberTrivia get_Zero() @@ -10010,11 +10014,13 @@ FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: FSharp.Compiler.SyntaxTrivia.SynLe FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: FSharp.Compiler.SyntaxTrivia.SynValSigTrivia Zero FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: FSharp.Compiler.SyntaxTrivia.SynValSigTrivia get_Zero() FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] EqualsRange +FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] InlineKeyword FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] WithKeyword FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_EqualsRange() +FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_InlineKeyword() FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_WithKeyword() FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: System.String ToString() -FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: Void .ctor(FSharp.Compiler.SyntaxTrivia.SynLeadingKeyword, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range]) +FSharp.Compiler.SyntaxTrivia.SynValSigTrivia: Void .ctor(FSharp.Compiler.SyntaxTrivia.SynLeadingKeyword, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range]) FSharp.Compiler.Text.ISourceText FSharp.Compiler.Text.ISourceText: Boolean ContentEquals(FSharp.Compiler.Text.ISourceText) FSharp.Compiler.Text.ISourceText: Boolean SubTextEquals(System.String, Int32) diff --git a/tests/service/SyntaxTreeTests/BindingTests.fs b/tests/service/SyntaxTreeTests/BindingTests.fs index e2afdfd7f93..ef6efe22230 100644 --- a/tests/service/SyntaxTreeTests/BindingTests.fs +++ b/tests/service/SyntaxTreeTests/BindingTests.fs @@ -439,3 +439,44 @@ type X = assertRange (3,28) (3,29) mColon1 assertRange (3,52) (3,53) mColon2 | _ -> Assert.Fail $"Could not get valid AST, got {parseResults}" + +[] +let ``Inline keyword in binding`` () = + let parseResults = + getParseResults """ +let inline x y z = + let inline a b c = () + () +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Let(bindings = [ + SynBinding(trivia = { InlineKeyword = Some mInline1 } + expr = SynExpr.LetOrUse(bindings = [ + SynBinding(trivia = { InlineKeyword = Some mInline2 }) + ])) + ]) + ]) ])) -> + assertRange (2,4) (2,10) mInline1 + assertRange (3,8) (3,14) mInline2 + | _ -> Assert.Fail $"Could not get valid AST, got {parseResults}" + +[] +let ``Conditional directive around inline keyword`` () = + let parseResults = + getParseResults """ +let +#if !FOO + inline +#endif + map f ar = Async.map (Result.map f) ar +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Let(bindings = [ + SynBinding(trivia = { InlineKeyword = Some mInline }) ]) + ]) ])) -> + assertRange (4,4) (4,10) mInline + | _ -> Assert.Fail $"Could not get valid AST, got {parseResults}" diff --git a/tests/service/SyntaxTreeTests/MemberTests.fs b/tests/service/SyntaxTreeTests/MemberTests.fs index 3533a4e69b4..2cd0eaafa4e 100644 --- a/tests/service/SyntaxTreeTests/MemberTests.fs +++ b/tests/service/SyntaxTreeTests/MemberTests.fs @@ -315,3 +315,50 @@ type X = assertRange (7, 20) (7, 24) mWith assertRange (8, 32) (8, 35) mGet | _ -> Assert.Fail "Could not get valid AST" + +[] +let ``Member with inline keyword`` () = + let parseResults = + getParseResults + """ +type X = + member inline x.Y () = () +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types( + typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [ + SynMemberDefn.Member(memberDefn = SynBinding(trivia = { InlineKeyword = Some mInline })) + ])) ] + ) + ]) ])) -> + assertRange (3, 11) (3, 17) mInline + | ast -> Assert.Fail $"Could not get valid AST, got {ast}" + +[] +let ``Get/Set member with inline keyword`` () = + let parseResults = + getParseResults + """ +type X = + member inline x.Y + with inline get () = 4 + and inline set y = () +""" + + match parseResults with + | ParsedInput.ImplFile (ParsedImplFileInput (contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Types( + typeDefns = [ SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(members = [ + SynMemberDefn.GetSetMember(Some (SynBinding(trivia = { InlineKeyword = Some mInlineGet })), + Some (SynBinding(trivia = { InlineKeyword = Some mInlineSet })), + _, + { InlineKeyword = Some mInlineGetSetMember }) + ])) ] + ) + ]) ])) -> + assertRange (3, 11) (3, 17) mInlineGetSetMember + assertRange (4, 13) (4, 19) mInlineGet + assertRange (5, 12) (5, 18) mInlineSet + | ast -> Assert.Fail $"Could not get valid AST, got {ast}" diff --git a/tests/service/SyntaxTreeTests/ValTests.fs b/tests/service/SyntaxTreeTests/ValTests.fs new file mode 100644 index 00000000000..c14415bad6e --- /dev/null +++ b/tests/service/SyntaxTreeTests/ValTests.fs @@ -0,0 +1,20 @@ +module FSharp.Compiler.Service.Tests.SyntaxTreeTests.ValTests + +open FSharp.Compiler.Service.Tests.Common +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTrivia +open NUnit.Framework + +[] +let ``Inline keyword`` () = + let parseResults = + getParseResultsOfSignatureFile + """namespace X + +val inline meh: int -> int""" + + match parseResults with + | ParsedInput.SigFile (ParsedSigFileInput (contents = [ + SynModuleOrNamespaceSig(decls = [SynModuleSigDecl.Val(valSig = SynValSig(trivia = { InlineKeyword = Some mInline }))]) ])) -> + assertRange (3, 4) (3,10) mInline + | ast -> Assert.Fail $"Could not get valid AST, got {ast}"