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

Improve handling of line directives #17536

Merged
merged 3 commits into from
Aug 16, 2024
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
6 changes: 5 additions & 1 deletion src/Compiler/SyntaxTree/ParseHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ let posOfLexPosition (p: Position) = mkPos p.Line p.Column

/// Get an F# compiler range from a lexer range
let mkSynRange (p1: Position) (p2: Position) =
mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition p2)
if p1.FileIndex = p2.FileIndex then
mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition p2)
else
// This means we had a #line directive in the middle of this syntax element.
mkFileIndexRange p1.FileIndex (posOfLexPosition p1) (posOfLexPosition (p1.ShiftColumnBy 1))

type LexBuffer<'Char> with

Expand Down
66 changes: 66 additions & 0 deletions tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Line.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
namespace CompilerDirectives

open Microsoft.FSharp.Control
open Xunit
open FSharp.Test.Compiler
open FSharp.Compiler.CodeAnalysis
open FSharp.Compiler.Text
open FSharp.Compiler.Syntax

module Line =

let checker = FSharpChecker.Create()

let parse (source: string) =
let langVersion = "preview"
let sourceFileName = __SOURCE_FILE__
let parsingOptions =
{ FSharpParsingOptions.Default with
SourceFiles = [| sourceFileName |]
LangVersionText = langVersion
ApplyLineDirectives = true
}
checker.ParseFile(sourceFileName, SourceText.ofString source, parsingOptions) |> Async.RunSynchronously


[<Literal>]
let private case1 = """module A
#line 1 "xyz.fs"
(
printfn ""
)
"""

[<Literal>]
let private case2 = """module A
(
#line 1 "xyz.fs"
printfn ""
)
"""

[<Literal>]
let private case3 = """module A
(
#line 1 "xyz.fs"
)
"""

[<Theory>]
[<InlineData(1, case1, "xyz.fs:(1,0--3,1)")>]
[<InlineData(2, case2, "Line.fs:(2,0--2,1)")>]
[<InlineData(3, case3, "Line.fs:(2,0--2,1)")>]
let ``check expr range interacting with line directive`` (case, source, expectedRange) =
let parseResults = parse source
if parseResults.ParseHadErrors then failwith "unexpected: parse error"
let exprRange =
match parseResults.ParseTree with
| ParsedInput.ImplFile(ParsedImplFileInput(contents = contents)) ->
let (SynModuleOrNamespace(decls = decls)) = List.exactlyOne contents
match List.exactlyOne decls with
| SynModuleDecl.Expr(_, range) -> $"{range.FileName}:{range}"
| _ -> failwith $"unexpected: not an expr"
| ParsedInput.SigFile _ -> failwith "unexpected: sig file"
if exprRange <> expectedRange then
failwith $"case{case}: expected: {expectedRange}, found {exprRange}"

Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace ErrorMessages
namespace CompilerDirectives

open Xunit
open FSharp.Test.Compiler

module HashDirectives =
module NonStringArgs =

[<InlineData("8.0")>]
[<InlineData("9.0")>]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
<Compile Include="..\service\FsUnit.fs">
<Link>FsUnit.fs</Link>
</Compile>
<Compile Include="CompilerDirectives\Line.fs" />
<Compile Include="CompilerDirectives\NonStringArgs.fs" />
<Compile Include="Conformance\BasicGrammarElements\AccessibilityAnnotations\Basic\Basic.fs" />
<Compile Include="Conformance\BasicGrammarElements\AccessibilityAnnotations\OnOverridesAndIFaceImpl\OnOverridesAndIFaceImpl.fs" />
<Compile Include="Conformance\BasicGrammarElements\AccessibilityAnnotations\OnTypeMembers\OnTypeMembers.fs" />
Expand Down Expand Up @@ -177,9 +179,9 @@
<Compile Include="EmittedIL\TestFunctions\TestFunctions.fs" />
<Compile Include="EmittedIL\Tuples\Tuples.fs" />
<Compile Include="EmittedIL\Nullness\NullnessMetadata.fs" />
<Compile Include="EmittedIL\FixedBindings\FixedBindings.fs" />
<Compile Include="ErrorMessages\TypedInterpolatedStringsTests.fs" />
<!--<Compile Include="EmittedIL\StructDefensiveCopy\StructDefensiveCopy.fs" />-->
<Compile Include="EmittedIL\FixedBindings\FixedBindings.fs" />
<Compile Include="ErrorMessages\UnsupportedAttributes.fs" />
<Compile Include="ErrorMessages\TailCallAttribute.fs" />
<Compile Include="ErrorMessages\IndexingSyntax.fs" />
Expand All @@ -196,7 +198,6 @@
<Compile Include="ErrorMessages\MissingExpressionTests.fs" />
<Compile Include="ErrorMessages\ModuleTests.fs" />
<Compile Include="ErrorMessages\NameResolutionTests.fs" />
<Compile Include="ErrorMessages\Directives.fs" />
<Compile Include="ErrorMessages\SuggestionsTests.fs" />
<Compile Include="ErrorMessages\TypeMismatchTests.fs" />
<Compile Include="ErrorMessages\UnitGenericAbstactType.fs" />
Expand Down
Loading