@@ -622,6 +622,31 @@ def generate_exports(
622
622
package_suggests ,
623
623
** kwargs
624
624
):
625
+ export_string = make_namespace_exports (components , prefix )
626
+
627
+ # Look for wildcards in the metadata
628
+ has_wildcards = False
629
+ for component_data in metadata .values ():
630
+ if any (key .endswith ('-*' ) for key in component_data ['props' ]):
631
+ has_wildcards = True
632
+ break
633
+
634
+ # now, bundle up the package information and create all the requisite
635
+ # elements of an R package, so that the end result is installable either
636
+ # locally or directly from GitHub
637
+ generate_rpkg (
638
+ pkg_data ,
639
+ rpkg_data ,
640
+ project_shortname ,
641
+ export_string ,
642
+ package_depends ,
643
+ package_imports ,
644
+ package_suggests ,
645
+ has_wildcards ,
646
+ )
647
+
648
+
649
+ def make_namespace_exports (components , prefix ):
625
650
export_string = ""
626
651
for component in components :
627
652
if (
@@ -639,46 +664,49 @@ def generate_exports(
639
664
omitlist = ["utils.R" , "internal.R" ] + [
640
665
"{}{}.R" .format (prefix , component ) for component in components
641
666
]
642
- stripped_line = ""
643
667
fnlist = []
644
668
645
669
for script in os .listdir ("R" ):
646
670
if script .endswith (".R" ) and script not in omitlist :
647
671
rfilelist += [os .path .join ("R" , script )]
648
672
649
- # in R, either = or <- may be used to create and assign objects
650
- definitions = ["<-function" , "=function" ]
651
-
652
673
for rfile in rfilelist :
653
674
with open (rfile , "r" ) as script :
654
- for line in script :
655
- stripped_line = line .replace (" " , "" ).replace ("\n " , "" )
656
- if any (fndef in stripped_line for fndef in definitions ):
657
- fnlist += set ([re .split ("<-|=" , stripped_line )[0 ]])
675
+ s = script .read ()
676
+
677
+ # remove comments
678
+ s = re .sub ('#.*$' , '' , s , flags = re .M )
679
+
680
+ # put the whole file on one line
681
+ s = s .replace ("\n " , " " ).replace ("\r " , " " )
682
+
683
+ # empty out strings, in case of unmatched block terminators
684
+ s = re .sub (r"'([^'\\]|\\'|\\[^'])*'" , "''" , s )
685
+ s = re .sub (r'"([^"\\]|\\"|\\[^"])*"' , '""' , s )
686
+
687
+ # empty out block terminators () and {}
688
+ # so we don't catch nested functions, or functions as arguments
689
+ # repeat until it stops changing, in case of multiply nested blocks
690
+ prev_len = len (s ) + 1
691
+ while len (s ) < prev_len :
692
+ prev_len = len (s )
693
+ s = re .sub (r"\(([^()]|\(\))*\)" , "()" , s )
694
+ s = re .sub (r"\{([^{}]|\{\})*\}" , "{}" , s )
695
+
696
+ # now, in whatever is left, look for functions
697
+ matches = re .findall (
698
+ # in R, either = or <- may be used to create and assign objects
699
+ r"([^A-Za-z0-9._]|^)([A-Za-z0-9._]+)\s*(=|<-)\s*function" , s
700
+ )
701
+ for match in matches :
702
+ fn = match [1 ]
703
+ # Allow users to mark functions as private by prefixing with .
704
+ if fn [0 ] != "." and fn not in fnlist :
705
+ fnlist .append (fn )
658
706
659
707
export_string += "\n " .join ("export({})" .format (function )
660
708
for function in fnlist )
661
-
662
- # Look for wildcards in the metadata
663
- has_wildcards = False
664
- for component_data in metadata .values ():
665
- if any (key .endswith ('-*' ) for key in component_data ['props' ]):
666
- has_wildcards = True
667
- break
668
-
669
- # now, bundle up the package information and create all the requisite
670
- # elements of an R package, so that the end result is installable either
671
- # locally or directly from GitHub
672
- generate_rpkg (
673
- pkg_data ,
674
- rpkg_data ,
675
- project_shortname ,
676
- export_string ,
677
- package_depends ,
678
- package_imports ,
679
- package_suggests ,
680
- has_wildcards ,
681
- )
709
+ return export_string
682
710
683
711
684
712
def get_r_prop_types (type_object ):
0 commit comments