diff --git a/.gitignore b/.gitignore index 3005fad..ecda0b5 100644 --- a/.gitignore +++ b/.gitignore @@ -42,4 +42,9 @@ node_modules/ .fake # Wasm example files -examples/*.wasm \ No newline at end of file +examples/*.wasm + + +# Clojure ignore due to VS Code extensions +.clj-kondo/ +.lsp/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..9b40dec --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "test/tinyfs_testprojects"] + path = test/tinyfs_testprojects + url = git@github.com:morgankenyon/tinyfs_testprojects.git diff --git a/cli/Arguments.fs b/cli/Arguments.fs index f333c23..3a855d5 100644 --- a/cli/Arguments.fs +++ b/cli/Arguments.fs @@ -44,22 +44,30 @@ let runPrint print = printfn "%s" print Ok() +let parseFsProjectFile (fileInfo: FileInfo) = + + [] + let compileFile (filename: string) = printfn "Compiling: %s" filename - let fileText = System.IO.File.ReadAllText filename - - let name = System.IO.Path.GetFileNameWithoutExtension filename let fileInfo = new System.IO.FileInfo(filename) - let directory = fileInfo.DirectoryName - let wasmFilename = $"{directory}{Path.DirectorySeparatorChar}{name}.wasm" + if fileInfo.Extension = "fs" then + let fileText = System.IO.File.ReadAllText filename + + let name = System.IO.Path.GetFileNameWithoutExtension filename + let directory = fileInfo.DirectoryName + let wasmFilename = $"{directory}{Path.DirectorySeparatorChar}{name}.wasm" - let wasmBytes = EndToEnd.compile fileText |> List.toArray + let wasmBytes = EndToEnd.compile fileText |> List.toArray - System.IO.File.WriteAllBytes(wasmFilename, wasmBytes) - printfn "Compiled to: %s" wasmFilename + System.IO.File.WriteAllBytes(wasmFilename, wasmBytes) + printfn "Compiled to: %s" wasmFilename - wasmFilename + wasmFilename + else + printfn "%s" "FS Proj baby" + "test" let runFile (filename: string) = printfn "Running: %s" filename diff --git a/src/FSharpToAst.fs b/src/FSharpToAst.fs index eae8e30..78fbf70 100644 --- a/src/FSharpToAst.fs +++ b/src/FSharpToAst.fs @@ -1,8 +1,10 @@ module TinyFS.Core.FSharpToAst open FSharp.Compiler.CodeAnalysis -open System.IO open FSharp.Compiler.Text +open Ionide.ProjInfo + +open System.IO let parseAndCheckSingleFile (checker: FSharpChecker) (input: string) = let file = Path.ChangeExtension(System.IO.Path.GetTempFileName(), ".fsx") @@ -15,6 +17,39 @@ let parseAndCheckSingleFile (checker: FSharpChecker) (input: string) = checker.ParseAndCheckProject(projOptions) |> Async.RunSynchronously +let sysLib nm = + let sysDir = + System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() + let (++) a b = Path.Combine(a, b) + sysDir ++ nm + ".dll" + +let fsCorePath () = + "C:\Program Files\dotnet\sdk\9.0.200\FSharp\FSharp.Core.dll" + +let parseAndCheckProject (checker: FSharpChecker) (projectPath: string) (projectFilePath: string) = + // let file = new System.IO.FileInfo(projectPath); + // file.Directory.Create(); + let projectDirectory: DirectoryInfo = Directory.CreateDirectory(projectPath); + let toolsPath = Init.init projectDirectory None + let defaultLoader: IWorkspaceLoader = WorkspaceLoader.Create(toolsPath, []) + let projectOptions = defaultLoader.LoadProjects([ projectPath ]) |> Seq.toArray + let fcsProjectOptions = + FCS.mapManyOptions projectOptions + |> Seq.toList + let args: string array = + [| + yield $"{projectPath}/Library.fs" + |] + let projectOptions = + checker.GetProjectOptionsFromCommandLineArgs(projectFilePath, args) // projectFilePath args // GetProjectOptionsFromProjectFile(projectFilePath) + + // Parse and check the entire project + let projectResults = + checker.ParseAndCheckProject(projectOptions) + |> Async.RunSynchronously + + projectResults + let getDeclarations checker (input: string) = let checkProjectResults = parseAndCheckSingleFile checker input let checkedFile = checkProjectResults.AssemblyContents.ImplementationFiles.[0] @@ -31,3 +66,19 @@ let getDeclarations checker (input: string) = failwith msg else checkedFile.Declarations + +let getDeclarationsFromProject checker (projectPath: string) (projectFilePath: string) = + let checkProjectResults = parseAndCheckProject checker projectPath projectFilePath + + // Now you can work with the full project results + // Example: get all the declarations in the project + let declarations = + checkProjectResults.AssemblyContents.ImplementationFiles + |> List.map (fun f -> f.Declarations) + |> List.collect id + + declarations + //for file in checkProjectResults.AssemblyContents.ImplementationFiles do + // for decl in file.Declarations do + // // Process declarations + // printfn " Declaration: %A" decl. diff --git a/src/TinyFS.Core.fsproj b/src/TinyFS.Core.fsproj index 612a0fa..c5c35cc 100644 --- a/src/TinyFS.Core.fsproj +++ b/src/TinyFS.Core.fsproj @@ -30,6 +30,10 @@ + + + + diff --git a/test/FSharpToAstTests.fs b/test/FSharpToAstTests.fs index 58e835d..1587aa9 100644 --- a/test/FSharpToAstTests.fs +++ b/test/FSharpToAstTests.fs @@ -1,23 +1,33 @@ module TinyFS.Test.FSharpToAstTests open Faqt +open FSharp.Compiler.CodeAnalysis +open System.Reflection +open System +open System.IO open TinyFS.Core.FSharpToAst -open TinyFS.Test.Helpers open Xunit -open FSharp.Compiler.CodeAnalysis -//let checker: FSharpChecker = FSharpChecker.Create(keepAssemblyContents = true) -//[] -//let ``Can convert simple let statement to ast`` () = -// let input = -// $""" -//module Test +let checker: FSharpChecker = FSharpChecker.Create(keepAssemblyContents = true) +let GetDirectoryPath(assembly: Assembly) = + let filePath = (new Uri(assembly.Location)).LocalPath; + Path.GetDirectoryName(filePath); -//let x = 1 -//""" +let joinWithOpSeparator (parts: string list) = + List.reduce (fun a b -> $"{a}{Path.DirectorySeparatorChar}{b}") parts +[] +let ``Can convert simple let statement to ast`` () = + + let localDir = GetDirectoryPath(Assembly.GetExecutingAssembly()) + let testProjectPath = + [ localDir; "tinyfs_testprojects"; "HelloWorld" ] + |> joinWithOpSeparator + let testProjectDir = + [ localDir; "tinyfs_testprojects"; "HelloWorld"; "HelloWorld.fsproj" ] + |> joinWithOpSeparator -// let declarations = getDeclarations checker input -// declarations.Should().HaveLength(1) + let declarations = getDeclarationsFromProject checker testProjectPath testProjectDir + declarations.Should().HaveLength(1) //[] //let ``Can convert several let statements to ast`` () = diff --git a/test/TinyFS.Test.fsproj b/test/TinyFS.Test.fsproj index ee7cc57..3ea9950 100644 --- a/test/TinyFS.Test.fsproj +++ b/test/TinyFS.Test.fsproj @@ -7,6 +7,15 @@ + + PreserveNewest + + + + PreserveNewest + + + @@ -16,6 +25,8 @@ + + diff --git a/test/tinyfs_testprojects b/test/tinyfs_testprojects new file mode 160000 index 0000000..e791676 --- /dev/null +++ b/test/tinyfs_testprojects @@ -0,0 +1 @@ +Subproject commit e79167604385afbebe186ff9aa12e8792621b0ae