Skip to content

Commit 8a6805f

Browse files
committed
Rebase
1 parent 5573e10 commit 8a6805f

File tree

4 files changed

+77
-31
lines changed

4 files changed

+77
-31
lines changed

lib/Extensions.fs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ module String =
5151
state.Replace(e, "\\" + e)
5252
) s
5353

54+
module Option =
55+
let iterNone f = function
56+
| Some x -> Some x
57+
| None -> f (); None
58+
5459
module Result =
5560
let toOption result =
5661
match result with Ok x -> Some x | Error _ -> None
@@ -101,7 +106,11 @@ open Fable.Core.JsInterop
101106

102107
type JS.ObjectConstructor with
103108
[<Emit("$0.entries($1)")>]
104-
member __.entries (x: 'a) : (string * obj) [] = jsNative
109+
member __.entries (_: 'a) : (string * obj) [] = jsNative
110+
111+
type JS.NumberConstructor with
112+
[<Emit("$0.isSafeInteger($1)")>]
113+
member __.isSafeInteger (_: float) : bool = jsNative
105114

106115
type JSRecord<'TKey, 'TValue> =
107116
[<EmitIndexer>]
@@ -157,6 +166,9 @@ module Path =
157166
let dirname (path: string) : string =
158167
Node.path.dirname(path)
159168

169+
let basename (path: string) : string =
170+
Node.path.basename(path)
171+
160172
let join (paths: string list) : string =
161173
Node.path.join(Array.ofList paths)
162174

lib/JsHelper.fs

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ type IPackageJson =
4545
abstract version: string
4646
abstract types: string option
4747
abstract typings: string option
48-
abstract exports: JSRecord<string, IPackageExportItem> option
48+
abstract exports: JSRecord<string, U2<string, IPackageExportItem>> option
4949

5050
let getPackageInfo (exampleFilePath: string) : Syntax.PackageInfo option =
5151
nodeOnly <| fun () ->
@@ -77,23 +77,28 @@ let getPackageInfo (exampleFilePath: string) : Syntax.PackageInfo option =
7777
| Some exports ->
7878
[
7979
for k, v in exports.entries do
80-
match v.types with
81-
| None -> ()
82-
| Some types ->
83-
if JS.typeof types = "string" then
84-
yield k, !!types
85-
else
86-
let types = !!types : IPackageExportItemEntry
87-
match types.``default`` with
88-
| Some v -> yield k, v
89-
| None ->
90-
yield!
91-
types.entries
92-
|> Array.tryPick (fun (_, v) ->
93-
if JS.typeof v = "string" && v.EndsWith(".d.ts") then Some v
94-
else None)
95-
|> Option.map (fun v -> k, v)
96-
|> Option.toList
80+
if JS.typeof v = "string" then
81+
let v = !!v : string
82+
if v.EndsWith(".d.ts") then yield k, v
83+
else
84+
let v = !!v : IPackageExportItem
85+
match v.types with
86+
| None -> ()
87+
| Some types ->
88+
if JS.typeof types = "string" then
89+
yield k, !!types
90+
else
91+
let types = !!types : IPackageExportItemEntry
92+
match types.``default`` with
93+
| Some v -> yield k, v
94+
| None ->
95+
yield!
96+
types.entries
97+
|> Array.tryPick (fun (_, v) ->
98+
if JS.typeof v = "string" && v.EndsWith(".d.ts") then Some v
99+
else None)
100+
|> Option.map (fun v -> k, v)
101+
|> Option.toList
97102
]
98103

99104
let indexFile =
@@ -141,18 +146,18 @@ let inferPackageInfoFromFileName (sourceFile: Path.Absolute) : {| name: string;
141146
|> fun x ->
142147
let inm = x.LastIndexOf "node_modules"
143148
if inm = -1 then x
144-
else x.Substring(inm+13)
149+
else x.Substring(inm)
145150
|> String.split "/"
146151
|> List.ofArray
147152
match parts with
148-
| [] -> None
149-
| "@types" :: name :: rest ->
153+
| "node_modules" :: "@types" :: name :: rest ->
150154
let name = if name.Contains("__") then "@" + name.Replace("__", "/") else name
151155
Some {| name = name; isDefinitelyTyped = true; rest = rest |}
152-
| user :: name :: rest when user.StartsWith("@") ->
153-
Some {| name = user + "/" + name; isDefinitelyTyped = true; rest = rest |}
154-
| name :: rest ->
155-
Some {| name = name; isDefinitelyTyped = true; rest = rest |}
156+
| "node_modules" :: user :: name :: rest when user.StartsWith("@") ->
157+
Some {| name = user + "/" + name; isDefinitelyTyped = false; rest = rest |}
158+
| "node_modules" :: name :: rest ->
159+
Some {| name = name; isDefinitelyTyped = false; rest = rest |}
160+
| _ -> None
156161

157162
let inline stripExtension path =
158163
path |> String.replace ".ts" "" |> String.replace ".d" ""
@@ -184,7 +189,8 @@ let getJsModuleName (info: Syntax.PackageInfo option) (sourceFile: Path.Absolute
184189
Path.join [info.name; submodule] |> Heuristic
185190
| None ->
186191
match inferPackageInfoFromFileName sourceFile with
187-
| None -> Unknown
192+
| None ->
193+
Path.basename sourceFile |> stripExtension |> Heuristic
188194
| Some info ->
189195
if info.isDefinitelyTyped then
190196
let rest =

lib/Parser.fs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -707,12 +707,21 @@ module private ParserImpl =
707707
match getPropertyName em.name with
708708
| Some name ->
709709
let value =
710+
let inline fallback () =
711+
match ctx.checker.getConstantValue(!^em) with
712+
| None -> None
713+
| Some (U2.Case1 str) -> Some (LString str)
714+
| Some (U2.Case2 num) ->
715+
if Fable.Core.JS.Constructors.Number.isSafeInteger(num) then Some (LInt (int num))
716+
else Some (LFloat num)
710717
match em.initializer with
711-
| None -> None
718+
| None -> fallback ()
712719
| Some ep ->
713720
match readLiteral ep with
714-
| Some ((LInt _ | LString _) as l) -> Some l
715-
| _ -> nodeWarn ctx ep "enum value '%s' for case '%s' not supported" (ep.getText()) name; None
721+
| Some ((LInt _ | LFloat _ | LString _) as l) -> Some l
722+
| _ ->
723+
fallback () |> Option.iterNone (fun () ->
724+
nodeWarn ctx ep "enum value '%s' for case '%s' not supported" (ep.getText()) name)
716725
let comments = readCommentsForNamedDeclaration ctx em
717726
Some { comments = comments; loc = Node.location em; name = name; value = value }
718727
| None -> nodeWarn ctx em "unsupported enum case name '%s'" (getText em.name); None

lib/Typer.fs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1376,6 +1376,25 @@ module ResolvedUnion =
13761376
resolveUnionMap <- resolveUnionMap |> Map.add u result
13771377
result
13781378

1379+
let inferEnumCaseValue (stmts: Statement list) : Statement list =
1380+
let rec go = function
1381+
| Enum e ->
1382+
let f (state: Literal option) (c: EnumCase) : EnumCase * Literal option =
1383+
match c.value with
1384+
| Some v -> c, Some v
1385+
| None ->
1386+
let v =
1387+
match state with
1388+
| None -> Some (LInt 0)
1389+
| Some (LInt n) -> Some (LInt (n+1))
1390+
| Some (LFloat f) -> Some (LFloat (f+1.0))
1391+
| Some _ -> None
1392+
{ c with value = v }, v
1393+
Enum { e with cases = e.cases |> List.mapFold f None |> fst }
1394+
| Module m -> Module { m with statements = m.statements |> List.map go }
1395+
| s -> s
1396+
stmts |> List.map go
1397+
13791398
let rec mergeStatements (stmts: Statement list) =
13801399
let mutable result : Choice<Statement, Class ref, Module ref> list = []
13811400

@@ -1765,7 +1784,7 @@ let runAll (srcs: SourceFile list) (baseCtx: IContext<#TyperOptions>) =
17651784
let inline withSourceFileContext ctx f (src: SourceFile) =
17661785
f (ctx |> TyperContext.ofSourceFileRoot src.fileName) src
17671786

1768-
let result = srcs |> List.map (mapStatements mergeStatements)
1787+
let result = srcs |> List.map (mapStatements (inferEnumCaseValue >> mergeStatements))
17691788

17701789
// build a context
17711790
let ctx = createRootContextForTyper result baseCtx

0 commit comments

Comments
 (0)