Skip to content

Commit fd047ae

Browse files
Fix #2709
1 parent b897166 commit fd047ae

File tree

8 files changed

+511
-42
lines changed

8 files changed

+511
-42
lines changed

src/Fable.Cli/Util.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ module Log =
7878

7979
let inSameLineIfNotCI (msg: string) =
8080
if not isCi then
81+
let msg = if msg.Length > 80 then msg.[..80] + "..." else msg
8182
let curCursorLeft = Console.CursorLeft
8283
Console.SetCursorPosition(0, Console.CursorTop)
8384
Console.Out.Write(msg)

src/Fable.Transforms/FSharp2Fable.Util.fs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ type Witness =
277277
| _ -> []
278278

279279
type Context =
280-
{ Scope: (FSharpMemberOrFunctionOrValue * Fable.Ident * Fable.Expr option) list
280+
{ Scope: (FSharpMemberOrFunctionOrValue option * Fable.Ident * Fable.Expr option) list
281281
ScopeInlineValues: (FSharpMemberOrFunctionOrValue * FSharpExpr) list
282282
ScopeInlineArgs: (Fable.Ident * Fable.Expr) list
283283
UsedNamesInRootScope: Set<string>
@@ -1348,9 +1348,6 @@ module Identifiers =
13481348
open Helpers
13491349
open TypeHelpers
13501350

1351-
let putIdentInScope (ctx: Context) (fsRef: FSharpMemberOrFunctionOrValue) (ident: Fable.Ident) value =
1352-
{ ctx with Scope = (fsRef, ident, value)::ctx.Scope}
1353-
13541351
let makeIdentFrom (_com: IFableCompiler) (ctx: Context) (fsRef: FSharpMemberOrFunctionOrValue): Fable.Ident =
13551352
let sanitizedName = (fsRef.CompiledName, Naming.NoMemberPart)
13561353
||> Naming.sanitizeIdent (isUsedName ctx)
@@ -1363,24 +1360,21 @@ module Identifiers =
13631360
Range = { makeRange fsRef.DeclarationLocation
13641361
with identifierName = Some fsRef.DisplayName } |> Some }
13651362

1366-
let putArgInScope com ctx (fsRef: FSharpMemberOrFunctionOrValue): Context*Fable.Ident =
1363+
let putIdentInScope com ctx (fsRef: FSharpMemberOrFunctionOrValue) value: Context*Fable.Ident =
13671364
let ident = makeIdentFrom com ctx fsRef
1368-
putIdentInScope ctx fsRef ident None, ident
1369-
1370-
let (|PutArgInScope|) com ctx fsRef = putArgInScope com ctx fsRef
1365+
{ ctx with Scope = (Some fsRef, ident, value)::ctx.Scope }, ident
13711366

1372-
let putBindingInScope com ctx (fsRef: FSharpMemberOrFunctionOrValue) value: Context*Fable.Ident =
1373-
let ident = makeIdentFrom com ctx fsRef
1374-
putIdentInScope ctx fsRef ident (Some value), ident
1367+
let (|PutIdentInScope|) com ctx fsRef = putIdentInScope com ctx fsRef None
13751368

13761369
let identWithRange r (ident: Fable.Ident) =
13771370
let originalName = ident.Range |> Option.bind (fun r -> r.identifierName)
13781371
{ ident with Range = r |> Option.map (fun r -> { r with identifierName = originalName }) }
13791372

13801373
let tryGetIdentFromScopeIf (ctx: Context) r predicate =
13811374
ctx.Scope |> List.tryPick (fun (fsRef, ident, _) ->
1382-
if predicate fsRef then identWithRange r ident |> Fable.IdentExpr |> Some
1383-
else None)
1375+
fsRef
1376+
|> Option.filter predicate
1377+
|> Option.map (fun _ -> identWithRange r ident |> Fable.IdentExpr))
13841378

13851379
/// Get corresponding identifier to F# value in current scope
13861380
let tryGetIdentFromScope (ctx: Context) r (fsRef: FSharpMemberOrFunctionOrValue) =
@@ -1396,20 +1390,20 @@ module Util =
13961390
let ctx, args =
13971391
((ctx, []), args)
13981392
||> List.fold (fun (ctx, accArgs) var ->
1399-
let newContext, arg = putArgInScope com ctx var
1393+
let newContext, arg = putIdentInScope com ctx var None
14001394
newContext, arg::accArgs)
14011395
ctx, List.rev args
14021396

14031397
let bindMemberArgs com ctx (args: FSharpMemberOrFunctionOrValue list list) =
14041398
let ctx, transformedArgs, args =
14051399
match args with
14061400
| (firstArg::restArgs1)::restArgs2 when firstArg.IsMemberThisValue ->
1407-
let ctx, thisArg = putArgInScope com ctx firstArg
1401+
let ctx, thisArg = putIdentInScope com ctx firstArg None
14081402
let thisArg = { thisArg with IsThisArgument = true }
14091403
let ctx = { ctx with BoundMemberThis = Some thisArg }
14101404
ctx, [thisArg], restArgs1::restArgs2
14111405
| (firstArg::restArgs1)::restArgs2 when firstArg.IsConstructorThisValue ->
1412-
let ctx, thisArg = putArgInScope com ctx firstArg
1406+
let ctx, thisArg = putIdentInScope com ctx firstArg None
14131407
let thisArg = { thisArg with IsThisArgument = true }
14141408
let ctx = { ctx with BoundConstructorThis = Some thisArg }
14151409
ctx, [thisArg], restArgs1::restArgs2
@@ -1424,7 +1418,7 @@ module Util =
14241418
let makeTryCatch com ctx r (Transform com ctx body) catchClause finalBody =
14251419
let catchClause =
14261420
match catchClause with
1427-
| Some (PutArgInScope com ctx (catchContext, catchVar), catchBody) ->
1421+
| Some (PutIdentInScope com ctx (catchContext, catchVar), catchBody) ->
14281422
// Add caughtException to context so it can be retrieved by `reraise`
14291423
let catchContext = { catchContext with CaughtException = Some catchVar }
14301424
Some (catchVar, com.Transform(catchContext, catchBody))

src/Fable.Transforms/FSharp2Fable.fs

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ let rec private transformDecisionTargets (com: IFableCompiler) (ctx: Context) ac
402402
| (idents, expr)::tail ->
403403
let ctx, idents =
404404
(idents, (ctx, [])) ||> List.foldBack (fun ident (ctx, idents) ->
405-
let ctx, ident = putArgInScope com ctx ident
405+
let ctx, ident = putIdentInScope com ctx ident None
406406
ctx, ident::idents)
407407
let! expr = transformExpr com ctx expr
408408
return! transformDecisionTargets com ctx ((idents, expr)::acc) tail
@@ -534,7 +534,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr =
534534
| FSharpExprPatterns.FastIntegerForLoop(start, limit, body, isUp) ->
535535
let r = makeRangeFrom fsExpr
536536
match body with
537-
| FSharpExprPatterns.Lambda (PutArgInScope com ctx (newContext, ident), body) ->
537+
| FSharpExprPatterns.Lambda (PutIdentInScope com ctx (newContext, ident), body) ->
538538
let! start = transformExpr com ctx start
539539
let! limit = transformExpr com ctx limit
540540
let! body = transformExpr com newContext body
@@ -595,7 +595,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr =
595595
let! value = transformExpr com ctx value
596596
let typ = makeType ctx.GenericArgs createEvent.Type
597597
let value = makeCallFrom com ctx (makeRangeFrom createEvent) typ Seq.empty (Some value) [] event
598-
let ctx, ident = putBindingInScope com ctx var value
598+
let ctx, ident = putIdentInScope com ctx var (Some value)
599599
let! body = transformExpr com ctx body
600600
return Fable.Let(ident, value, body)
601601

@@ -605,7 +605,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr =
605605
return! transformExpr com ctx body
606606
else
607607
let! value = transformExpr com ctx value
608-
let ctx, ident = putBindingInScope com ctx var value
608+
let ctx, ident = putIdentInScope com ctx var (Some value)
609609
let! body = transformExpr com ctx body
610610
match value with
611611
| Fable.Import(info, t, r) when not info.IsCompilerGenerated ->
@@ -621,7 +621,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr =
621621
// First get a context containing all idents and use it compile the values
622622
let ctx, idents =
623623
(recBindings, (ctx, []))
624-
||> List.foldBack (fun (PutArgInScope com ctx (newContext, ident), _) (ctx, idents) ->
624+
||> List.foldBack (fun (PutIdentInScope com ctx (newContext, ident), _) (ctx, idents) ->
625625
(newContext, ident::idents))
626626
let _, bindingExprs = List.unzip recBindings
627627
let! exprs = transformExprList com ctx bindingExprs
@@ -1508,6 +1508,22 @@ type FableCompiler(com: Compiler) =
15081508
{ ident with Name = sanitizedName }
15091509
else ident
15101510

1511+
let rec foldArgs acc = function
1512+
| argIdent::restArgIdents, argExpr::restArgExprs ->
1513+
foldArgs ((argIdent, argExpr)::acc) (restArgIdents, restArgExprs)
1514+
| (argIdent: Fable.Ident)::restArgIdents, [] ->
1515+
foldArgs ((argIdent, Fable.Value(Fable.NewOption(None, argIdent.Type), None))::acc) (restArgIdents, [])
1516+
| [], _ -> List.rev acc
1517+
1518+
let ctx, bindings =
1519+
((ctx, []), foldArgs [] (inExpr.Args, args)) ||> List.fold (fun (ctx, bindings) (argId, arg) ->
1520+
let argId = resolveIdent ctx argId
1521+
// Change type and mark argId as compiler-generated so Fable also
1522+
// tries to inline it in DEBUG mode (some patterns depend on this)
1523+
let argId = { argId with Type = arg.Type; IsCompilerGenerated = true }
1524+
let ctx = { ctx with Scope = (None, argId, Some arg)::ctx.Scope }
1525+
ctx, (argId, arg)::bindings)
1526+
15111527
let rec resolveGenArg (ctx: Context) = function
15121528
| Fable.GenericParam name as v ->
15131529
match Map.tryFind name ctx.GenericArgs with
@@ -1517,19 +1533,32 @@ type FableCompiler(com: Compiler) =
15171533

15181534
let rec resolveExpr ctx expr =
15191535
expr |> visitFromOutsideIn (function
1520-
// Resolve idents
1536+
// Resolve bindings
1537+
| Fable.Let(i, v, b) ->
1538+
let i = resolveIdent ctx i
1539+
let v = resolveExpr ctx v
1540+
let ctx = { ctx with Scope = (None, i, Some v)::ctx.Scope }
1541+
Fable.Let(i, v, resolveExpr ctx b) |> Some
1542+
1543+
| Fable.LetRec(bindings, b) ->
1544+
let ctx, bindings =
1545+
((ctx, bindings), bindings) ||> List.fold(fun (ctx, bindings) (i, e) ->
1546+
let i = resolveIdent ctx i
1547+
let e = resolveExpr ctx e
1548+
{ ctx with Scope = (None, i, Some e)::ctx.Scope }, (i, e)::bindings)
1549+
Fable.LetRec(List.rev bindings, resolveExpr ctx b) |> Some
1550+
1551+
// Resolve idents in other expressions
15211552
| Fable.IdentExpr i -> Fable.IdentExpr(resolveIdent ctx i) |> Some
15221553
| Fable.Lambda(arg, b, n) -> Fable.Lambda(resolveIdent ctx arg, resolveExpr ctx b, n) |> Some
15231554
| Fable.Delegate(args, b, n) -> Fable.Delegate(List.map (resolveIdent ctx) args, resolveExpr ctx b, n) |> Some
15241555
| Fable.DecisionTree(e, targets) -> Fable.DecisionTree(resolveExpr ctx e, targets |> List.map(fun (idents, e) -> List.map (resolveIdent ctx) idents, resolveExpr ctx e)) |> Some
1525-
| Fable.Let(i, v, b) -> Fable.Let(resolveIdent ctx i, resolveExpr ctx v, resolveExpr ctx b) |> Some
1526-
| Fable.LetRec(bindings, b) -> Fable.LetRec(bindings |> List.map(fun (i, e) -> resolveIdent ctx i, resolveExpr ctx e), resolveExpr ctx b) |> Some
15271556
| Fable.ForLoop(i, s, l, b, u, r) -> Fable.ForLoop(resolveIdent ctx i, resolveExpr ctx s, resolveExpr ctx l, resolveExpr ctx b, u, r) |> Some
15281557
| Fable.TryCatch(b, c, d, r) -> Fable.TryCatch(resolveExpr ctx b, (c |> Option.map (fun (i, e) -> resolveIdent ctx i, resolveExpr ctx e)), (d |> Option.map (resolveExpr ctx)), r) |> Some
15291558
| Fable.ObjectExpr(members, t, baseCall) ->
15301559
let members = members |> List.map (fun m ->
15311560
{ m with Args = List.map (resolveIdent ctx) m.Args
1532-
Body = resolveExpr ctx m.Body })
1561+
Body = resolveExpr ctx m.Body })
15331562
Fable.ObjectExpr(members, resolveGenArg ctx t, baseCall |> Option.map (resolveExpr ctx)) |> Some
15341563

15351564
// Resolve imports. TODO: add test
@@ -1595,21 +1624,6 @@ type FableCompiler(com: Compiler) =
15951624

15961625
| _ -> None)
15971626

1598-
let rec foldArgs acc = function
1599-
| argIdent::restArgIdents, argExpr::restArgExprs ->
1600-
foldArgs ((argIdent, argExpr)::acc) (restArgIdents, restArgExprs)
1601-
| (argIdent: Fable.Ident)::restArgIdents, [] ->
1602-
foldArgs ((argIdent, Fable.Value(Fable.NewOption(None, argIdent.Type), None))::acc) (restArgIdents, [])
1603-
| [], _ -> List.rev acc
1604-
1605-
let bindings =
1606-
([], foldArgs [] (inExpr.Args, args)) ||> List.fold (fun bindings (argId, arg) ->
1607-
let argId = resolveIdent ctx argId
1608-
// Change type and mark argId as compiler-generated so Fable also
1609-
// tries to inline it in DEBUG mode (some patterns depend on this)
1610-
let argId = { argId with Type = arg.Type; IsCompilerGenerated = true }
1611-
(argId, arg)::bindings)
1612-
16131627
let ctx = { ctx with ScopeInlineArgs = ctx.ScopeInlineArgs @ bindings }
16141628
bindings, resolveExpr ctx inExpr.Body
16151629

@@ -1661,7 +1675,7 @@ let getInlineExprs fileName (declarations: FSharpImplementationFileDeclaration l
16611675

16621676
let ctx, idents =
16631677
((ctx, []), List.concat argIds) ||> List.fold (fun (ctx, idents) argId ->
1664-
let ctx, ident = putArgInScope com ctx argId
1678+
let ctx, ident = putIdentInScope com ctx argId None
16651679
ctx, ident::idents)
16661680

16671681
{ Args = List.rev idents

tests/React/Counter.fs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module Counter
22

3+
open Fable.React
34
open Feliz
45

56
[<ReactComponent>]
@@ -17,5 +18,8 @@ let Counter() =
1718
prop.text "Increment"
1819
prop.onClick (fun _ -> setCount(count + 1))
1920
]
21+
22+
// Check that fluent-ui bindings work, see #2709
23+
Fable.FluentUI.Button.defaultButton [] [ str "A fluent button" ]
2024
]
2125
]

tests/React/Fable.Tests.React.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<Compile Include="__tests__/Tests.fs" />
99
</ItemGroup>
1010
<ItemGroup>
11+
<PackageReference Include="Fable.FluentUI" Version="0.6.0" />
1112
<PackageReference Include="Fable.Jester" Version="0.29.1" />
1213
<PackageReference Include="Fable.ReactTestingLibrary" Version="0.29.1" />
1314
<PackageReference Include="Feliz" Version="1.22.0" />

tests/React/__tests__/__snapshots__/Tests.fs.js.snap

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,27 @@ exports[`React tests Counter renders correctly 1`] = `
1515
>
1616
Increment
1717
</button>
18+
<button
19+
class="ms-Button ms-Button--default root-109"
20+
data-is-focusable="true"
21+
type="button"
22+
>
23+
<span
24+
class="ms-Button-flexContainer flexContainer-110"
25+
data-automationid="splitbuttonprimary"
26+
>
27+
<span
28+
class="ms-Button-textContainer textContainer-111"
29+
>
30+
<span
31+
class="ms-Button-label label-113"
32+
id="id__0"
33+
>
34+
A fluent button
35+
</span>
36+
</span>
37+
</span>
38+
</button>
1839
</div>
1940
</div>
2041
`;

0 commit comments

Comments
 (0)