Skip to content

Commit fa6128f

Browse files
committed
feat: add supports for split get/set declaration field
[converter] Fix #82 Fix #106
1 parent 70c6e11 commit fa6128f

File tree

10 files changed

+296
-1
lines changed

10 files changed

+296
-1
lines changed

src/Glutinum.Converter/GlueAST.fs

+20
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,24 @@ type GlueProperty =
7979
IsPrivate: bool
8080
}
8181

82+
type GlueSetAccessor =
83+
{
84+
Name: string
85+
Documentation: GlueComment list
86+
ArgumentType: GlueType
87+
IsStatic: bool
88+
IsPrivate: bool
89+
}
90+
91+
type GlueGetAccessor =
92+
{
93+
Name: string
94+
Documentation: GlueComment list
95+
Type: GlueType
96+
IsStatic: bool
97+
IsPrivate: bool
98+
}
99+
82100
type GlueIndexSignature =
83101
{
84102
Parameters: GlueParameter list
@@ -103,6 +121,8 @@ type GlueConstructSignature =
103121
type GlueMember =
104122
| Method of GlueMethod
105123
| Property of GlueProperty
124+
| GetAccessor of GlueGetAccessor
125+
| SetAccessor of GlueSetAccessor
106126
| CallSignature of GlueCallSignature
107127
| IndexSignature of GlueIndexSignature
108128
| MethodSignature of GlueMethodSignature

src/Glutinum.Converter/Reader/Declaration.fs

+54
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,60 @@ let readDeclaration
122122
: GlueProperty)
123123
|> GlueMember.Property
124124

125+
| Ts.SyntaxKind.GetAccessor ->
126+
let getAccessorDeclaration = declaration :?> Ts.GetAccessorDeclaration
127+
let name = unbox<Ts.Identifier> getAccessorDeclaration.name
128+
129+
let hasPrivateModifier =
130+
ModifierUtil.HasModifier(
131+
getAccessorDeclaration.modifiers,
132+
Ts.SyntaxKind.PrivateKeyword
133+
)
134+
135+
let isPrivateIdentifier = name.kind = Ts.SyntaxKind.PrivateIdentifier
136+
137+
({
138+
Name = name.getText ()
139+
Documentation = reader.ReadDocumentationFromNode name
140+
Type = reader.ReadTypeNode getAccessorDeclaration.``type``
141+
IsStatic =
142+
ModifierUtil.HasModifier(
143+
getAccessorDeclaration.modifiers,
144+
Ts.SyntaxKind.StaticKeyword
145+
)
146+
IsPrivate = hasPrivateModifier || isPrivateIdentifier
147+
}
148+
: GlueGetAccessor)
149+
|> GlueMember.GetAccessor
150+
151+
| Ts.SyntaxKind.SetAccessor ->
152+
let setAccessorDeclaration = declaration :?> Ts.SetAccessorDeclaration
153+
let name = unbox<Ts.Identifier> setAccessorDeclaration.name
154+
155+
let hasPrivateModifier =
156+
ModifierUtil.HasModifier(
157+
setAccessorDeclaration.modifiers,
158+
Ts.SyntaxKind.PrivateKeyword
159+
)
160+
161+
let isPrivateIdentifier = name.kind = Ts.SyntaxKind.PrivateIdentifier
162+
163+
({
164+
Name = name.getText ()
165+
Documentation = reader.ReadDocumentationFromNode name
166+
ArgumentType =
167+
reader.ReadTypeNode
168+
setAccessorDeclaration.parameters.[0].``type``
169+
IsStatic =
170+
ModifierUtil.HasModifier(
171+
setAccessorDeclaration.modifiers,
172+
Ts.SyntaxKind.StaticKeyword
173+
)
174+
IsPrivate = hasPrivateModifier || isPrivateIdentifier
175+
}
176+
: GlueSetAccessor)
177+
|> GlueMember.SetAccessor
178+
125179
| _ ->
126180
generateReaderError
127181
"declaration"

src/Glutinum.Converter/Transform.fs

+132-1
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,8 @@ let rec private transformType
382382
| GlueMember.IndexSignature _ -> false
383383
| GlueMember.MethodSignature _
384384
| GlueMember.Property _
385+
| GlueMember.GetAccessor _
386+
| GlueMember.SetAccessor _
385387
| GlueMember.CallSignature _
386388
| GlueMember.Method _
387389
| GlueMember.ConstructSignature _ -> true
@@ -827,6 +829,61 @@ module private TransformMembers =
827829
: FSharpMember list
828830
=
829831
members
832+
// We want to transform GetAccessor / SetAccessor
833+
// into a single Property if they are related to the same property
834+
|> List.choose (
835+
function
836+
| GlueMember.GetAccessor getAccessorInfo as self ->
837+
let associatedSetAccessor =
838+
members
839+
|> List.tryFind (
840+
function
841+
| GlueMember.SetAccessor setPropertyInfo ->
842+
getAccessorInfo.Name = setPropertyInfo.Name
843+
| _ -> false
844+
)
845+
846+
match associatedSetAccessor with
847+
// If we found an associated SetAccessor, we want to transform into a Property
848+
// and it is now a read-write property
849+
| Some _ ->
850+
{
851+
Name = getAccessorInfo.Name
852+
Documentation = getAccessorInfo.Documentation
853+
Type = getAccessorInfo.Type
854+
IsOptional = false
855+
IsStatic = getAccessorInfo.IsStatic
856+
Accessor = GlueAccessor.ReadWrite
857+
IsPrivate = getAccessorInfo.IsPrivate
858+
}
859+
|> GlueMember.Property
860+
|> Some
861+
// Otherwise, we keep the GetAccessor as is
862+
| None -> Some self
863+
864+
| GlueMember.SetAccessor setAccessorInfo as self ->
865+
let associatedGetAccessor =
866+
members
867+
|> List.tryFind (
868+
function
869+
| GlueMember.GetAccessor getPropertyInfo ->
870+
setAccessorInfo.Name = getPropertyInfo.Name
871+
| _ -> false
872+
)
873+
874+
// If we found an associated GetAccessor, we want to remove the SetAccessor
875+
// the property has been transformed into a Property during the GetAccessor check
876+
match associatedGetAccessor with
877+
| Some _ -> None
878+
// Otherwise, we keep the SetAccessor as is
879+
| None -> Some self
880+
| GlueMember.CallSignature _ as self -> Some self
881+
| GlueMember.Method _ as self -> Some self
882+
| GlueMember.Property _ as self -> Some self
883+
| GlueMember.IndexSignature _ as self -> Some self
884+
| GlueMember.MethodSignature _ as self -> Some self
885+
| GlueMember.ConstructSignature _ as self -> Some self
886+
)
830887
|> List.choose (
831888
function
832889
| GlueMember.Method methodInfo ->
@@ -934,6 +991,52 @@ module private TransformMembers =
934991
|> FSharpMember.Property
935992
|> Some
936993

994+
| GlueMember.GetAccessor getAccessorInfo ->
995+
let name, context =
996+
sanitizeNameAndPushScope getAccessorInfo.Name context
997+
998+
let xmlDocInfo = transformComment getAccessorInfo.Documentation
999+
1000+
{
1001+
Attributes = [ yield! xmlDocInfo.ObsoleteAttributes ]
1002+
Name = name
1003+
OriginalName = getAccessorInfo.Name
1004+
Parameters = []
1005+
Type = transformType context getAccessorInfo.Type
1006+
TypeParameters = []
1007+
IsOptional = false
1008+
IsStatic = getAccessorInfo.IsStatic
1009+
Accessor = Some FSharpAccessor.ReadOnly
1010+
Accessibility = FSharpAccessibility.Public
1011+
XmlDoc = xmlDocInfo.XmlDoc
1012+
Body = FSharpMemberInfoBody.NativeOnly
1013+
}
1014+
|> FSharpMember.Property
1015+
|> Some
1016+
1017+
| GlueMember.SetAccessor setAccessorInfo ->
1018+
let name, context =
1019+
sanitizeNameAndPushScope setAccessorInfo.Name context
1020+
1021+
let xmlDocInfo = transformComment setAccessorInfo.Documentation
1022+
1023+
{
1024+
Attributes = [ yield! xmlDocInfo.ObsoleteAttributes ]
1025+
Name = name
1026+
OriginalName = setAccessorInfo.Name
1027+
Parameters = []
1028+
Type = transformType context setAccessorInfo.ArgumentType
1029+
TypeParameters = []
1030+
IsOptional = false
1031+
IsStatic = setAccessorInfo.IsStatic
1032+
Accessor = Some FSharpAccessor.WriteOnly
1033+
Accessibility = FSharpAccessibility.Public
1034+
XmlDoc = xmlDocInfo.XmlDoc
1035+
Body = FSharpMemberInfoBody.NativeOnly
1036+
}
1037+
|> FSharpMember.Property
1038+
|> Some
1039+
9371040
| GlueMember.IndexSignature indexSignature ->
9381041
let name, context = sanitizeNameAndPushScope "Item" context
9391042

@@ -1036,6 +1139,30 @@ module private TransformMembers =
10361139
}
10371140
: FSharpParameter
10381141

1142+
| GlueMember.GetAccessor getAccessorInfo ->
1143+
let name, context =
1144+
sanitizeNameAndPushScope getAccessorInfo.Name context
1145+
1146+
{
1147+
Attributes = []
1148+
Name = name
1149+
IsOptional = false
1150+
Type = transformType context getAccessorInfo.Type
1151+
}
1152+
: FSharpParameter
1153+
1154+
| GlueMember.SetAccessor setAccessorInfo ->
1155+
let name, context =
1156+
sanitizeNameAndPushScope setAccessorInfo.Name context
1157+
1158+
{
1159+
Attributes = []
1160+
Name = name
1161+
IsOptional = false
1162+
Type = transformType context setAccessorInfo.ArgumentType
1163+
}
1164+
: FSharpParameter
1165+
10391166
| GlueMember.IndexSignature indexSignature ->
10401167
let name, context = sanitizeNameAndPushScope "Item" context
10411168

@@ -1206,7 +1333,9 @@ module TypeAliasDeclaration =
12061333
match m with
12071334
| GlueMember.Method { Name = caseName }
12081335
| GlueMember.MethodSignature { Name = caseName }
1209-
| GlueMember.Property { Name = caseName } ->
1336+
| GlueMember.Property { Name = caseName }
1337+
| GlueMember.GetAccessor { Name = caseName }
1338+
| GlueMember.SetAccessor { Name = caseName } ->
12101339

12111340
let sanitizeResult =
12121341
Naming.sanitizeNameWithResult caseName
@@ -1524,6 +1653,8 @@ let private transformTypeAliasDeclaration
15241653
match m with
15251654
| GlueMember.Method { Type = typ }
15261655
| GlueMember.Property { Type = typ }
1656+
| GlueMember.GetAccessor { Type = typ }
1657+
| GlueMember.SetAccessor { ArgumentType = typ }
15271658
| GlueMember.CallSignature { Type = typ }
15281659
| GlueMember.ConstructSignature { Type = typ }
15291660
| GlueMember.MethodSignature { Type = typ }

src/Glutinum.Web/Pages/Editors.GlueAST.GlueASTViewer.fs

+20
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,26 @@ type GlueASTViewer =
186186
GlueASTViewer.Type constructSignature.Type
187187
]
188188

189+
| GlueMember.GetAccessor getAccessorInfo ->
190+
ASTViewer.renderNode "GetAccessor" [
191+
GlueASTViewer.Name getAccessorInfo.Name
192+
GlueASTViewer.Documentation getAccessorInfo.Documentation
193+
GlueASTViewer.IsStatic getAccessorInfo.IsStatic
194+
GlueASTViewer.IsPrivate getAccessorInfo.IsPrivate
195+
GlueASTViewer.Type getAccessorInfo.Type
196+
]
197+
198+
| GlueMember.SetAccessor setAccessorInfo ->
199+
ASTViewer.renderNode "SetAccessor" [
200+
GlueASTViewer.Name setAccessorInfo.Name
201+
GlueASTViewer.Documentation setAccessorInfo.Documentation
202+
GlueASTViewer.IsStatic setAccessorInfo.IsStatic
203+
GlueASTViewer.IsPrivate setAccessorInfo.IsPrivate
204+
ASTViewer.renderNode "ArgumentType" [
205+
GlueASTViewer.GlueType setAccessorInfo.ArgumentType
206+
]
207+
]
208+
189209
static member private Members(members: GlueMember list) =
190210
members
191211
|> List.map GlueASTViewer.GlueMember
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export class Foo {
2+
get id(): string;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module rec Glutinum
2+
3+
open Fable.Core
4+
open Fable.Core.JsInterop
5+
open System
6+
7+
[<AbstractClass>]
8+
[<Erase>]
9+
type Exports =
10+
[<Import("Foo", "REPLACE_ME_WITH_MODULE_NAME"); EmitConstructor>]
11+
static member Foo () : Foo = nativeOnly
12+
13+
[<AllowNullLiteral>]
14+
[<Interface>]
15+
type Foo =
16+
abstract member id: string with get
17+
18+
(***)
19+
#r "nuget: Fable.Core"
20+
(***)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export class Foo {
2+
get id(): string;
3+
set id(value: string);
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module rec Glutinum
2+
3+
open Fable.Core
4+
open Fable.Core.JsInterop
5+
open System
6+
7+
[<AbstractClass>]
8+
[<Erase>]
9+
type Exports =
10+
[<Import("Foo", "REPLACE_ME_WITH_MODULE_NAME"); EmitConstructor>]
11+
static member Foo () : Foo = nativeOnly
12+
13+
[<AllowNullLiteral>]
14+
[<Interface>]
15+
type Foo =
16+
abstract member id: string with get, set
17+
18+
(***)
19+
#r "nuget: Fable.Core"
20+
(***)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export class Foo {
2+
set id(value: string);
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module rec Glutinum
2+
3+
open Fable.Core
4+
open Fable.Core.JsInterop
5+
open System
6+
7+
[<AbstractClass>]
8+
[<Erase>]
9+
type Exports =
10+
[<Import("Foo", "REPLACE_ME_WITH_MODULE_NAME"); EmitConstructor>]
11+
static member Foo () : Foo = nativeOnly
12+
13+
[<AllowNullLiteral>]
14+
[<Interface>]
15+
type Foo =
16+
abstract member id: string with set
17+
18+
(***)
19+
#r "nuget: Fable.Core"
20+
(***)

0 commit comments

Comments
 (0)