@@ -2,10 +2,11 @@ open Belt;
22
33exception ReasonGenerationError ( string) ;
44
5- let extractName = identifier=>
5+ let rec extractName = identifier=>
66switch (identifier) {
77| DotTyped . Identifier (id )=> id
88| DotTyped . UnknownIdentifier => "Unknown"
9+ | DotTyped . MemberAccess (id , member )=> id++ "." ++ extractName(member)
910 };
1011
1112let extractTypeName = identifier=> {
@@ -41,14 +42,22 @@ let rec fromDotTyped =
4142 (extractName(name), fromDotTyped(type_), optional)
4243 ),
4344 fromDotTyped(returnType),
44- );
45+ )
46+
47+ | _ => raise (ReasonGenerationError ("Unknown dottyped type" ));
4548
46- let rec compile = (~moduleName=?, moduleDefinition)=>
49+ let rec compile = (~moduleName=?, ~typeTable =?, moduleDefinition)=>
4750switch (moduleDefinition) {
4851| DotTyped . ModuleDeclaration ({name, declarations})=>
4952let declarations =
50- Array . map(declarations, compile(~moduleName= extractName(name)));
51- Js . Array . joinWith("\n " , declarations);
53+ Array . map(
54+ declarations,
55+ compile(
56+ ~moduleName= extractName(name),
57+ ~typeTable= TypeTable2 . make(declarations),
58+ ),
59+ );
60+ Js . Array . joinWith("\n " , declarations)|. Reason . parseRE|. Reason . printRE;
5261
5362| DotTyped . ReactComponent ({name, type_: DotTyped . Object (propTypes )})=>
5463Rabel . module_(
@@ -78,6 +87,16 @@ let rec compile = (~moduleName=?, moduleDefinition) =>
7887 )
7988
8089| DotTyped . ReactComponent ({name, type_: DotTyped . Named (propTypesName )})=>
90+ let maybePropTypes =
91+ Map . String . get(Option . getExn(typeTable), extractName(propTypesName));
92+ let propTypes =
93+ switch (maybePropTypes) {
94+ | Some (DotTyped . Object (p ))=> p
95+ | _ =>
96+ raise (ReasonGenerationError ("React prop types must be an object" ))
97+ };
98+ let hasOptional = Array . some(propTypes. properties, prop=> prop. optional);
99+
81100Rabel . module_(
82101 extractModuleName(name),
83102[|
@@ -92,12 +111,39 @@ let rec compile = (~moduleName=?, moduleDefinition) =>
92111Rabel . let_(
93112"make" ,
94113Rabel . function_(
95- Array . concat([||] , [| ("children" , false , None )|] ),
96- extractModuleName(propTypesName)++ ".t" ,
114+ Array . concat(
115+ Array . map(propTypes. properties, prop=>
116+ (
117+ extractName(prop. name),
118+ true ,
119+ prop. optional? Some ("?" ): None ,
120+ )
121+ ),
122+ [| ("children" , false , None )|] ,
123+ ),
124+ Rabel . Ast . apply(
125+ "ReasonReact.wrapJsForReason" ,
126+ [|
127+ "~reactClass" ,
128+ "~props="
129+ ++ Rabel . Ast . apply(
130+ extractModuleName(propTypesName)++ ".t" ,
131+ Array . concat(
132+ Array . map(propTypes. properties, prop=>
133+ "~"
134+ ++ extractName(prop. name)
135+ ++ (prop. optional? "?" : "" )
136+ ),
137+ hasOptional? [| "()" |] : [||] ,
138+ ),
139+ ),
140+ "children" ,
141+ |] ,
142+ ),
97143 ),
98144 ),
99145|] ,
100- )
146+ );
101147
102148| DotTyped . LetDeclaration ({name, type_})=>
103149Rabel . Decorators . bsModule(
@@ -113,10 +159,10 @@ let rec compile = (~moduleName=?, moduleDefinition) =>
113159Rabel . module_(
114160 extractModuleName(name),
115161[|
116- Rabel . type_ (
117- "t " ,
118- Rabel . Decorators . bsDeriving (
119- "abstract " ,
162+ Rabel . Decorators . bsDeriving (
163+ "abstract " ,
164+ Rabel . type_ (
165+ "t " ,
120166Rabel . Types . record_(
121167Array . map(properties, prop=>
122168 (
@@ -143,4 +189,6 @@ let rec compile = (~moduleName=?, moduleDefinition) =>
143189 extractName(name),
144190 ),
145191 )
192+
193+ | _ => raise (ReasonGenerationError ("Unknown dottyped declaration" ))
146194 };