Skip to content

Commit

Permalink
Merge pull request #42 from edgarfgp/rework-class-widget
Browse files Browse the repository at this point in the history
Rework Class Widget
  • Loading branch information
edgarfgp committed Jun 13, 2023
2 parents ecd292a + 235aacc commit fd8834d
Show file tree
Hide file tree
Showing 8 changed files with 645 additions and 58 deletions.
217 changes: 207 additions & 10 deletions src/Fabulous.AST.Tests/TypeDefinitions/Class.fs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ type Person =
)
)

AnonymousModule() { Class("Person", []) { EscapeHatch(memberNode) } }
AnonymousModule() { (Class("Person") { EscapeHatch(memberNode) }).implicitConstructorParameters([]) }
|> produces
"""
type Person () =
Expand Down Expand Up @@ -110,12 +110,16 @@ type Person () =
)

let param =
SimplePatNode(None, false, SingleTextNode("name", Range.Zero), None, Range.Zero)
[ "name"; "lastName"; "age" ]
|> List.map(fun n -> SimplePatNode(None, false, SingleTextNode(n, Range.Zero), None, Range.Zero))

AnonymousModule() { Class("Person", [ param ]) { EscapeHatch(memberNode) } }
AnonymousModule() {
(Class("Person") { EscapeHatch(memberNode) })
.implicitConstructorParameters(param)
}
|> produces
"""
type Person (name) =
type Person (name, lastName, age) =
member this.Name = name
"""
Expand Down Expand Up @@ -149,14 +153,26 @@ type Person (name) =
)

let param =
SimplePatNode(None, false, SingleTextNode("name", Range.Zero), Some(Type.FromString("string")), Range.Zero)
[ ("name", "string"); ("lastName", "string"); ("age", "int") ]
|> List.map(fun n ->
let isOpt = fst n = "age"

SimplePatNode(
None,
isOpt,
SingleTextNode(fst n, Range.Zero),
Some(Type.FromString($"{snd n}")),
Range.Zero
))

AnonymousModule() { Class("Person", [ param ]) { EscapeHatch(memberNode) } }
AnonymousModule() {
(Class("Person") { EscapeHatch(memberNode) })
.implicitConstructorParameters(param)
}
|> produces
"""
type Person (name: string) =
type Person (name: string, lastName: string, ?age: int) =
member this.Name = name
"""

[<Test>]
Expand Down Expand Up @@ -190,7 +206,11 @@ type Person (name: string) =
let param =
SimplePatNode(None, false, SingleTextNode("name", Range.Zero), Some(Type.FromString("string")), Range.Zero)

AnonymousModule() { (Class("Person", [ param ]) { EscapeHatch(memberNode) }).isStruct() }
AnonymousModule() {
(Class("Person") { EscapeHatch(memberNode) })
.isStruct()
.implicitConstructorParameters([ param ])
}
|> produces
"""
[<Struct>]
Expand Down Expand Up @@ -228,8 +248,9 @@ type Person (name: string) =
)

AnonymousModule() {
(Class("Person", []) { EscapeHatch(memberNode) })
(Class("Person") { EscapeHatch(memberNode) })
.attributes([ "Sealed"; "AbstractClass" ])
.implicitConstructorParameters([])
}
|> produces
"""
Expand All @@ -238,3 +259,179 @@ type Person () =
member this.Name = ""
"""

[<Test>]
let ``Produces a generic class`` () =
let memberNode =
MemberDefn.Member(
BindingNode(
None,
None,
MultipleTextsNode([ SingleTextNode("member", Range.Zero) ], Range.Zero),
false,
None,
None,
Choice1Of2(
IdentListNode(
[ IdentifierOrDot.Ident(SingleTextNode("this", Range.Zero))
IdentifierOrDot.Ident(SingleTextNode(".", Range.Zero))
IdentifierOrDot.Ident(SingleTextNode("Name", Range.Zero)) ],
Range.Zero
)
),
None,
List.Empty,
None,
SingleTextNode("=", Range.Zero),
Expr.Constant(Constant.FromText(SingleTextNode("\"\"", Range.Zero))),
Range.Zero
)
)

AnonymousModule() {
GenericClass("Person", [ "'a"; "'b" ]) { EscapeHatch(memberNode) }

}
|> produces
"""
type Person <'a, 'b> =
member this.Name = ""
"""

[<Test>]
let ``Produces a generic class with a constructor`` () =
let memberNode =
MemberDefn.Member(
BindingNode(
None,
None,
MultipleTextsNode([ SingleTextNode("member", Range.Zero) ], Range.Zero),
false,
None,
None,
Choice1Of2(
IdentListNode(
[ IdentifierOrDot.Ident(SingleTextNode("this", Range.Zero))
IdentifierOrDot.Ident(SingleTextNode(".", Range.Zero))
IdentifierOrDot.Ident(SingleTextNode("Name", Range.Zero)) ],
Range.Zero
)
),
None,
List.Empty,
None,
SingleTextNode("=", Range.Zero),
Expr.Constant(Constant.FromText(SingleTextNode("\"\"", Range.Zero))),
Range.Zero
)
)

AnonymousModule() {
(GenericClass("Person", [ "'a"; "'b" ]) { EscapeHatch(memberNode) })
.implicitConstructorParameters([])

}
|> produces
"""
type Person <'a, 'b>() =
member this.Name = ""
"""

[<Test>]
let ``Produces a struct generic class with a constructor`` () =
let memberNode =
MemberDefn.Member(
BindingNode(
None,
None,
MultipleTextsNode([ SingleTextNode("member", Range.Zero) ], Range.Zero),
false,
None,
None,
Choice1Of2(
IdentListNode(
[ IdentifierOrDot.Ident(SingleTextNode("this", Range.Zero))
IdentifierOrDot.Ident(SingleTextNode(".", Range.Zero))
IdentifierOrDot.Ident(SingleTextNode("Name", Range.Zero)) ],
Range.Zero
)
),
None,
List.Empty,
None,
SingleTextNode("=", Range.Zero),
Expr.Constant(Constant.FromText(SingleTextNode("\"\"", Range.Zero))),
Range.Zero
)
)

AnonymousModule() {
(GenericClass("Person", [ "'a"; "'b" ]) { EscapeHatch(memberNode) })
.isStruct()
.implicitConstructorParameters([])

}
|> produces
"""
[<Struct>]
type Person <'a, 'b>() =
member this.Name = ""
"""

[<Test>]
let ``Produces a class end`` () =
AnonymousModule() { ClassEnd("MyClass") }
|> produces
"""
type MyClass =
class
end
"""

[<Test>]
let ``Produces a class end with constructor`` () =
AnonymousModule() { ClassEnd("MyClass").implicitConstructorParameters([]) }
|> produces
"""
type MyClass () =
class
end
"""

[<Test>]
let ``Produces a class end with constructor and attributes`` () =
AnonymousModule() {
ClassEnd("MyClass")
.attributes([ "Sealed"; "AbstractClass" ])
.implicitConstructorParameters([])
}
|> produces
"""
[<Sealed; AbstractClass>]
type MyClass () =
class
end
"""

[<Test>]
let ``Produces a class end with type params`` () =
AnonymousModule() { ClassEnd("MyClass", [ "'a"; "'b" ]) }
|> produces
"""
type MyClass <'a, 'b> =
class
end
"""

[<Test>]
let ``Produces a class end with constructor and type params`` () =
AnonymousModule() { ClassEnd("MyClass", [ "'a"; "'b" ]).implicitConstructorParameters([]) }
|> produces
"""
type MyClass <'a, 'b>() =
class
end
"""
4 changes: 3 additions & 1 deletion src/Fabulous.AST/Fabulous.AST.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@
<Compile Include="Widgets\TypeDefinitions\Abbrev.fs" />
<Compile Include="Widgets\TypeDefinitions\Union.fs" />
<Compile Include="Widgets\TypeDefinitions\Record.fs" />
<Compile Include="Widgets\TypeDefinitions\Class.fs" />
<Compile Include="Widgets\TypeDefinitions\Interface.fs" />
<Compile Include="Widgets\TypeDefinitions\Class.fs" />
<Compile Include="Widgets\TypeDefinitions\GenericClass.fs" />
<Compile Include="Widgets\TypeDefinitions\ClassEnd.fs" />
<Compile Include="Widgets\TypeDefinitions\GenericInterface.fs" />
<Compile Include="Widgets\ControlFlow\IfThen.fs" />
<Compile Include="Widgets\ControlFlow\IfThenElif.fs" />
Expand Down
7 changes: 7 additions & 0 deletions src/Fabulous.AST/Widgets/Common.fs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,19 @@ module Auxiliary =
let lessThan = SingleTextNode.Create "<"
let greaterThan = SingleTextNode.Create ">"
let equals = SingleTextNode.Create "="
let comma = SingleTextNode.Create ","
let ``type`` = SingleTextNode.Create "type"
let leftAttribute = SingleTextNode.Create "[<"
let rightAttribute = SingleTextNode.Create ">]"
let leftCurlyBrace = SingleTextNode.Create "{"
let rightCurlyBrace = SingleTextNode.Create "}"
let leftParenthesis = SingleTextNode.Create "("
let rightParenthesis = SingleTextNode.Create ")"
let ``abstract`` = SingleTextNode.Create "abstract"
let ``interface`` = SingleTextNode.Create "interface"
let ``class`` = SingleTextNode.Create "class"
let ``end`` = SingleTextNode.Create "end"
let ``with`` = SingleTextNode.Create "with"
let ``member`` = SingleTextNode.Create "member"
let rightArrow = SingleTextNode.Create "->"
let lefArrow = SingleTextNode.Create "<-"
Expand Down

0 comments on commit fd8834d

Please sign in to comment.