Skip to content

Separation & major refactoring of core modules #40

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

Merged
merged 17 commits into from
Jan 7, 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ _opam/
# Outputs
output
*.fs.js*
output*.txt

# Test artifacts
test/jsoo/src/*.mli
Expand Down
24 changes: 15 additions & 9 deletions build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,22 +77,29 @@ Target.create "YarnInstall" <| fun _ ->

Target.create "Prepare" ignore

Target.create "BuildOnly" <| fun _ ->
Target.create "BuildForPublish" <| fun _ ->
dotnetExec "fable" $"{srcDir} --sourceMaps --run webpack --mode=production"

Target.create "BuildForTest" <| fun _ ->
dotnetExec "fable" $"{srcDir} --sourceMaps --define DEBUG --run webpack --mode=development"

Target.create "Build" ignore

Target.create "Watch" <| fun _ ->
dotnetExec "fable" $"watch {srcDir} --sourceMaps --define DEBUG --run webpack -w --mode=development"

Target.create "TestComplete" ignore

"Clean"
==> "YarnInstall"
==> "Restore"
==> "Prepare"
==> "Build"

"Prepare"
?=> "BuildOnly"
?=> "BuildForTest"
?=> "TestComplete"
?=> "BuildForPublish"
==> "Build"

"Prepare"
Expand Down Expand Up @@ -128,13 +135,13 @@ module Test =
// "full" packages involving a lot of dependencies (which includes some "safe" packages)
"safe", !! "node_modules/@types/scheduler/tracing.d.ts", [];
"full", !! "node_modules/csstype/index.d.ts", [];
"safe", !! "node_modules/@types/prop-types/index.d.ts", [];
"safe", !! "node_modules/@types/prop-types/index.d.ts", ["--rec-module=off"];
"full", !! "node_modules/@types/react/index.d.ts" ++ "node_modules/@types/react/global.d.ts", [];
"full", !! "node_modules/@types/react-modal/index.d.ts", [];

// "safe" package which depends on another "safe" package
"safe", !! "node_modules/@types/yargs-parser/index.d.ts", [];
"safe", !! "node_modules/@types/yargs/index.d.ts", [];
"safe", !! "node_modules/@types/yargs/index.d.ts", ["--rec-module=off"];
]

for preset, package, additionalOptions in packages do
Expand All @@ -153,7 +160,7 @@ Target.create "TestJsooGenerateBindings" <| fun _ -> Test.Jsoo.generateBindings
Target.create "TestJsooBuild" <| fun _ -> Test.Jsoo.build ()
Target.create "TestJsoo" ignore

"BuildOnly"
"BuildForTest"
==> "TestJsooClean"
==> "TestJsooGenerateBindings"
==> "TestJsooBuild"
Expand All @@ -164,10 +171,9 @@ Target.create "TestOnly" ignore

"TestJsoo"
==> "TestOnly"
==> "TestComplete"
==> "Test"

"Build" ==> "Test"

// Publish targets

module Publish =
Expand Down Expand Up @@ -225,15 +231,15 @@ Target.create "PublishJsoo" <| fun _ ->
Publish.Jsoo.updateVersion ()
Publish.Jsoo.testBuild ()

"BuildOnly"
"BuildForPublish"
==> "PublishNpm"
==> "PublishJsoo"
==> "PublishOnly"
==> "Publish"

"TestJsoo" ==> "PublishJsoo"

"Build" ==> "Publish"
"Build" ?=> "Test" ?=> "Publish"

Target.create "All" ignore

Expand Down
11 changes: 8 additions & 3 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,24 @@ Overview for Developers

Modules with **\[\<AutoOpen\>\]** does not require `open` to use.

- `src/`
- `Bindings/` ... bindings to JS libraries
- `lib/` ... target-agnostic part of the tool (will be separated to a different repo in near future)
- `Bindings/` ... bindings to JS libraries (typescript, browser-or-node)
- `Extensions.fs` ... **\[\<AutoOpen\>\]** extensions for standard library and JS libraries
- `DataTypes/` ... common data structures and algorithm
- `Text.fs` ... efficient rope with `O(1)` concat & `O(n)` stringify
- `Trie.fs` ... trie based on immutable map
- `Graph.fs` ... graph based on immutable map & graph algorithms
- `Common.fs` ... **\[\<AutoOpen\>\]** global command line options, types, and modules
- `Common.fs` ... global interfaces
- `Syntax.fs` ... AST for parsed TypeScAript code
- `Naming.fs` ... naming helpers
- `JsHelper.fs` ... helper functions for JavaScript-related things e.g. NPM packages and ES6 module names.
- `TypeScriptHelper.fs` ... helper functions for using TypeScript Compiler API
- `Typer.fs` ... functions for resolving and manipulating AST
- `Parser.fs` ... functions for converting TS syntax tree to our AST
- `src/` ... target-dependent part of the tool
- `Bindings/` ... bindings to JS libraries (yargs)
- `Extensions.fs` ... **\[\<AutoOpen\>\]** extensions for standard library and JS libraries
- `Common.fs` ... **\[\<AutoOpen\>\]** global command line options, types, and modules
- `Target.fs` ... generic definitions for each targets (`ITarget<_>`)
- `Targets/` ... targets should be placed into here
- `ParserTest.fs` ... debug target to test parser and typer
Expand Down
11 changes: 11 additions & 0 deletions lib/Bindings/BrowserOrNode.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// ts2fable 0.7.1
module rec BrowserOrNode
open System
open Fable.Core
open Fable.Core.JS

let [<Import("isBrowser","browser-or-node")>] isBrowser: bool = jsNative
let [<Import("isWebWorker","browser-or-node")>] isWebWorker: bool = jsNative
let [<Import("isNode","browser-or-node")>] isNode: bool = jsNative
let [<Import("isJsDom","browser-or-node")>] isJsDom: bool = jsNative
let [<Import("isDeno","browser-or-node")>] isDeno: bool = jsNative
File renamed without changes.
46 changes: 46 additions & 0 deletions lib/Common.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module Ts2Ml.Common

type ILogger =
abstract tracef: fmt:Printf.StringFormat<'T, unit> -> 'T
abstract warnf: fmt:Printf.StringFormat<'T, unit> -> 'T
abstract errorf: fmt:Printf.StringFormat<'T, 'Result> -> 'T

type IOptions =
abstract followRelativeReferences: bool with get, set

type IContext<'Options when 'Options :> IOptions> =
abstract options: 'Options
abstract logger: ILogger

type IContext =
inherit IContext<IOptions>

/// Stateful class to rename overloaded identifiers.
type OverloadRenamer(?rename: string -> int -> string, ?used: Set<string * string>) =
let rename =
match rename with
| Some f -> f
| None -> (fun s i -> s + (String.replicate i "'"))
let m = new MutableMap<string * string, int>()
do
match used with
| None -> ()
| Some used ->
for name in used |> Set.toSeq do
m.[name] <- 0

/// If the `name` is already used in the same `category`, returns the new renamed name.
///
/// Otherwise, (even if it is used in a different `category`), returns the original name.
///
/// `category` can be arbitrary, but it is intended for something like `value`, `type`, `module`, etc.
member __.Rename (category: string) (name: string) =
match m.TryGetValue((category, name)) with
| true, i ->
m.[(category, name)] <- i + 1
let name' = rename name (i+1)
m.[(category, name')] <- 0
name'
| false, _ ->
m.[(category, name)] <- 0
name
18 changes: 18 additions & 0 deletions src/DataTypes/Graph.fs → lib/DataTypes/Graph.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@ namespace DataTypes
type Graph<'node when 'node: comparison> = Map<'node, 'node list>

module Graph =
let empty : Graph<_> = Map.empty

let add origin target (graph: Graph<_>) : Graph<_> =
match graph |> Map.tryFind origin with
| None -> graph |> Map.add origin [target]
| Some targets -> graph |> Map.add origin (target :: targets |> List.distinct)

let addEdge (origin, target) (graph: Graph<_>) : Graph<_> = add origin target graph

let remove origin target (graph: Graph<_>) : Graph<_> =
match graph |> Map.tryFind origin with
| Some targets -> graph |> Map.add origin (targets |> List.except [target])
| None -> graph

let removeEdge (origin, target) (graph: Graph<_>) : Graph<_> = remove origin target graph

let rec private dfsImpl' g (used, ordRev) v =
let used = used |> Set.add v
let used, ordRev =
Expand All @@ -19,11 +35,13 @@ module Graph =

let ofEdges (edges: ('a * 'a) list) : Graph<_> =
edges
|> List.distinct
|> List.groupBy fst
|> List.fold (fun state (k, xs) -> state |> Map.add k (xs |> List.map snd)) Map.empty

let ofEdgesRev (edges: ('a * 'a) list) : Graph<_> =
edges
|> List.distinct
|> List.groupBy snd
|> List.fold (fun state (k, xs) -> state |> Map.add k (xs |> List.map fst)) Map.empty

Expand Down
2 changes: 2 additions & 0 deletions src/DataTypes/Text.fs → lib/DataTypes/Text.fs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
namespace DataTypes

open Ts2Ml.Extensions

[<StructuredFormatDisplay("{AsString}")>]
type text =
private
Expand Down
22 changes: 22 additions & 0 deletions src/DataTypes/Trie.fs → lib/DataTypes/Trie.fs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,28 @@ module Trie =
| Some child -> { t with children = t.children |> Map.add k (setSubTrie ks subTrie child) }
| None -> { t with children = t.children |> Map.add k (setSubTrie ks subTrie empty) }

let rec getLongestMatch (ks: 'k list) (trie: Trie<'k, 'v>) : {| value: 'v option; rest: 'k list |} =
match ks with
| [] -> {| value = trie.value; rest = [] |}
| k :: ks ->
match Map.tryFind k trie.children with
| Some child -> getLongestMatch ks child
| None -> {| value = trie.value; rest = k :: ks |}

let collectPath (ks: 'k list) (collector: 'k list -> 'v option -> 'a option) (trie: Trie<'k, 'v>) : 'a list =
let rec go acc ks trie =
let acc =
match collector ks trie.value with
| Some a -> a :: acc
| None -> acc
match ks with
| [] -> List.rev acc
| k :: ks ->
match Map.tryFind k trie.children with
| Some child -> go acc ks child
| None -> List.rev acc
go [] ks trie

let fold (f: 'state -> 'k list -> 'v -> 'state) (s: 'state) (t: Trie<'k, 'v>) =
let rec go ksRev state t =
let state =
Expand Down
Loading