@@ -597,7 +597,10 @@ impl Compiler {
597
597
self . in_loop = false ;
598
598
self . in_function_def = true ;
599
599
let mut flags = self . enter_function ( name, args) ?;
600
- self . compile_statements ( body) ?;
600
+
601
+ let ( new_body, doc_str) = get_doc ( body) ;
602
+
603
+ self . compile_statements ( new_body) ?;
601
604
602
605
// Emit None at end:
603
606
self . emit ( Instruction :: LoadConst {
@@ -662,6 +665,20 @@ impl Compiler {
662
665
self . emit ( Instruction :: StoreName {
663
666
name : name. to_string ( ) ,
664
667
} ) ;
668
+
669
+ if let Some ( doc_string) = doc_str {
670
+ self . emit ( Instruction :: LoadConst {
671
+ value : bytecode:: Constant :: String {
672
+ value : doc_string. to_string ( ) ,
673
+ } ,
674
+ } ) ;
675
+ self . emit ( Instruction :: LoadName {
676
+ name : name. to_string ( ) ,
677
+ } ) ;
678
+ self . emit ( Instruction :: StoreAttr {
679
+ name : "__doc__" . to_string ( ) ,
680
+ } ) ;
681
+ }
665
682
self . in_loop = was_in_loop;
666
683
self . in_function_def = was_in_function_def;
667
684
Ok ( ( ) )
@@ -689,13 +706,17 @@ impl Compiler {
689
706
line_number,
690
707
name. to_string ( ) ,
691
708
) ) ;
692
- self . compile_statements ( body) ?;
709
+
710
+ let ( new_body, doc_str) = get_doc ( body) ;
711
+
712
+ self . compile_statements ( new_body) ?;
693
713
self . emit ( Instruction :: LoadConst {
694
714
value : bytecode:: Constant :: None ,
695
715
} ) ;
696
716
self . emit ( Instruction :: ReturnValue ) ;
697
717
698
718
let code = self . pop_code_object ( ) ;
719
+
699
720
self . emit ( Instruction :: LoadConst {
700
721
value : bytecode:: Constant :: Code {
701
722
code : Box :: new ( code) ,
@@ -755,6 +776,19 @@ impl Compiler {
755
776
self . emit ( Instruction :: StoreName {
756
777
name : name. to_string ( ) ,
757
778
} ) ;
779
+ if let Some ( doc_string) = doc_str {
780
+ self . emit ( Instruction :: LoadConst {
781
+ value : bytecode:: Constant :: String {
782
+ value : doc_string. to_string ( ) ,
783
+ } ,
784
+ } ) ;
785
+ self . emit ( Instruction :: LoadName {
786
+ name : name. to_string ( ) ,
787
+ } ) ;
788
+ self . emit ( Instruction :: StoreAttr {
789
+ name : "__doc__" . to_string ( ) ,
790
+ } ) ;
791
+ }
758
792
self . in_loop = was_in_loop;
759
793
Ok ( ( ) )
760
794
}
@@ -1511,6 +1545,21 @@ impl Compiler {
1511
1545
}
1512
1546
}
1513
1547
1548
+ fn get_doc ( body : & [ ast:: LocatedStatement ] ) -> ( & [ ast:: LocatedStatement ] , Option < String > ) {
1549
+ if let Some ( val) = body. get ( 0 ) {
1550
+ if let ast:: Statement :: Expression { ref expression } = val. node {
1551
+ if let ast:: Expression :: String { ref value } = expression {
1552
+ if let ast:: StringGroup :: Constant { ref value } = value {
1553
+ if let Some ( ( _, body_rest) ) = body. split_first ( ) {
1554
+ return ( body_rest, Some ( value. to_string ( ) ) ) ;
1555
+ }
1556
+ }
1557
+ }
1558
+ }
1559
+ }
1560
+ ( body, None )
1561
+ }
1562
+
1514
1563
#[ cfg( test) ]
1515
1564
mod tests {
1516
1565
use super :: Compiler ;
0 commit comments