Skip to content

Commit

Permalink
Solid: match and If statements support
Browse files Browse the repository at this point in the history
  • Loading branch information
Lanayx committed Nov 13, 2024
1 parent 18669b6 commit 159e198
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 20 deletions.
26 changes: 20 additions & 6 deletions src/Oxpecker.Solid.FablePlugin/Library.fs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@ module internal rec AST =
let next2Children = getChildren [] next2
let next1Children = getChildren [] next1
next2Children @ next1Children @ currentList
| Let({ Name = first }, Let(_, expr, _), Let({ Name = second }, next, _)) when
| Let({ Name = first }, Let(_, expr, _), Let({ Name = second }, next, _))
| Let({ Name = first }, expr, Let({ Name = second }, next, _)) when
first.StartsWith("first") && second.StartsWith("second")
->
match expr with
Expand All @@ -259,6 +260,12 @@ module internal rec AST =
| expr ->
let newExpr = transform expr
getChildren (newExpr :: currentList) next
| IfThenElse(guardExpr, thenExpr, elseExpr, range) ->
IfThenElse(guardExpr, transform thenExpr, transform elseExpr, range)
:: currentList
| DecisionTree(decisionTree, targets) ->
DecisionTree(decisionTree, targets |> List.map(fun (target, expr) -> target, transform expr))
:: currentList
// router cases
| Call(Get(IdentExpr _, FieldGet _, Any, _), { Args = args }, _, _) ->
match args with
Expand All @@ -280,21 +287,20 @@ module internal rec AST =
next2Children @ next1Children @ currentList
| [ expr ] -> expr :: currentList
| _ -> currentList

| Let({
Name = name
Range = range
Type = DeclaredType({ FullName = fullName }, [])
},
_,
_) when
((not <| name.StartsWith("returnVal")) && (not <| name.StartsWith("element")))
&& fullName.StartsWith("Oxpecker.Solid")
((name.StartsWith("returnVal") && fullName.StartsWith("Oxpecker.Solid"))
|| (name.StartsWith("element") && fullName.StartsWith("Oxpecker.Solid")))
|> not
->
match range with
| Some range -> failwith $"`let` binding inside HTML CE can't be converted to JSX:line {range.start.line}"
| None -> failwith $"`let` binding inside HTML CE can't be converted to JSX"

| _ -> currentList

let listItemType =
Expand Down Expand Up @@ -377,10 +383,13 @@ module internal rec AST =

let transform (expr: Expr) =
match expr with
| LetTagNoChildrenWithProps tagCall -> transformTagInfo tagCall
| LetTagNoChildrenWithProps tagCall
| LetElement & Let(_, LetTagNoChildrenWithProps tagCall, _) -> transformTagInfo tagCall
| TagNoChildren(tagName, range) -> transformTagInfo(TagInfo.NoChildren(tagName, [], range))
| CallTagNoChildrenWithHandler tagCall -> transformTagInfo tagCall
| LetTagNoChildrenNoProps tagCall -> transformTagInfo tagCall
| TagWithChildren callInfo -> transformTagInfo(TagInfo.WithChildren callInfo)
| LetTagWithChildren tagCall -> transformTagInfo tagCall
| LibraryTagImport(imp, range) -> transformTagInfo(TagInfo.NoChildren(LibraryImport imp, [], range))
| Let(_, LibraryTagImport(imp, range), TagWithChildren(_, callInfo, _)) ->
transformTagInfo(TagInfo.WithChildren(LibraryImport imp, callInfo, range))
Expand All @@ -402,6 +411,11 @@ module internal rec AST =
Args = callInfo.Args |> List.map transform
}
Call(callee, newCallInfo, typ, range)
| TextNoSiblings body -> body
| IfThenElse(guardExpr, thenExpr, elseExpr, range) ->
IfThenElse(guardExpr, transform thenExpr, transform elseExpr, range)
| DecisionTree(decisionTree, targets) ->
DecisionTree(decisionTree, targets |> List.map(fun (target, expr) -> target, transform expr))
| TypeCast(expr, DeclaredType _) -> transform expr
| _ -> expr

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
<PackageTags>Oxpecker;F#;FSharp;Plugin;fable-javascript;Compiler;Fable;Solid;Solidjs</PackageTags>
<Authors>Vladimir Shchur</Authors>
<PackageReadmeFile>README.md</PackageReadmeFile>
<Version>0.2.3</Version>
<PackageVersion>0.2.3</PackageVersion>
<PackageReleaseNotes>Explicit error on let bindings</PackageReleaseNotes>
<Version>0.3.0</Version>
<PackageVersion>0.3.0</PackageVersion>
<PackageReleaseNotes>Support for match and if expressions</PackageReleaseNotes>
</PropertyGroup>

<ItemGroup>
Expand Down
6 changes: 3 additions & 3 deletions src/Oxpecker.Solid/Oxpecker.Solid.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
<PackageTags>Oxpecker;F#;FSharp;Fable;fable-javascript;Web;Framework;Solid;Solidjs</PackageTags>
<Authors>Vladimir Shchur</Authors>
<PackageReadmeFile>README.md</PackageReadmeFile>
<Version>0.2.2</Version>
<PackageVersion>0.2.2</PackageVersion>
<PackageReleaseNotes>Fixed jsx for Solid A element</PackageReleaseNotes>
<Version>0.3.0</Version>
<PackageVersion>0.3.0</PackageVersion>
<PackageReleaseNotes>Support for match and if expressions</PackageReleaseNotes>
</PropertyGroup>

<ItemGroup>
Expand Down
14 changes: 9 additions & 5 deletions tests/Oxpecker.Solid.Tests/Cases/Parameters/Parameters.expected
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { int32ToString } from "./fable_modules/fable-library-js.4.23.0/Util.js";

export function Test(id) {
export function Test(id, hello) {
const helloWorld = hello + " world";
return <div id={int32ToString(id)}
class="testclass"
aria-labelledby="testlabel">
<>
Hello
</>
world!
{(id > 0) ? <h3></h3> : <h2 class={int32ToString(id)}>
{id}
</h2>}
{(id > 5) ? <h4 class={helloWorld}></h4> : helloWorld}
{(id === 2) ? <h1 id="two">
{helloWorld}
</h1> : ((id > 2) ? <h1 id={int32ToString(id)}></h1> : <h1></h1>)}
</div>;
}

11 changes: 8 additions & 3 deletions tests/Oxpecker.Solid.Tests/Cases/Parameters/Parameters.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ open Oxpecker.Solid
open Oxpecker.Solid.Aria

[<SolidComponent>]
let Test (id: int) =
let hello = "Hello "
let Test (id: int) (hello: string) =
let helloWorld = hello + " world"
div(id=string id, class'="testclass", ariaLabelledBy="testlabel") {
Fragment() { hello }; "world!"
if id > 0 then h3() else h2(class'=string id) { id }
if id > 5 then h4(class'=helloWorld) else helloWorld
match id with
| 2 -> h1(id="two") { helloWorld }
| x when x > 2 -> h1(id=string x)
| _ -> h1()
}

0 comments on commit 159e198

Please sign in to comment.