Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add extern keyword to SynBindingTrivia. #14030

Merged
merged 3 commits into from
Oct 6, 2022
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
3 changes: 3 additions & 0 deletions src/Compiler/SyntaxTree/ParseHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ let mkSynMemberDefnGetSet
{
LetKeyword = None
EqualsRange = mEquals
ExternKeyword = None
}

let binding =
Expand Down Expand Up @@ -542,6 +543,7 @@ let mkSynMemberDefnGetSet
{
LetKeyword = None
EqualsRange = mEquals
ExternKeyword = None
}

let binding =
Expand Down Expand Up @@ -629,6 +631,7 @@ let mkSynMemberDefnGetSet
{
LetKeyword = None
EqualsRange = mEquals
ExternKeyword = None
}

let bindingOuter =
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTrivia.fs
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,14 @@ type SynTypeDefnSigTrivia =
type SynBindingTrivia =
{
LetKeyword: range option
ExternKeyword: range option
EqualsRange: range option
}

static member Zero: SynBindingTrivia =
{
LetKeyword = None
ExternKeyword = None
EqualsRange = None
}

Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTrivia.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ type SynBindingTrivia =
/// The syntax range of the `let` keyword.
LetKeyword: range option

/// The syntax range of the `extern` keyword.
ExternKeyword: range option

/// The syntax range of the `=` token.
EqualsRange: range option
}
Expand Down
16 changes: 9 additions & 7 deletions src/Compiler/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -1868,7 +1868,7 @@ memberCore:
let xmlDoc = grabXmlDocAtRangeStart(parseState, attrs, rangeStart)
let memberFlags = Some (memFlagsBuilder SynMemberKind.Member)
let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range)
let trivia: SynBindingTrivia = { LetKeyword = None; EqualsRange = Some mEquals }
let trivia: SynBindingTrivia = { LetKeyword = None; EqualsRange = Some mEquals; ExternKeyword = None }
let binding = mkSynBinding (xmlDoc, bindingPat) (vis, $1, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, $5, mRhs, [], attrs, memberFlags, trivia)
let memberRange = unionRanges rangeStart mRhs |> unionRangeWithXmlDoc xmlDoc
[ SynMemberDefn.Member (binding, memberRange) ]) }
Expand Down Expand Up @@ -1985,7 +1985,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 = { LetKeyword = None; EqualsRange = Some mEquals }
let synBindingTrivia: SynBindingTrivia = { LetKeyword = None; EqualsRange = Some mEquals; ExternKeyword = None }
[ SynMemberDefn.Member(SynBinding (None, SynBindingKind.Normal, false, false, $1, xmlDoc, valSynData, declPat, None, expr, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, synBindingTrivia), m) ] }

| opt_attributes opt_declVisibility STATIC typeKeyword tyconDefn
Expand Down Expand Up @@ -2743,7 +2743,8 @@ hardwhiteDefnBindingsTerminator:
/* An 'extern' DllImport function definition in C-style syntax */
cPrototype:
| EXTERN cRetType opt_access ident opt_HIGH_PRECEDENCE_APP LPAREN externArgs rparen
{ let rty, vis, nm, args = $2, $3, $4, $7
{ let mExtern = rhs parseState 1
let rty, vis, nm, args = $2, $3, $4, $7
let nmm = rhs parseState 3
let argsm = rhs parseState 6
let mBindLhs = lhs parseState
Expand All @@ -2760,10 +2761,11 @@ 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 = { LetKeyword = None; ExternKeyword = Some mExtern; EqualsRange = None }
let binding =
mkSynBinding
(xmlDoc, bindingPat)
(vis, false, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, Some rty, rhsExpr, mRhs, [], attrs, None, SynBindingTrivia.Zero)
(vis, false, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, Some rty, rhsExpr, mRhs, [], attrs, None, trivia)
[], [binding]) }

/* A list of arguments in an 'extern' DllImport function definition */
Expand Down Expand Up @@ -2882,7 +2884,7 @@ localBinding:
let mWhole = (unionRanges mLetKwd 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 = { LetKeyword = Some mLetKwd; EqualsRange = Some mEquals }
let trivia: SynBindingTrivia = { LetKeyword = Some mLetKwd; EqualsRange = Some mEquals; ExternKeyword = None }
mkSynBinding (xmlDoc, bindingPat) (vis, $1, $2, mWholeBindLhs, spBind, optReturnType, expr, mRhs, opts, attrs, None, trivia))
localBindingRange, localBindingBuilder }

Expand All @@ -2897,7 +2899,7 @@ 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 = { LetKeyword = Some mLetKwd; EqualsRange = Some mEquals }
let trivia: SynBindingTrivia = { LetKeyword = Some mLetKwd; EqualsRange = Some mEquals; ExternKeyword = None }
mkSynBinding (xmlDoc, bindingPat) (vis, $1, $2, mBindLhs, spBind, optReturnType, rhsExpr, mRhs, [], attrs, None, trivia))
mWhole, localBindingBuilder }

Expand All @@ -2910,7 +2912,7 @@ localBinding:
let localBindingBuilder =
(fun xmlDoc attrs vis mLetKwd ->
let spBind = DebugPointAtBinding.Yes (unionRanges mLetKwd mRhs)
let trivia = { LetKeyword = Some mLetKwd; EqualsRange = None }
let trivia = { LetKeyword = Some mLetKwd; EqualsRange = None; ExternKeyword = None }
let rhsExpr = arbExpr("localBinding2", mRhs)
mkSynBinding (xmlDoc, bindingPat) (vis, $1, $2, mBindLhs, spBind, optReturnType, rhsExpr, mRhs, [], attrs, None, trivia))
mWhole, localBindingBuilder }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@
<Compile Include="..\service\SyntaxTreeTests\AttributeTests.fs">
<Link>SyntaxTree\AttributeTests.fs</Link>
</Compile>
<Compile Include="..\service\SyntaxTreeTests\ExternTests.fs">
<Link>SyntaxTree\ExternTests.fs</Link>
</Compile>
<Compile Include="..\service\FileSystemTests.fs">
<Link>FileSystemTests.fs</Link>
</Compile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9419,11 +9419,13 @@ FSharp.Compiler.SyntaxTrivia.SynBindingTrivia
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: FSharp.Compiler.SyntaxTrivia.SynBindingTrivia Zero
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: FSharp.Compiler.SyntaxTrivia.SynBindingTrivia get_Zero()
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] ExternKeyword
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] LetKeyword
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_ExternKeyword()
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_LetKeyword()
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: System.String ToString()
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Void .ctor(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range])
FSharp.Compiler.SyntaxTrivia.SynBindingTrivia: Void .ctor(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.SynEnumCaseTrivia
FSharp.Compiler.SyntaxTrivia.SynEnumCaseTrivia: FSharp.Compiler.Text.Range EqualsRange
FSharp.Compiler.SyntaxTrivia.SynEnumCaseTrivia: FSharp.Compiler.Text.Range get_EqualsRange()
Expand Down
21 changes: 21 additions & 0 deletions tests/service/SyntaxTreeTests/ExternTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module FSharp.Compiler.Service.Tests.SyntaxTreeTests.ExternTests

open FSharp.Compiler.Service.Tests.Common
open FSharp.Compiler.Syntax
open FSharp.Compiler.SyntaxTrivia
open NUnit.Framework

[<Test>]
let ``extern keyword is present in trivia`` () =
let parseResults = getParseResults "extern void GetProcessHeap()"

match parseResults with
| ParsedInput.ImplFile(ParsedImplFileInput(contents = [
SynModuleOrNamespace.SynModuleOrNamespace(decls = [
SynModuleDecl.Let(bindings = [
SynBinding(trivia = { ExternKeyword = Some mExtern })
])
])
])) ->
assertRange (1, 0) (1, 6) mExtern
| _ -> Assert.Fail $"Could not get valid AST, got {parseResults}"