@@ -35,13 +35,15 @@ pub struct Context<'a> {
35
35
36
36
#[ derive( Default ) ]
37
37
pub struct ExportedClass {
38
+ comments : String ,
38
39
contents : String ,
39
40
typescript : String ,
40
41
constructor : Option < String > ,
41
42
fields : Vec < ClassField > ,
42
43
}
43
44
44
45
struct ClassField {
46
+ comments : String ,
45
47
name : String ,
46
48
readonly : bool ,
47
49
}
@@ -52,9 +54,12 @@ pub struct SubContext<'a, 'b: 'a> {
52
54
}
53
55
54
56
impl < ' a > Context < ' a > {
55
- fn export ( & mut self , name : & str , contents : & str ) {
57
+ fn export ( & mut self , name : & str , contents : & str , comments : Option < String > ) {
56
58
let contents = deindent ( contents) ;
57
59
let contents = contents. trim ( ) ;
60
+ if let Some ( ref c) = comments {
61
+ self . globals . push_str ( c) ;
62
+ }
58
63
let global = if self . config . nodejs {
59
64
if contents. starts_with ( "class" ) {
60
65
format ! ( "{1}\n module.exports.{0} = {0};\n " , name, contents)
@@ -396,7 +401,7 @@ impl<'a> Context<'a> {
396
401
. with_context ( |_| {
397
402
format ! ( "failed to generate internal JS function `{}`" , name)
398
403
} ) ?;
399
- self . export ( name, & contents) ;
404
+ self . export ( name, & contents, None ) ;
400
405
Ok ( ( ) )
401
406
}
402
407
@@ -461,7 +466,7 @@ impl<'a> Context<'a> {
461
466
function(ptr) {{
462
467
return addHeapObject({}.__construct(ptr));
463
468
}}
464
- " , name) ) ;
469
+ " , name) , None ) ;
465
470
}
466
471
467
472
for field in class. fields . iter ( ) {
@@ -484,7 +489,10 @@ impl<'a> Context<'a> {
484
489
. method ( true )
485
490
. ret ( & Some ( descriptor) ) ?
486
491
. finish ( "" , & format ! ( "wasm.{}" , wasm_getter) ) ;
487
-
492
+ if !dst. ends_with ( "\n " ) {
493
+ dst. push_str ( "\n " ) ;
494
+ }
495
+ dst. push_str ( & field. comments ) ;
488
496
dst. push_str ( "get " ) ;
489
497
dst. push_str ( & field. name ) ;
490
498
dst. push_str ( & get) ;
@@ -504,13 +512,12 @@ impl<'a> Context<'a> {
504
512
}}
505
513
" , shared:: free_function( & name) ) ) ;
506
514
ts_dst. push_str ( "free(): void;\n " ) ;
507
-
508
515
dst. push_str ( & class. contents ) ;
509
516
ts_dst. push_str ( & class. typescript ) ;
510
517
dst. push_str ( "}\n " ) ;
511
518
ts_dst. push_str ( "}\n " ) ;
512
519
513
- self . export ( & name, & dst) ;
520
+ self . export ( & name, & dst, Some ( class . comments . clone ( ) ) ) ;
514
521
self . typescript . push_str ( & ts_dst) ;
515
522
516
523
Ok ( ( ) )
@@ -534,7 +541,7 @@ impl<'a> Context<'a> {
534
541
535
542
fn rewrite_imports ( & mut self , module_name : & str ) {
536
543
for ( name, contents) in self . _rewrite_imports ( module_name) {
537
- self . export ( & name, & contents) ;
544
+ self . export ( & name, & contents, None ) ;
538
545
}
539
546
}
540
547
@@ -691,7 +698,7 @@ impl<'a> Context<'a> {
691
698
return;
692
699
throw new Error('stack is not currently empty');
693
700
}
694
- " ) ;
701
+ " , None ) ;
695
702
}
696
703
}
697
704
@@ -715,7 +722,7 @@ impl<'a> Context<'a> {
715
722
throw new Error('slab is not currently empty');
716
723
}}
717
724
}}
718
- " , initial_values. len( ) ) ) ;
725
+ " , initial_values. len( ) ) , None ) ;
719
726
}
720
727
}
721
728
@@ -1406,7 +1413,7 @@ impl<'a> Context<'a> {
1406
1413
1407
1414
// Ensure a blank line between adjacent items, and ensure everything is
1408
1415
// terminated with a newline.
1409
- while !self . globals . ends_with ( "\n \n \n " ) {
1416
+ while !self . globals . ends_with ( "\n \n \n " ) && ! self . globals . ends_with ( "*/ \n " ) {
1410
1417
self . globals . push_str ( "\n " ) ;
1411
1418
}
1412
1419
self . globals . push_str ( s) ;
@@ -1452,14 +1459,16 @@ impl<'a, 'b> SubContext<'a, 'b> {
1452
1459
self . generate_enum ( e) ;
1453
1460
}
1454
1461
for s in self . program . structs . iter ( ) {
1455
- self . cx . exported_classes
1462
+ let mut class = self . cx . exported_classes
1456
1463
. entry ( s. name . clone ( ) )
1457
- . or_insert_with ( Default :: default)
1458
- . fields
1459
- . extend ( s. fields . iter ( ) . map ( |s| {
1464
+ . or_insert_with ( Default :: default) ;
1465
+ class. comments = format_doc_comments ( & s. comments ) ;
1466
+ class. fields
1467
+ . extend ( s. fields . iter ( ) . map ( |f| {
1460
1468
ClassField {
1461
- name : s. name . clone ( ) ,
1462
- readonly : s. readonly ,
1469
+ name : f. name . clone ( ) ,
1470
+ readonly : f. readonly ,
1471
+ comments : format_doc_comments ( & f. comments ) ,
1463
1472
}
1464
1473
} ) ) ;
1465
1474
}
@@ -1477,7 +1486,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
1477
1486
let ( js, ts) = Js2Rust :: new ( & export. function . name , self . cx )
1478
1487
. process ( descriptor. unwrap_function ( ) ) ?
1479
1488
. finish ( "function" , & format ! ( "wasm.{}" , export. function. name) ) ;
1480
- self . cx . export ( & export. function . name , & js) ;
1489
+ self . cx . export ( & export. function . name , & js, Some ( format_doc_comments ( & export . comments ) ) ) ;
1481
1490
self . cx . globals . push_str ( "\n " ) ;
1482
1491
self . cx . typescript . push_str ( "export " ) ;
1483
1492
self . cx . typescript . push_str ( & ts) ;
@@ -1498,6 +1507,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
1498
1507
. finish ( "" , & format ! ( "wasm.{}" , wasm_name) ) ;
1499
1508
let class = self . cx . exported_classes . entry ( class_name. to_string ( ) )
1500
1509
. or_insert ( ExportedClass :: default ( ) ) ;
1510
+ class. contents . push_str ( & format_doc_comments ( & export. comments ) ) ;
1501
1511
if !export. method {
1502
1512
class. contents . push_str ( "static " ) ;
1503
1513
class. typescript . push_str ( "static " ) ;
@@ -1514,7 +1524,6 @@ impl<'a, 'b> SubContext<'a, 'b> {
1514
1524
1 => Some ( constructors[ 0 ] . clone ( ) ) ,
1515
1525
x @ _ => bail ! ( "there must be only one constructor, not {}" , x) ,
1516
1526
} ;
1517
-
1518
1527
class. contents . push_str ( & export. function . name ) ;
1519
1528
class. contents . push_str ( & js) ;
1520
1529
class. contents . push_str ( "\n " ) ;
@@ -1593,7 +1602,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
1593
1602
function() {{
1594
1603
return addHeapObject({});
1595
1604
}}
1596
- " , obj) ) ;
1605
+ " , obj) , None ) ;
1597
1606
Ok ( ( ) )
1598
1607
}
1599
1608
@@ -1688,7 +1697,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
1688
1697
. catch ( import. catch )
1689
1698
. process ( descriptor. unwrap_function ( ) ) ?
1690
1699
. finish ( & target) ;
1691
- self . cx . export ( & import. shim , & js) ;
1700
+ self . cx . export ( & import. shim , & js, None ) ;
1692
1701
Ok ( ( ) )
1693
1702
}
1694
1703
@@ -1698,7 +1707,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
1698
1707
for variant in enum_. variants . iter ( ) {
1699
1708
variants. push_str ( & format ! ( "{}:{}," , variant. name, variant. value) ) ;
1700
1709
}
1701
- self . cx . export ( & enum_. name , & format ! ( "Object.freeze({{ {} }})" , variants) ) ;
1710
+ self . cx . export ( & enum_. name , & format ! ( "Object.freeze({{ {} }})" , variants) , Some ( format_doc_comments ( & enum_ . comments ) ) ) ;
1702
1711
self . cx . typescript . push_str ( & format ! ( "export enum {} {{" , enum_. name) ) ;
1703
1712
1704
1713
variants. clear ( ) ;
@@ -1764,3 +1773,9 @@ fn deindent(s: &str) -> String {
1764
1773
}
1765
1774
ret
1766
1775
}
1776
+
1777
+
1778
+ fn format_doc_comments ( comments : & Vec < String > ) -> String {
1779
+ let body: String = comments. iter ( ) . map ( |c| format ! ( "*{}\n " , c. trim_matches( '"' ) ) ) . collect ( ) ;
1780
+ format ! ( "/**\n {}*/\n " , body)
1781
+ }
0 commit comments