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

Fix ProjectFileNames order when getting project options from script #594

Merged
merged 6 commits into from
Jul 20, 2016
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
55 changes: 25 additions & 30 deletions src/fsharp/CompileOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4976,37 +4976,32 @@ module private ScriptPreprocessClosure =
match closureDirective with
| ClosedSourceFile _ as csf -> [csf]
| SourceFile(filename,m,source) ->
let filename = FileSystem.GetFullPathShim(filename)
if observedSources.HaveSeen(filename) then []
else
observedSources.SetSeen(filename)

let errors = ref []
let warnings = ref []
let errorLogger =
{ new ErrorLogger("FindClosure") with
member x.ErrorSinkImpl(e) = errors := e :: !errors
member x.WarnSinkImpl(e) = warnings := e :: !warnings
member x.ErrorCount = (!errors).Length }

use unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> errorLogger)
let pathOfMetaCommandSource = Path.GetDirectoryName(filename)
match ParseScriptText(filename,source,!tcConfig,codeContext,lexResourceManager,errorLogger) with
| Some(input) ->
let tcConfigResult, noWarns = ApplyMetaCommandsFromInputToTcConfigAndGatherNoWarn !tcConfig (input,pathOfMetaCommandSource)
tcConfig := tcConfigResult
let errors = ref []
let warnings = ref []
let errorLogger =
{ new ErrorLogger("FindClosure") with
member x.ErrorSinkImpl(e) = errors := e :: !errors
member x.WarnSinkImpl(e) = warnings := e :: !warnings
member x.ErrorCount = (!errors).Length }

use unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> errorLogger)
let pathOfMetaCommandSource = Path.GetDirectoryName(filename)
match ParseScriptText(filename,source,!tcConfig,codeContext,lexResourceManager,errorLogger) with
| Some(input) ->
let tcConfigResult, noWarns = ApplyMetaCommandsFromInputToTcConfigAndGatherNoWarn !tcConfig (input,pathOfMetaCommandSource)
tcConfig := tcConfigResult

let AddFileIfNotSeen(m,filename) =
if observedSources.HaveSeen(filename) then []
else
if IsScript(filename) then SourceFileOfFilename(filename,m,tcConfigResult.inputCodePage)
else
observedSources.SetSeen(filename)
[ClosedSourceFile(filename,m,None,[],[],[])] // Don't traverse into .fs leafs.
let AddFileIfNotSeen(m,filename) =
if observedSources.HaveSeen(filename) then []
else
observedSources.SetSeen(filename)
if IsScript(filename) then SourceFileOfFilename(filename,m,tcConfigResult.inputCodePage)
else [ClosedSourceFile(filename,m,None,[],[],[])] // Don't traverse into .fs leafs.

let loadedSources = (!tcConfig).GetAvailableLoadedSources() |> List.rev |> List.map AddFileIfNotSeen |> List.concat
ClosedSourceFile(filename,m,Some(input),!errors,!warnings,!noWarns) :: loadedSources |> List.map FindClosure |> List.concat // Final closure is in reverse order. Keep the closed source at the top.
| None -> [ClosedSourceFile(filename,m,None,!errors,!warnings,[])]
let loadedSources = (!tcConfig).GetAvailableLoadedSources() |> List.map AddFileIfNotSeen |> List.concat
(loadedSources |> List.map FindClosure |> List.concat)
@ [ClosedSourceFile(filename,m,Some(input),!errors,!warnings,!noWarns)]
| None -> [ClosedSourceFile(filename,m,None,!errors,!warnings,[])]

closureDirectives |> List.map FindClosure |> List.concat, !tcConfig

Expand All @@ -5024,7 +5019,7 @@ module private ScriptPreprocessClosure =
let sourceFiles = ref []
let sourceInputs = ref []
let globalNoWarns = ref []
for directive in closureDirectives do
for directive in List.rev closureDirectives do
match directive with
| ClosedSourceFile(filename,m,input,_,_,noWarns) ->
let filename = FileSystem.GetFullPathShim(filename)
Expand Down
16 changes: 16 additions & 0 deletions tests/service/ProjectOptionsTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,22 @@ let ``Project file parsing -- report files``() =
for f in Directory.EnumerateFiles(@"C:\Program Files (x86)\Microsoft SDKs\F#\4.0\","*",SearchOption.AllDirectories) do
printfn "File: %s" f

[<Test>]
let ``Test ProjectFileNames order for GetProjectOptionsFromScript`` () = // See #594
let test scriptName expected =
let scriptPath = __SOURCE_DIRECTORY__ + @"/data/ScriptProject/" + scriptName + ".fsx"
let scriptSource = File.ReadAllText scriptPath
let projOpts =
checker.GetProjectOptionsFromScript(scriptPath, scriptSource)
|> Async.RunSynchronously
projOpts.ProjectFileNames
|> Array.map Path.GetFileNameWithoutExtension
|> (=) expected
|> shouldEqual true
test "Main1" [|"BaseLib1"; "Lib1"; "Lib2"; "Main1"|]
test "Main2" [|"BaseLib1"; "Lib1"; "Lib2"; "Lib3"; "Main2"|]
test "Main3" [|"Lib3"; "Lib4"; "Main3"|]
test "Main4" [|"BaseLib2"; "Lib5"; "BaseLib1"; "Lib1"; "Lib2"; "Main4"|]

#endif

Expand Down
3 changes: 3 additions & 0 deletions tests/service/data/ScriptProject/BaseLib1.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module BaseLib1

let add2 x = x + 2
3 changes: 3 additions & 0 deletions tests/service/data/ScriptProject/BaseLib2.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module BaseLib2

let add10 x = x + 10
2 changes: 2 additions & 0 deletions tests/service/data/ScriptProject/Lib1.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#load "BaseLib1.fs"
let add3 = BaseLib1.add2 >> ((+) 1)
2 changes: 2 additions & 0 deletions tests/service/data/ScriptProject/Lib2.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#load "BaseLib1.fs"
let add4 = BaseLib1.add2 >> ((+) 2)
3 changes: 3 additions & 0 deletions tests/service/data/ScriptProject/Lib3.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module Lib3

let add6 = ((+) 6)
3 changes: 3 additions & 0 deletions tests/service/data/ScriptProject/Lib4.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module Lib4

let add8 = ((+) 8)
2 changes: 2 additions & 0 deletions tests/service/data/ScriptProject/Lib5.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#load "BaseLib2.fs"
let add12 = BaseLib2.add10 >> ((+) 2)
4 changes: 4 additions & 0 deletions tests/service/data/ScriptProject/Main1.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#load "Lib1.fsx"
#load "Lib2.fsx"
Lib1.add3 5 |> printfn "%i"
Lib2.add4 5 |> printfn "%i"
6 changes: 6 additions & 0 deletions tests/service/data/ScriptProject/Main2.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#load "Lib1.fsx"
#load "Lib2.fsx"
#load "Lib3.fs"
Lib1.add3 5 |> printfn "%i"
Lib2.add4 5 |> printfn "%i"
Lib3.add6 5 |> printfn "%i"
4 changes: 4 additions & 0 deletions tests/service/data/ScriptProject/Main3.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#load "Lib3.fs"
#load "Lib4.fs"
Lib3.add6 5 |> printfn "%i"
Lib4.add8 5 |> printfn "%i"
6 changes: 6 additions & 0 deletions tests/service/data/ScriptProject/Main4.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#load "Lib5.fsx"
#load "Lib1.fsx"
#load "Lib2.fsx"
Lib1.add3 5 |> printfn "%i"
Lib2.add4 5 |> printfn "%i"
Lib5.add12 5 |> printfn "%i"