diff --git a/src/Directory.Build.props b/src/Directory.Build.props index dcef6ff4fb..33364963ee 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -15,6 +15,7 @@ true true snupkg + $(OtherFlags) --test:GraphBasedChecking --test:ParallelOptimization --test:ParallelIlxGen diff --git a/src/Fable.Cli/Fable.Cli.fsproj b/src/Fable.Cli/Fable.Cli.fsproj index 562e89f817..154d9aa91d 100644 --- a/src/Fable.Cli/Fable.Cli.fsproj +++ b/src/Fable.Cli/Fable.Cli.fsproj @@ -57,11 +57,13 @@ + + diff --git a/src/Fable.Cli/FileWatchers.fsi b/src/Fable.Cli/FileWatchers.fsi new file mode 100644 index 0000000000..0ba984e013 --- /dev/null +++ b/src/Fable.Cli/FileWatchers.fsi @@ -0,0 +1,45 @@ +module Fable.Cli.FileWatcher + +open System +open System.IO + +type IFileSystemWatcher = + inherit IDisposable + + [] + abstract OnFileChange: IEvent + + [] + abstract OnError: IEvent + + /// Directory path + abstract BasePath: string with get, set + abstract EnableRaisingEvents: bool with get, set + /// File name filters + abstract GlobFilters: string list + +/// An alternative file watcher based on polling. +/// ignoredDirectoryNameRegexes allows ignoring directories to improve performance. +type PollingFileWatcher = + new: + watchedDirectoryPath: string * ignoredDirectoryNameRegexes: string seq -> + PollingFileWatcher + + /// Defaults to false. Must be set to true to start raising events. + member EnableRaisingEvents: bool with get, set + interface IDisposable + +/// A wrapper around the immutable polling watcher, +/// implementing IFileSystemWatcher with its mutable BasePath. +type ResetablePollingFileWatcher = + new: + fileNameGlobFilters: string list * + ignoredDirectoryNameRegexes: string seq -> + ResetablePollingFileWatcher + + interface IFileSystemWatcher + +/// A FileSystemWatcher wrapper that implements the IFileSystemWatcher interface. +type DotnetFileWatcher = + new: globFilters: string list -> DotnetFileWatcher + interface IFileSystemWatcher diff --git a/src/Fable.Cli/Util.fsi b/src/Fable.Cli/Util.fsi new file mode 100644 index 0000000000..716540fd7d --- /dev/null +++ b/src/Fable.Cli/Util.fsi @@ -0,0 +1,204 @@ +namespace Fable.Cli + +#nowarn "3391" + +open System + +type RunProcess = + new: + exeFile: string * args: string list * ?watch: bool * ?fast: bool -> + RunProcess + + member ExeFile: string + member Args: string list + member IsWatch: bool + member IsFast: bool + +type CliArgs = + { + ProjectFile: string + RootDir: string + OutDir: string option + IsWatch: bool + Precompile: bool + PrecompiledLib: string option + PrintAst: bool + FableLibraryPath: string option + Configuration: string + NoRestore: bool + NoCache: bool + NoParallelTypeCheck: bool + SourceMaps: bool + SourceMapsRoot: string option + Exclude: string list + Replace: Map + RunProcess: RunProcess option + CompilerOptions: Fable.CompilerOptions + } + + member ProjectFileAsRelativePath: string + member RunProcessEnv: (string * string) list + +[] +module Log = + val newLine: string + /// To be called only at the beginning of the app + val makeVerbose: unit -> unit + val makeSilent: unit -> unit + val inSameLineIfNotCI: msg: string -> unit + val always: msg: string -> unit + val verbose: msg: Lazy -> unit + val warning: msg: string -> unit + val error: msg: string -> unit + val showFemtoMsg: show: (unit -> bool) -> unit + +module File = + val defaultFileExt: usesOutDir: bool -> language: Fable.Language -> string + + val changeExtensionButUseDefaultExtensionInFableModules: + lang: Fable.Language -> + isInFableModules: bool -> + filePath: string -> + fileExt: string -> + string + + val relPathToCurDir: path: string -> string + /// File.ReadAllText fails with locked files. See https://stackoverflow.com/a/1389172 + val readAllTextNonBlocking: path: string -> string + + val tryFindNonEmptyDirectoryUpwards: + opts: + {| + exclude: string list + matches: string list + |} -> + dir: string -> + string option + + val tryFindUpwards: fileName: string -> dir: string -> string option + + val tryNodeModulesBin: + workingDir: string -> exeFile: string -> string option + + /// System.IO.GetFullPath doesn't change the case of the argument in case insensitive file systems + /// even if it doesn't match the actual path, causing unexpected issues when comparing files later. + val getExactFullPath: pathName: string -> string + /// FAKE and other tools clean dirs but don't remove them, so check whether it doesn't exist or it's empty + val isDirectoryEmpty: dir: string -> bool + val safeDelete: path: string -> unit + val withLock: dir: string -> action: (unit -> 'T) -> 'T + +[] +module Process = + val startWithEnv: + envVars: (string * string) list -> + (string -> string -> string list -> unit) + + val runSyncWithEnv: + envVars: (string * string) list -> + workingDir: string -> + exePath: string -> + args: string list -> + int + + val runSync: + workingDir: string -> exePath: string -> args: string list -> int + +type PathResolver = + abstract TryPrecompiledOutPath: + sourceDir: string * relativePath: string -> string option + + abstract GetOrAddDeduplicateTargetDir: + importDir: string * addTargetDir: (Set -> string) -> string + +module Imports = + val getRelativePath: path: string -> pathTo: string -> string + + val getTargetAbsolutePath: + pathResolver: PathResolver -> + importPath: string -> + projDir: string -> + outDir: string -> + string + + val getImportPath: + pathResolver: PathResolver -> + sourcePath: string -> + targetPath: string -> + projDir: string -> + outDir: string option -> + importPath: string -> + string + +module Observable = + type SingleObservable<'T> = + new: dispose: (unit -> unit) -> SingleObservable<'T> + member Trigger: v: 'T -> unit + interface IObservable<'T> + + val throttle: ms: int -> obs: IObservable<'T> -> IObservable<'T array> + +[] +module ResultCE = + type ResultBuilder = + new: unit -> ResultBuilder + member Zero: Result + + member Bind: + v: Result<'d, 'e> * f: ('d -> Result<'f, 'e>) -> Result<'f, 'e> + + member Return: v: 'b -> Result<'b, 'c> + member ReturnFrom: v: 'a -> 'a + + val result: ResultBuilder + +module Json = + val read: path: string -> 'T + val write: path: string -> data: 'T -> unit + +module Performance = + val measure: f: (unit -> 'a) -> 'a * int64 + val measureAsync: f: (unit -> Async<'a>) -> Async<'a * int64> + +type PrecompiledFileJson = + { + RootModule: string + OutPath: string + } + +type PrecompiledInfoJson = + { + CompilerVersion: string + CompilerOptions: Fable.CompilerOptions + FableLibDir: string + Files: Map + InlineExprHeaders: string[] + } + +type PrecompiledInfoImpl = + new: + fableModulesDir: string * info: PrecompiledInfoJson -> + PrecompiledInfoImpl + + member CompilerVersion: string + member CompilerOptions: Fable.CompilerOptions + member Files: Map + member FableLibDir: string + member DllPath: string + member TryPrecompiledOutPath: normalizedFullPath: string -> string option + static member GetDllPath: fableModulesDir: string -> string + interface Fable.Transforms.State.PrecompiledInfo + static member GetPath: fableModulesDir: string -> string + + static member GetInlineExprsPath: + fableModulesDir: string * index: int -> string + + static member Load: fableModulesDir: string -> PrecompiledInfoImpl + + static member Save: + files: Map * + inlineExprs: (string * 'a) array * + compilerOptions: Fable.CompilerOptions * + fableModulesDir: string * + fableLibDir: string -> + unit diff --git a/src/Fable.Transforms/FSharp2Fable.fsi b/src/Fable.Transforms/FSharp2Fable.fsi new file mode 100644 index 0000000000..f043a925d6 --- /dev/null +++ b/src/Fable.Transforms/FSharp2Fable.fsi @@ -0,0 +1,18 @@ +module rec Fable.Transforms.FSharp2Fable.Compiler + +open FSharp.Compiler.Symbols +open Fable +open Fable.AST + +val getRootFSharpEntities: + declarations: FSharpImplementationFileDeclaration list -> FSharpEntity seq + +val getRootModule: + declarations: FSharpImplementationFileDeclaration list -> string + +val getInlineExprs: + fileName: string -> + declarations: FSharpImplementationFileDeclaration list -> + (string * InlineExprLazy) list + +val transformFile: com: Compiler -> Fable.File diff --git a/src/Fable.Transforms/Fable.Transforms.fsproj b/src/Fable.Transforms/Fable.Transforms.fsproj index 173effc88e..1b24b1bc6e 100644 --- a/src/Fable.Transforms/Fable.Transforms.fsproj +++ b/src/Fable.Transforms/Fable.Transforms.fsproj @@ -24,7 +24,9 @@ + + diff --git a/src/Fable.Transforms/FableTransforms.fsi b/src/Fable.Transforms/FableTransforms.fsi new file mode 100644 index 0000000000..87ce3df078 --- /dev/null +++ b/src/Fable.Transforms/FableTransforms.fsi @@ -0,0 +1,20 @@ +module Fable.Transforms.FableTransforms + +open Fable +open Fable.AST.Fable + +val isIdentCaptured: identName: string -> expr: Expr -> bool +val isTailRecursive: identName: string -> expr: Expr -> bool * bool +val replaceValues: replacements: Map -> expr: Expr -> Expr +val uncurryType: typ: Type -> Type + +val getTransformations: _com: Compiler -> (#Compiler -> Expr -> Expr) list + +val transformDeclaration: + transformations: (Compiler -> Expr -> Expr) list -> + com: Compiler -> + file: File -> + decl: Declaration -> + Declaration + +val transformFile: com: Compiler -> file: File -> File