Skip to main content

perl_lexer/builtins/
builtin_signatures.rs

1//! Comprehensive built-in function signatures for Perl scripting.
2//!
3//! This module provides signature information for Perl built-in functions with
4//! a focus on parser and LSP feature support. It enables accurate completion,
5//! hover, and signature help for common built-ins.
6//!
7//! # LSP Workflow Integration
8//!
9//! - **Parse**: Identifies built-in calls for syntax understanding
10//! - **Index**: Classifies symbols for reference tracking
11//! - **Navigate**: Powers signature help and related navigation context
12//! - **Complete**: Supplies completion labels and arguments
13//! - **Analyze**: Supports diagnostics that rely on built-in semantics
14
15use std::collections::HashMap;
16use std::sync::OnceLock;
17
18/// Built-in function signature with documentation for Perl script development
19///
20/// Contains complete signature information and documentation for Perl built-in
21/// functions, optimized for Perl parsing use cases within LSP workflows.
22pub struct BuiltinSignature {
23    /// Function signature variants showing different parameter combinations
24    pub signatures: Vec<&'static str>,
25    /// Comprehensive documentation explaining function behavior and Perl parsing use cases
26    pub documentation: &'static str,
27}
28
29static SIGNATURES_CACHE: OnceLock<HashMap<&'static str, BuiltinSignature>> = OnceLock::new();
30
31/// Create comprehensive built-in function signatures
32pub fn create_builtin_signatures() -> &'static HashMap<&'static str, BuiltinSignature> {
33    SIGNATURES_CACHE.get_or_init(|| {
34        let mut signatures = HashMap::new();
35
36        // ===== I/O Functions =====
37        signatures.insert(
38            "print",
39            BuiltinSignature {
40                signatures: vec![
41                    "print FILEHANDLE LIST",
42                    "print FILEHANDLE",
43                    "print LIST",
44                    "print",
45                ],
46                documentation: "Prints a string or list of strings to a filehandle",
47            },
48        );
49
50        signatures.insert(
51            "printf",
52            BuiltinSignature {
53                signatures: vec!["printf FILEHANDLE FORMAT, LIST", "printf FORMAT, LIST"],
54                documentation: "Prints a formatted string",
55            },
56        );
57
58        signatures.insert(
59            "say",
60            BuiltinSignature {
61                signatures: vec!["say FILEHANDLE LIST", "say FILEHANDLE", "say LIST", "say"],
62                documentation: "Prints with a newline",
63            },
64        );
65
66        signatures.insert(
67            "open",
68            BuiltinSignature {
69                signatures: vec![
70                    "open FILEHANDLE, MODE, FILENAME",
71                    "open FILEHANDLE, EXPR",
72                    "open FILEHANDLE",
73                ],
74                documentation: "Opens a file",
75            },
76        );
77
78        signatures.insert(
79            "XSLoader::load",
80            BuiltinSignature {
81                signatures: vec!["XSLoader::load MODULE, VERSION"],
82                documentation: "Loads an XS extension for a module",
83            },
84        );
85
86        signatures.insert(
87            "DynaLoader::bootstrap",
88            BuiltinSignature {
89                signatures: vec!["DynaLoader::bootstrap MODULE, VERSION"],
90                documentation: "Bootstraps an XS extension via DynaLoader",
91            },
92        );
93
94        signatures.insert(
95            "bootstrap",
96            BuiltinSignature {
97                signatures: vec!["bootstrap MODULE, VERSION"],
98                documentation: "Bootstraps an XS extension via DynaLoader",
99            },
100        );
101
102        signatures.insert(
103            "sysopen",
104            BuiltinSignature {
105                signatures: vec![
106                    "sysopen FILEHANDLE, FILENAME, MODE, PERMS",
107                    "sysopen FILEHANDLE, FILENAME, MODE",
108                ],
109                documentation: "Opens a file using system call semantics",
110            },
111        );
112
113        signatures.insert(
114            "close",
115            BuiltinSignature {
116                signatures: vec!["close FILEHANDLE", "close"],
117                documentation: "Closes a filehandle",
118            },
119        );
120
121        signatures.insert(
122            "read",
123            BuiltinSignature {
124                signatures: vec![
125                    "read FILEHANDLE, SCALAR, LENGTH, OFFSET",
126                    "read FILEHANDLE, SCALAR, LENGTH",
127                ],
128                documentation: "Reads from a filehandle into a scalar",
129            },
130        );
131
132        signatures.insert(
133            "readline",
134            BuiltinSignature {
135                signatures: vec!["readline FILEHANDLE", "readline"],
136                documentation: "Reads a line from a filehandle",
137            },
138        );
139
140        signatures.insert(
141            "readpipe",
142            BuiltinSignature {
143                signatures: vec!["readpipe EXPR", "readpipe"],
144                documentation: "Executes a command and returns its output",
145            },
146        );
147
148        signatures.insert(
149            "sysread",
150            BuiltinSignature {
151                signatures: vec![
152                    "sysread FILEHANDLE, SCALAR, LENGTH, OFFSET",
153                    "sysread FILEHANDLE, SCALAR, LENGTH",
154                ],
155                documentation: "Reads from a filehandle bypassing stdio",
156            },
157        );
158
159        signatures.insert(
160            "write",
161            BuiltinSignature {
162                signatures: vec!["write FILEHANDLE", "write"],
163                documentation: "Writes a formatted record",
164            },
165        );
166
167        signatures.insert(
168            "syswrite",
169            BuiltinSignature {
170                signatures: vec![
171                    "syswrite FILEHANDLE, SCALAR, LENGTH, OFFSET",
172                    "syswrite FILEHANDLE, SCALAR, LENGTH",
173                    "syswrite FILEHANDLE, SCALAR",
174                ],
175                documentation: "Writes to a filehandle bypassing stdio",
176            },
177        );
178
179        signatures.insert(
180            "seek",
181            BuiltinSignature {
182                signatures: vec!["seek FILEHANDLE, POSITION, WHENCE"],
183                documentation: "Sets file pointer position",
184            },
185        );
186
187        signatures.insert(
188            "tell",
189            BuiltinSignature {
190                signatures: vec!["tell FILEHANDLE", "tell"],
191                documentation: "Returns current file position",
192            },
193        );
194
195        signatures.insert(
196            "eof",
197            BuiltinSignature {
198                signatures: vec!["eof FILEHANDLE", "eof"],
199                documentation: "Tests for end of file",
200            },
201        );
202
203        // ===== String Functions =====
204        signatures.insert(
205            "chomp",
206            BuiltinSignature {
207                signatures: vec!["chomp VARIABLE", "chomp LIST", "chomp"],
208                documentation: "Removes trailing newline from string",
209            },
210        );
211
212        signatures.insert(
213            "chop",
214            BuiltinSignature {
215                signatures: vec!["chop VARIABLE", "chop LIST", "chop"],
216                documentation: "Removes last character from string",
217            },
218        );
219
220        signatures.insert(
221            "chr",
222            BuiltinSignature {
223                signatures: vec!["chr NUMBER", "chr"],
224                documentation: "Returns character for a number",
225            },
226        );
227
228        signatures.insert(
229            "ord",
230            BuiltinSignature {
231                signatures: vec!["ord EXPR", "ord"],
232                documentation: "Returns numeric value of character",
233            },
234        );
235
236        signatures.insert(
237            "hex",
238            BuiltinSignature {
239                signatures: vec!["hex EXPR", "hex"],
240                documentation: "Converts hex string to number",
241            },
242        );
243
244        signatures.insert(
245            "oct",
246            BuiltinSignature {
247                signatures: vec!["oct EXPR", "oct"],
248                documentation: "Converts octal string to number",
249            },
250        );
251
252        signatures.insert(
253            "length",
254            BuiltinSignature {
255                signatures: vec!["length EXPR", "length"],
256                documentation: "Returns length of string",
257            },
258        );
259
260        signatures.insert(
261            "substr",
262            BuiltinSignature {
263                signatures: vec![
264                    "substr EXPR, OFFSET, LENGTH, REPLACEMENT",
265                    "substr EXPR, OFFSET, LENGTH",
266                    "substr EXPR, OFFSET",
267                ],
268                documentation: "Extracts or replaces substring",
269            },
270        );
271
272        signatures.insert(
273            "index",
274            BuiltinSignature {
275                signatures: vec!["index STR, SUBSTR, POSITION", "index STR, SUBSTR"],
276                documentation: "Finds position of substring",
277            },
278        );
279
280        signatures.insert(
281            "rindex",
282            BuiltinSignature {
283                signatures: vec!["rindex STR, SUBSTR, POSITION", "rindex STR, SUBSTR"],
284                documentation: "Finds position of substring from end",
285            },
286        );
287
288        signatures.insert(
289            "sprintf",
290            BuiltinSignature {
291                signatures: vec!["sprintf FORMAT, LIST"],
292                documentation: "Returns formatted string",
293            },
294        );
295
296        signatures.insert(
297            "lc",
298            BuiltinSignature {
299                signatures: vec!["lc EXPR", "lc"],
300                documentation: "Returns lowercase version",
301            },
302        );
303
304        signatures.insert(
305            "lcfirst",
306            BuiltinSignature {
307                signatures: vec!["lcfirst EXPR", "lcfirst"],
308                documentation: "Returns string with first char lowercase",
309            },
310        );
311
312        signatures.insert(
313            "uc",
314            BuiltinSignature {
315                signatures: vec!["uc EXPR", "uc"],
316                documentation: "Returns uppercase version",
317            },
318        );
319
320        signatures.insert(
321            "ucfirst",
322            BuiltinSignature {
323                signatures: vec!["ucfirst EXPR", "ucfirst"],
324                documentation: "Returns string with first char uppercase",
325            },
326        );
327
328        signatures.insert(
329            "quotemeta",
330            BuiltinSignature {
331                signatures: vec!["quotemeta EXPR", "quotemeta"],
332                documentation: "Quotes metacharacters",
333            },
334        );
335
336        signatures.insert(
337            "split",
338            BuiltinSignature {
339                signatures: vec![
340                    "split /PATTERN/, EXPR, LIMIT",
341                    "split /PATTERN/, EXPR",
342                    "split /PATTERN/",
343                    "split",
344                ],
345                documentation: "Splits string into list",
346            },
347        );
348
349        signatures.insert(
350            "join",
351            BuiltinSignature {
352                signatures: vec!["join EXPR, LIST"],
353                documentation: "Joins list into string",
354            },
355        );
356
357        signatures.insert(
358            "reverse",
359            BuiltinSignature {
360                signatures: vec!["reverse LIST"],
361                documentation: "Reverses list or string",
362            },
363        );
364
365        // ===== Array Functions =====
366        signatures.insert(
367            "push",
368            BuiltinSignature {
369                signatures: vec!["push ARRAY, LIST"],
370                documentation: "Appends values to array",
371            },
372        );
373
374        signatures.insert(
375            "pop",
376            BuiltinSignature {
377                signatures: vec!["pop ARRAY", "pop"],
378                documentation: "Removes and returns last element",
379            },
380        );
381
382        signatures.insert(
383            "shift",
384            BuiltinSignature {
385                signatures: vec!["shift ARRAY", "shift"],
386                documentation: "Removes and returns first element",
387            },
388        );
389
390        signatures.insert(
391            "unshift",
392            BuiltinSignature {
393                signatures: vec!["unshift ARRAY, LIST"],
394                documentation: "Prepends values to array",
395            },
396        );
397
398        signatures.insert(
399            "splice",
400            BuiltinSignature {
401                signatures: vec![
402                    "splice ARRAY, OFFSET, LENGTH, LIST",
403                    "splice ARRAY, OFFSET, LENGTH",
404                    "splice ARRAY, OFFSET",
405                    "splice ARRAY",
406                ],
407                documentation: "Removes and replaces array elements",
408            },
409        );
410
411        signatures.insert(
412            "map",
413            BuiltinSignature {
414                signatures: vec!["map BLOCK LIST", "map EXPR, LIST"],
415                documentation: "Transforms a list",
416            },
417        );
418
419        signatures.insert(
420            "grep",
421            BuiltinSignature {
422                signatures: vec!["grep BLOCK LIST", "grep EXPR, LIST"],
423                documentation: "Filters a list",
424            },
425        );
426
427        signatures.insert(
428            "sort",
429            BuiltinSignature {
430                signatures: vec!["sort BLOCK LIST", "sort SUBNAME LIST", "sort LIST"],
431                documentation: "Sorts a list",
432            },
433        );
434
435        // ===== Hash Functions =====
436        signatures.insert(
437            "each",
438            BuiltinSignature {
439                signatures: vec!["each HASH", "each ARRAY"],
440                documentation: "Returns key-value pair",
441            },
442        );
443
444        signatures.insert(
445            "keys",
446            BuiltinSignature {
447                signatures: vec!["keys HASH", "keys ARRAY"],
448                documentation: "Returns list of keys",
449            },
450        );
451
452        signatures.insert(
453            "values",
454            BuiltinSignature {
455                signatures: vec!["values HASH", "values ARRAY"],
456                documentation: "Returns list of values",
457            },
458        );
459
460        signatures.insert(
461            "exists",
462            BuiltinSignature {
463                signatures: vec!["exists EXPR"],
464                documentation: "Tests whether key exists",
465            },
466        );
467
468        signatures.insert(
469            "delete",
470            BuiltinSignature {
471                signatures: vec!["delete EXPR"],
472                documentation: "Deletes hash element",
473            },
474        );
475
476        // ===== File Test Operators =====
477        signatures.insert(
478            "stat",
479            BuiltinSignature {
480                signatures: vec!["stat FILEHANDLE", "stat EXPR", "stat"],
481                documentation: "Returns file statistics",
482            },
483        );
484
485        signatures.insert(
486            "lstat",
487            BuiltinSignature {
488                signatures: vec!["lstat FILEHANDLE", "lstat EXPR", "lstat"],
489                documentation: "Returns symbolic link statistics",
490            },
491        );
492
493        // ===== Directory Functions =====
494        signatures.insert(
495            "opendir",
496            BuiltinSignature {
497                signatures: vec!["opendir DIRHANDLE, EXPR"],
498                documentation: "Opens a directory",
499            },
500        );
501
502        signatures.insert(
503            "readdir",
504            BuiltinSignature {
505                signatures: vec!["readdir DIRHANDLE"],
506                documentation: "Reads directory entries",
507            },
508        );
509
510        signatures.insert(
511            "closedir",
512            BuiltinSignature {
513                signatures: vec!["closedir DIRHANDLE"],
514                documentation: "Closes a directory handle",
515            },
516        );
517
518        signatures.insert(
519            "rewinddir",
520            BuiltinSignature {
521                signatures: vec!["rewinddir DIRHANDLE"],
522                documentation: "Resets directory handle",
523            },
524        );
525
526        signatures.insert(
527            "telldir",
528            BuiltinSignature {
529                signatures: vec!["telldir DIRHANDLE"],
530                documentation: "Returns directory position",
531            },
532        );
533
534        signatures.insert(
535            "seekdir",
536            BuiltinSignature {
537                signatures: vec!["seekdir DIRHANDLE, POS"],
538                documentation: "Sets directory position",
539            },
540        );
541
542        // ===== File Operations =====
543        signatures.insert(
544            "chdir",
545            BuiltinSignature {
546                signatures: vec!["chdir EXPR", "chdir"],
547                documentation: "Changes the current working directory",
548            },
549        );
550
551        signatures.insert(
552            "chroot",
553            BuiltinSignature {
554                signatures: vec!["chroot FILENAME"],
555                documentation: "Changes the root directory for the process",
556            },
557        );
558
559        signatures.insert(
560            "chmod",
561            BuiltinSignature {
562                signatures: vec!["chmod MODE, LIST"],
563                documentation: "Changes file permissions",
564            },
565        );
566
567        signatures.insert(
568            "chown",
569            BuiltinSignature {
570                signatures: vec!["chown UID, GID, LIST"],
571                documentation: "Changes file ownership",
572            },
573        );
574
575        signatures.insert(
576            "link",
577            BuiltinSignature {
578                signatures: vec!["link OLDFILE, NEWFILE"],
579                documentation: "Creates hard link",
580            },
581        );
582
583        signatures.insert(
584            "symlink",
585            BuiltinSignature {
586                signatures: vec!["symlink OLDFILE, NEWFILE"],
587                documentation: "Creates symbolic link",
588            },
589        );
590
591        signatures.insert(
592            "readlink",
593            BuiltinSignature {
594                signatures: vec!["readlink EXPR", "readlink"],
595                documentation: "Reads symbolic link",
596            },
597        );
598
599        signatures.insert(
600            "rename",
601            BuiltinSignature {
602                signatures: vec!["rename OLDNAME, NEWNAME"],
603                documentation: "Renames a file",
604            },
605        );
606
607        signatures.insert(
608            "unlink",
609            BuiltinSignature {
610                signatures: vec!["unlink LIST", "unlink"],
611                documentation: "Deletes files",
612            },
613        );
614
615        signatures.insert(
616            "mkdir",
617            BuiltinSignature {
618                signatures: vec!["mkdir FILENAME, MODE", "mkdir FILENAME"],
619                documentation: "Creates directory",
620            },
621        );
622
623        signatures.insert(
624            "rmdir",
625            BuiltinSignature {
626                signatures: vec!["rmdir FILENAME", "rmdir"],
627                documentation: "Removes directory",
628            },
629        );
630
631        // ===== Process Functions =====
632        signatures.insert(
633            "system",
634            BuiltinSignature {
635                signatures: vec!["system LIST", "system PROGRAM LIST"],
636                documentation: "Executes system command",
637            },
638        );
639
640        signatures.insert(
641            "exec",
642            BuiltinSignature {
643                signatures: vec!["exec LIST", "exec PROGRAM LIST"],
644                documentation: "Executes system command (never returns)",
645            },
646        );
647
648        signatures.insert(
649            "fork",
650            BuiltinSignature { signatures: vec!["fork"], documentation: "Creates a child process" },
651        );
652
653        signatures.insert(
654            "wait",
655            BuiltinSignature { signatures: vec!["wait"], documentation: "Waits for child process" },
656        );
657
658        signatures.insert(
659            "waitpid",
660            BuiltinSignature {
661                signatures: vec!["waitpid PID, FLAGS"],
662                documentation: "Waits for specific child process",
663            },
664        );
665
666        signatures.insert(
667            "kill",
668            BuiltinSignature {
669                signatures: vec!["kill SIGNAL, LIST"],
670                documentation: "Sends signal to processes",
671            },
672        );
673
674        signatures.insert(
675            "getpid",
676            BuiltinSignature { signatures: vec!["getpid"], documentation: "Returns process ID" },
677        );
678
679        signatures.insert(
680            "getppid",
681            BuiltinSignature {
682                signatures: vec!["getppid"],
683                documentation: "Returns parent process ID",
684            },
685        );
686
687        // ===== Time Functions =====
688        signatures.insert(
689            "time",
690            BuiltinSignature { signatures: vec!["time"], documentation: "Returns current time" },
691        );
692
693        signatures.insert(
694            "localtime",
695            BuiltinSignature {
696                signatures: vec!["localtime EXPR", "localtime"],
697                documentation: "Converts time to local time",
698            },
699        );
700
701        signatures.insert(
702            "gmtime",
703            BuiltinSignature {
704                signatures: vec!["gmtime EXPR", "gmtime"],
705                documentation: "Converts time to GMT",
706            },
707        );
708
709        signatures.insert(
710            "sleep",
711            BuiltinSignature {
712                signatures: vec!["sleep EXPR", "sleep"],
713                documentation: "Sleeps for seconds",
714            },
715        );
716
717        signatures.insert(
718            "alarm",
719            BuiltinSignature {
720                signatures: vec!["alarm SECONDS", "alarm"],
721                documentation: "Sets alarm signal",
722            },
723        );
724
725        // ===== Mathematical Functions =====
726        signatures.insert(
727            "abs",
728            BuiltinSignature {
729                signatures: vec!["abs VALUE", "abs"],
730                documentation: "Returns absolute value",
731            },
732        );
733
734        signatures.insert(
735            "atan2",
736            BuiltinSignature {
737                signatures: vec!["atan2 Y, X"],
738                documentation: "Returns arctangent",
739            },
740        );
741
742        signatures.insert(
743            "cos",
744            BuiltinSignature {
745                signatures: vec!["cos EXPR", "cos"],
746                documentation: "Returns cosine",
747            },
748        );
749
750        signatures.insert(
751            "sin",
752            BuiltinSignature { signatures: vec!["sin EXPR", "sin"], documentation: "Returns sine" },
753        );
754
755        signatures.insert(
756            "exp",
757            BuiltinSignature {
758                signatures: vec!["exp EXPR", "exp"],
759                documentation: "Returns e raised to power",
760            },
761        );
762
763        signatures.insert(
764            "log",
765            BuiltinSignature {
766                signatures: vec!["log EXPR", "log"],
767                documentation: "Returns natural logarithm",
768            },
769        );
770
771        signatures.insert(
772            "sqrt",
773            BuiltinSignature {
774                signatures: vec!["sqrt EXPR", "sqrt"],
775                documentation: "Returns square root",
776            },
777        );
778
779        signatures.insert(
780            "int",
781            BuiltinSignature {
782                signatures: vec!["int EXPR", "int"],
783                documentation: "Returns integer portion",
784            },
785        );
786
787        signatures.insert(
788            "rand",
789            BuiltinSignature {
790                signatures: vec!["rand EXPR", "rand"],
791                documentation: "Returns random number",
792            },
793        );
794
795        signatures.insert(
796            "srand",
797            BuiltinSignature {
798                signatures: vec!["srand EXPR", "srand"],
799                documentation: "Seeds random number generator",
800            },
801        );
802
803        // ===== Type and Reference Functions =====
804        signatures.insert(
805            "ref",
806            BuiltinSignature {
807                signatures: vec!["ref EXPR", "ref"],
808                documentation: "Returns type of reference",
809            },
810        );
811
812        signatures.insert(
813            "bless",
814            BuiltinSignature {
815                signatures: vec!["bless REF, CLASSNAME", "bless REF"],
816                documentation: "Blesses reference into class",
817            },
818        );
819
820        signatures.insert(
821            "defined",
822            BuiltinSignature {
823                signatures: vec!["defined EXPR", "defined"],
824                documentation: "Tests whether value is defined",
825            },
826        );
827
828        signatures.insert(
829            "undef",
830            BuiltinSignature {
831                signatures: vec!["undef EXPR", "undef"],
832                documentation: "Undefines a value",
833            },
834        );
835
836        signatures.insert(
837            "scalar",
838            BuiltinSignature {
839                signatures: vec!["scalar EXPR"],
840                documentation: "Forces scalar context",
841            },
842        );
843
844        signatures.insert(
845            "wantarray",
846            BuiltinSignature {
847                signatures: vec!["wantarray"],
848                documentation: "Returns context of subroutine call",
849            },
850        );
851
852        // ===== Control Flow =====
853        signatures.insert(
854            "die",
855            BuiltinSignature {
856                signatures: vec!["die LIST", "die"],
857                documentation: "Raises an exception. Prefer Carp::croak in modules. Exception lands in $@ after eval",
858            },
859        );
860
861        signatures.insert(
862            "warn",
863            BuiltinSignature {
864                signatures: vec!["warn LIST", "warn"],
865                documentation: "Prints warning to STDERR. Prefer Carp::carp in modules",
866            },
867        );
868
869        signatures.insert(
870            "exit",
871            BuiltinSignature {
872                signatures: vec!["exit EXPR", "exit"],
873                documentation: "Exits the program",
874            },
875        );
876
877        signatures.insert(
878            "return",
879            BuiltinSignature {
880                signatures: vec!["return LIST", "return"],
881                documentation: "Returns from subroutine",
882            },
883        );
884
885        signatures.insert(
886            "next",
887            BuiltinSignature {
888                signatures: vec!["next LABEL", "next"],
889                documentation: "Starts next iteration of loop",
890            },
891        );
892
893        signatures.insert(
894            "last",
895            BuiltinSignature {
896                signatures: vec!["last LABEL", "last"],
897                documentation: "Exits loop",
898            },
899        );
900
901        signatures.insert(
902            "redo",
903            BuiltinSignature {
904                signatures: vec!["redo LABEL", "redo"],
905                documentation: "Restarts current iteration",
906            },
907        );
908
909        signatures.insert(
910            "goto",
911            BuiltinSignature {
912                signatures: vec!["goto LABEL", "goto EXPR", "goto &NAME"],
913                documentation: "Goes to label or subroutine",
914            },
915        );
916
917        // ===== Module Functions =====
918        signatures.insert(
919            "require",
920            BuiltinSignature {
921                signatures: vec!["require VERSION", "require MODULE", "require EXPR", "require"],
922                documentation: "Loads module or file",
923            },
924        );
925
926        signatures.insert(
927            "use",
928            BuiltinSignature {
929                signatures: vec![
930                    "use MODULE VERSION LIST",
931                    "use MODULE VERSION",
932                    "use MODULE LIST",
933                    "use MODULE",
934                    "use VERSION",
935                ],
936                documentation: "Imports module",
937            },
938        );
939
940        signatures.insert(
941            "no",
942            BuiltinSignature {
943                signatures: vec![
944                    "no MODULE VERSION LIST",
945                    "no MODULE VERSION",
946                    "no MODULE LIST",
947                    "no MODULE",
948                    "no VERSION",
949                ],
950                documentation: "Unimports module",
951            },
952        );
953
954        signatures.insert(
955            "import",
956            BuiltinSignature {
957                signatures: vec!["import MODULE LIST"],
958                documentation: "Imports symbols from module",
959            },
960        );
961
962        signatures.insert(
963            "unimport",
964            BuiltinSignature {
965                signatures: vec!["unimport MODULE LIST"],
966                documentation: "Unimports symbols from module",
967            },
968        );
969
970        // ===== Package Functions =====
971        signatures.insert(
972            "package",
973            BuiltinSignature {
974                signatures: vec!["package NAMESPACE VERSION", "package NAMESPACE"],
975                documentation: "Declares package namespace",
976            },
977        );
978
979        signatures.insert(
980            "caller",
981            BuiltinSignature {
982                signatures: vec!["caller EXPR", "caller"],
983                documentation: "Returns context of current subroutine call",
984            },
985        );
986
987        // ===== Eval and Do =====
988        signatures.insert(
989            "eval",
990            BuiltinSignature {
991                signatures: vec!["eval EXPR", "eval BLOCK"],
992                documentation: "Evaluates code",
993            },
994        );
995
996        signatures.insert(
997            "do",
998            BuiltinSignature {
999                signatures: vec!["do FILENAME", "do BLOCK"],
1000                documentation: "Executes file or block",
1001            },
1002        );
1003
1004        // ===== Tied Variables =====
1005        signatures.insert(
1006            "tie",
1007            BuiltinSignature {
1008                signatures: vec!["tie VARIABLE, CLASSNAME, LIST"],
1009                documentation: "Binds variable to class",
1010            },
1011        );
1012
1013        signatures.insert(
1014            "tied",
1015            BuiltinSignature {
1016                signatures: vec!["tied VARIABLE"],
1017                documentation: "Returns object tied to variable",
1018            },
1019        );
1020
1021        signatures.insert(
1022            "untie",
1023            BuiltinSignature {
1024                signatures: vec!["untie VARIABLE"],
1025                documentation: "Breaks binding on variable",
1026            },
1027        );
1028
1029        // ===== Socket Functions =====
1030        signatures.insert(
1031            "socket",
1032            BuiltinSignature {
1033                signatures: vec!["socket SOCKET, DOMAIN, TYPE, PROTOCOL"],
1034                documentation:
1035                    "Creates a socket. Returns true on success or undef on failure. See perldoc -f socket",
1036            },
1037        );
1038
1039        signatures.insert(
1040            "bind",
1041            BuiltinSignature {
1042                signatures: vec!["bind SOCKET, NAME"],
1043                documentation:
1044                    "Binds a packed address to a socket. Returns true on success or false on failure. See perldoc -f bind",
1045            },
1046        );
1047
1048        signatures.insert(
1049            "listen",
1050            BuiltinSignature {
1051                signatures: vec!["listen SOCKET, QUEUESIZE"],
1052                documentation:
1053                    "Marks a socket as accepting incoming connections. Returns true on success or false on failure. See perldoc -f listen",
1054            },
1055        );
1056
1057        signatures.insert(
1058            "accept",
1059            BuiltinSignature {
1060                signatures: vec!["accept NEWSOCKET, GENERICSOCKET"],
1061                documentation:
1062                    "Accepts an incoming socket connection. Returns the packed peer address on success or false on failure. See perldoc -f accept",
1063            },
1064        );
1065
1066        signatures.insert(
1067            "connect",
1068            BuiltinSignature {
1069                signatures: vec!["connect SOCKET, NAME"],
1070                documentation:
1071                    "Connects a socket to a packed peer address. Returns true on success or false on failure. See perldoc -f connect",
1072            },
1073        );
1074
1075        signatures.insert(
1076            "shutdown",
1077            BuiltinSignature {
1078                signatures: vec!["shutdown SOCKET, HOW"],
1079                documentation:
1080                    "Disables reads, writes, or both on a socket. Returns true on success or false on failure. See perldoc -f shutdown",
1081            },
1082        );
1083
1084        signatures.insert(
1085            "send",
1086            BuiltinSignature {
1087                signatures: vec!["send SOCKET, MSG, FLAGS, TO", "send SOCKET, MSG, FLAGS"],
1088                documentation:
1089                    "Sends a message on a socket. Returns the number of bytes sent or undef on failure. See perldoc -f send",
1090            },
1091        );
1092
1093        signatures.insert(
1094            "recv",
1095            BuiltinSignature {
1096                signatures: vec!["recv SOCKET, SCALAR, LENGTH, FLAGS"],
1097                documentation:
1098                    "Receives a message from a socket into a scalar buffer. Returns the sender address or an empty string at end of stream. See perldoc -f recv",
1099            },
1100        );
1101
1102        signatures.insert(
1103            "getsockopt",
1104            BuiltinSignature {
1105                signatures: vec!["getsockopt SOCKET, LEVEL, OPTNAME"],
1106                documentation:
1107                    "Reads a socket option value. Returns the packed option value or undef on failure. See perldoc -f getsockopt",
1108            },
1109        );
1110
1111        signatures.insert(
1112            "setsockopt",
1113            BuiltinSignature {
1114                signatures: vec!["setsockopt SOCKET, LEVEL, OPTNAME, OPTVAL"],
1115                documentation:
1116                    "Sets a socket option value. Returns true on success or false on failure. See perldoc -f setsockopt",
1117            },
1118        );
1119
1120        signatures.insert(
1121            "socketpair",
1122            BuiltinSignature {
1123                signatures: vec!["socketpair SOCKET1, SOCKET2, DOMAIN, TYPE, PROTOCOL"],
1124                documentation:
1125                    "Creates a pair of connected sockets. Returns true on success or false on failure. See perldoc -f socketpair",
1126            },
1127        );
1128
1129        signatures.insert(
1130            "sockatmark",
1131            BuiltinSignature {
1132                signatures: vec!["sockatmark SOCKET"],
1133                documentation: "Tests whether a socket is at an out-of-band mark",
1134            },
1135        );
1136
1137        signatures.insert(
1138            "getpeername",
1139            BuiltinSignature {
1140                signatures: vec!["getpeername SOCKET"],
1141                documentation: "Returns packed sockaddr address of other end of socket connection",
1142            },
1143        );
1144
1145        signatures.insert(
1146            "getsockname",
1147            BuiltinSignature {
1148                signatures: vec!["getsockname SOCKET"],
1149                documentation: "Returns packed sockaddr address of this end of socket connection",
1150            },
1151        );
1152
1153        // ===== I/O Control Functions =====
1154        signatures.insert(
1155            "pipe",
1156            BuiltinSignature {
1157                signatures: vec!["pipe READHANDLE, WRITEHANDLE"],
1158                documentation: "Opens a pair of connected pipes",
1159            },
1160        );
1161
1162        signatures.insert(
1163            "fcntl",
1164            BuiltinSignature {
1165                signatures: vec!["fcntl FILEHANDLE, FUNCTION, SCALAR"],
1166                documentation: "File control system call",
1167            },
1168        );
1169
1170        signatures.insert(
1171            "ioctl",
1172            BuiltinSignature {
1173                signatures: vec!["ioctl FILEHANDLE, FUNCTION, SCALAR"],
1174                documentation: "System-dependent device control system call",
1175            },
1176        );
1177
1178        signatures.insert(
1179            "flock",
1180            BuiltinSignature {
1181                signatures: vec!["flock FILEHANDLE, OPERATION"],
1182                documentation: "Locks or unlocks file",
1183            },
1184        );
1185
1186        signatures.insert(
1187            "select",
1188            BuiltinSignature {
1189                signatures: vec![
1190                    "select FILEHANDLE",
1191                    "select RBITS, WBITS, EBITS, TIMEOUT",
1192                    "select",
1193                ],
1194                documentation: "Sets default filehandle for output or performs select system call",
1195            },
1196        );
1197
1198        signatures.insert(
1199            "getc",
1200            BuiltinSignature {
1201                signatures: vec!["getc FILEHANDLE", "getc"],
1202                documentation: "Gets next character from filehandle",
1203            },
1204        );
1205
1206        signatures.insert(
1207            "binmode",
1208            BuiltinSignature {
1209                signatures: vec!["binmode FILEHANDLE, LAYER", "binmode FILEHANDLE"],
1210                documentation: "Sets binary mode on filehandle",
1211            },
1212        );
1213
1214        signatures.insert(
1215            "fileno",
1216            BuiltinSignature {
1217                signatures: vec!["fileno FILEHANDLE"],
1218                documentation: "Returns file descriptor number",
1219            },
1220        );
1221
1222        // ===== Network Functions =====
1223        signatures.insert(
1224            "gethostbyname",
1225            BuiltinSignature {
1226                signatures: vec!["gethostbyname NAME"],
1227                documentation: "Returns host information by name",
1228            },
1229        );
1230
1231        signatures.insert(
1232            "gethostbyaddr",
1233            BuiltinSignature {
1234                signatures: vec!["gethostbyaddr ADDR, ADDRTYPE"],
1235                documentation: "Returns host information by address",
1236            },
1237        );
1238
1239        signatures.insert(
1240            "getnetbyname",
1241            BuiltinSignature {
1242                signatures: vec!["getnetbyname NAME"],
1243                documentation: "Returns network information by name",
1244            },
1245        );
1246
1247        signatures.insert(
1248            "getnetbyaddr",
1249            BuiltinSignature {
1250                signatures: vec!["getnetbyaddr ADDR, ADDRTYPE"],
1251                documentation: "Returns network information by address",
1252            },
1253        );
1254
1255        signatures.insert(
1256            "getprotobyname",
1257            BuiltinSignature {
1258                signatures: vec!["getprotobyname NAME"],
1259                documentation: "Returns protocol information by name",
1260            },
1261        );
1262
1263        signatures.insert(
1264            "getprotobynumber",
1265            BuiltinSignature {
1266                signatures: vec!["getprotobynumber NUMBER"],
1267                documentation: "Returns protocol information by number",
1268            },
1269        );
1270
1271        signatures.insert(
1272            "getservbyname",
1273            BuiltinSignature {
1274                signatures: vec!["getservbyname NAME, PROTO"],
1275                documentation: "Returns service information by name",
1276            },
1277        );
1278
1279        signatures.insert(
1280            "getservbyport",
1281            BuiltinSignature {
1282                signatures: vec!["getservbyport PORT, PROTO"],
1283                documentation: "Returns service information by port",
1284            },
1285        );
1286
1287        signatures.insert(
1288            "gethostent",
1289            BuiltinSignature {
1290                signatures: vec!["gethostent"],
1291                documentation: "Returns next host from hosts file",
1292            },
1293        );
1294
1295        signatures.insert(
1296            "getnetent",
1297            BuiltinSignature {
1298                signatures: vec!["getnetent"],
1299                documentation: "Returns next network from networks file",
1300            },
1301        );
1302
1303        signatures.insert(
1304            "getprotoent",
1305            BuiltinSignature {
1306                signatures: vec!["getprotoent"],
1307                documentation: "Returns next protocol from protocols file",
1308            },
1309        );
1310
1311        signatures.insert(
1312            "getservent",
1313            BuiltinSignature {
1314                signatures: vec!["getservent"],
1315                documentation: "Returns next service from services file",
1316            },
1317        );
1318
1319        signatures.insert(
1320            "sethostent",
1321            BuiltinSignature {
1322                signatures: vec!["sethostent STAYOPEN"],
1323                documentation: "Opens or rewinds hosts file",
1324            },
1325        );
1326
1327        signatures.insert(
1328            "setnetent",
1329            BuiltinSignature {
1330                signatures: vec!["setnetent STAYOPEN"],
1331                documentation: "Opens or rewinds networks file",
1332            },
1333        );
1334
1335        signatures.insert(
1336            "setprotoent",
1337            BuiltinSignature {
1338                signatures: vec!["setprotoent STAYOPEN"],
1339                documentation: "Opens or rewinds protocols file",
1340            },
1341        );
1342
1343        signatures.insert(
1344            "setservent",
1345            BuiltinSignature {
1346                signatures: vec!["setservent STAYOPEN"],
1347                documentation: "Opens or rewinds services file",
1348            },
1349        );
1350
1351        signatures.insert(
1352            "endhostent",
1353            BuiltinSignature { signatures: vec!["endhostent"], documentation: "Closes hosts file" },
1354        );
1355
1356        signatures.insert(
1357            "endnetent",
1358            BuiltinSignature {
1359                signatures: vec!["endnetent"],
1360                documentation: "Closes networks file",
1361            },
1362        );
1363
1364        signatures.insert(
1365            "endprotoent",
1366            BuiltinSignature {
1367                signatures: vec!["endprotoent"],
1368                documentation: "Closes protocols file",
1369            },
1370        );
1371
1372        signatures.insert(
1373            "endservent",
1374            BuiltinSignature {
1375                signatures: vec!["endservent"],
1376                documentation: "Closes services file",
1377            },
1378        );
1379
1380        // ===== User and Group Functions =====
1381        signatures.insert(
1382            "getpwnam",
1383            BuiltinSignature {
1384                signatures: vec!["getpwnam NAME"],
1385                documentation: "Returns password entry by name",
1386            },
1387        );
1388
1389        signatures.insert(
1390            "getpwuid",
1391            BuiltinSignature {
1392                signatures: vec!["getpwuid UID"],
1393                documentation: "Returns password entry by uid",
1394            },
1395        );
1396
1397        signatures.insert(
1398            "getpwent",
1399            BuiltinSignature {
1400                signatures: vec!["getpwent"],
1401                documentation: "Returns next password entry",
1402            },
1403        );
1404
1405        signatures.insert(
1406            "setpwent",
1407            BuiltinSignature {
1408                signatures: vec!["setpwent"],
1409                documentation: "Rewinds password file",
1410            },
1411        );
1412
1413        signatures.insert(
1414            "endpwent",
1415            BuiltinSignature {
1416                signatures: vec!["endpwent"],
1417                documentation: "Closes password file",
1418            },
1419        );
1420
1421        signatures.insert(
1422            "getgrnam",
1423            BuiltinSignature {
1424                signatures: vec!["getgrnam NAME"],
1425                documentation: "Returns group entry by name",
1426            },
1427        );
1428
1429        signatures.insert(
1430            "getgrgid",
1431            BuiltinSignature {
1432                signatures: vec!["getgrgid GID"],
1433                documentation: "Returns group entry by gid",
1434            },
1435        );
1436
1437        signatures.insert(
1438            "getgrent",
1439            BuiltinSignature {
1440                signatures: vec!["getgrent"],
1441                documentation: "Returns next group entry",
1442            },
1443        );
1444
1445        signatures.insert(
1446            "setgrent",
1447            BuiltinSignature { signatures: vec!["setgrent"], documentation: "Rewinds group file" },
1448        );
1449
1450        signatures.insert(
1451            "endgrent",
1452            BuiltinSignature { signatures: vec!["endgrent"], documentation: "Closes group file" },
1453        );
1454
1455        signatures.insert(
1456            "getlogin",
1457            BuiltinSignature {
1458                signatures: vec!["getlogin"],
1459                documentation: "Returns current login name",
1460            },
1461        );
1462
1463        signatures.insert(
1464            "getuid",
1465            BuiltinSignature { signatures: vec!["getuid"], documentation: "Returns real user ID" },
1466        );
1467
1468        signatures.insert(
1469            "geteuid",
1470            BuiltinSignature {
1471                signatures: vec!["geteuid"],
1472                documentation: "Returns effective user ID",
1473            },
1474        );
1475
1476        signatures.insert(
1477            "getgid",
1478            BuiltinSignature { signatures: vec!["getgid"], documentation: "Returns real group ID" },
1479        );
1480
1481        signatures.insert(
1482            "getegid",
1483            BuiltinSignature {
1484                signatures: vec!["getegid"],
1485                documentation: "Returns effective group ID",
1486            },
1487        );
1488
1489        signatures.insert(
1490            "getgroups",
1491            BuiltinSignature {
1492                signatures: vec!["getgroups"],
1493                documentation: "Returns supplementary group IDs",
1494            },
1495        );
1496
1497        signatures.insert(
1498            "setuid",
1499            BuiltinSignature { signatures: vec!["setuid UID"], documentation: "Sets real user ID" },
1500        );
1501
1502        signatures.insert(
1503            "seteuid",
1504            BuiltinSignature {
1505                signatures: vec!["seteuid UID"],
1506                documentation: "Sets effective user ID",
1507            },
1508        );
1509
1510        signatures.insert(
1511            "setgid",
1512            BuiltinSignature {
1513                signatures: vec!["setgid GID"],
1514                documentation: "Sets real group ID",
1515            },
1516        );
1517
1518        signatures.insert(
1519            "setegid",
1520            BuiltinSignature {
1521                signatures: vec!["setegid GID"],
1522                documentation: "Sets effective group ID",
1523            },
1524        );
1525
1526        signatures.insert(
1527            "setgroups",
1528            BuiltinSignature {
1529                signatures: vec!["setgroups LIST"],
1530                documentation: "Sets supplementary group IDs",
1531            },
1532        );
1533
1534        // ===== Miscellaneous System Functions =====
1535        signatures.insert(
1536            "umask",
1537            BuiltinSignature {
1538                signatures: vec!["umask EXPR", "umask"],
1539                documentation: "Sets file creation mode mask",
1540            },
1541        );
1542
1543        signatures.insert(
1544            "truncate",
1545            BuiltinSignature {
1546                signatures: vec!["truncate FILEHANDLE, LENGTH", "truncate EXPR, LENGTH"],
1547                documentation: "Truncates file to specified length",
1548            },
1549        );
1550
1551        signatures.insert(
1552            "glob",
1553            BuiltinSignature {
1554                signatures: vec!["glob EXPR", "glob"],
1555                documentation: "Returns list of filenames matching pattern",
1556            },
1557        );
1558
1559        signatures.insert(
1560            "setpgrp",
1561            BuiltinSignature {
1562                signatures: vec!["setpgrp PID, PGRP"],
1563                documentation: "Sets process group",
1564            },
1565        );
1566
1567        signatures.insert(
1568            "getpgrp",
1569            BuiltinSignature {
1570                signatures: vec!["getpgrp PID"],
1571                documentation: "Returns process group",
1572            },
1573        );
1574
1575        signatures.insert(
1576            "syscall",
1577            BuiltinSignature {
1578                signatures: vec!["syscall NUMBER, LIST"],
1579                documentation: "Invokes a system call",
1580            },
1581        );
1582
1583        signatures.insert(
1584            "times",
1585            BuiltinSignature {
1586                signatures: vec!["times"],
1587                documentation: "Returns elapsed time for process and children",
1588            },
1589        );
1590
1591        signatures.insert(
1592            "getpriority",
1593            BuiltinSignature {
1594                signatures: vec!["getpriority WHICH, WHO"],
1595                documentation: "Returns current priority for process, process group, or user",
1596            },
1597        );
1598
1599        signatures.insert(
1600            "setpriority",
1601            BuiltinSignature {
1602                signatures: vec!["setpriority WHICH, WHO, PRIORITY"],
1603                documentation: "Sets priority for process, process group, or user",
1604            },
1605        );
1606
1607        // ===== Pack/Unpack =====
1608        signatures.insert(
1609            "pack",
1610            BuiltinSignature {
1611                signatures: vec!["pack TEMPLATE, LIST"],
1612                documentation: "Packs list into binary",
1613            },
1614        );
1615
1616        signatures.insert(
1617            "unpack",
1618            BuiltinSignature {
1619                signatures: vec!["unpack TEMPLATE, EXPR"],
1620                documentation: "Unpacks binary into list",
1621            },
1622        );
1623
1624        // ===== Regular Expression =====
1625        signatures.insert(
1626            "study",
1627            BuiltinSignature {
1628                signatures: vec!["study SCALAR", "study"],
1629                documentation: "Optimizes string for pattern matching",
1630            },
1631        );
1632
1633        signatures.insert(
1634            "pos",
1635            BuiltinSignature {
1636                signatures: vec!["pos SCALAR", "pos"],
1637                documentation: "Returns or sets match position",
1638            },
1639        );
1640
1641        signatures.insert(
1642            "reset",
1643            BuiltinSignature {
1644                signatures: vec!["reset EXPR", "reset"],
1645                documentation:
1646                    "Resets one-character variables and search state. Returns the reset expression. See perldoc -f reset",
1647            },
1648        );
1649
1650        // ===== Format Functions =====
1651        signatures.insert(
1652            "formline",
1653            BuiltinSignature {
1654                signatures: vec!["formline PICTURE, LIST"],
1655                documentation: "Internal function for formats",
1656            },
1657        );
1658
1659        signatures.insert(
1660            "format",
1661            BuiltinSignature {
1662                signatures: vec!["format NAME ="],
1663                documentation: "Declares format",
1664            },
1665        );
1666
1667        // ===== File Test Operators =====
1668        macro_rules! file_test {
1669            ($op:literal) => {
1670                signatures.insert(
1671                    $op,
1672                    BuiltinSignature {
1673                        signatures: vec![concat!($op, " FILE"), $op],
1674                        documentation: "File test operator",
1675                    },
1676                );
1677            };
1678        }
1679
1680        file_test!("-e");
1681        file_test!("-f");
1682        file_test!("-d");
1683        file_test!("-r");
1684        file_test!("-w");
1685        file_test!("-x");
1686        file_test!("-o");
1687        file_test!("-R");
1688        file_test!("-W");
1689        file_test!("-X");
1690        file_test!("-O");
1691        file_test!("-z");
1692        file_test!("-s");
1693        file_test!("-l");
1694        file_test!("-p");
1695        file_test!("-S");
1696        file_test!("-b");
1697        file_test!("-c");
1698        file_test!("-t");
1699        file_test!("-u");
1700        file_test!("-g");
1701        file_test!("-k");
1702        file_test!("-T");
1703        file_test!("-B");
1704        file_test!("-M");
1705        file_test!("-A");
1706        file_test!("-C");
1707
1708        // ===== Miscellaneous =====
1709        signatures.insert(
1710            "dump",
1711            BuiltinSignature {
1712                signatures: vec!["dump LABEL", "dump"],
1713                documentation:
1714                    "Creates an immediate core dump and resumes at an optional label when possible. Does not return normally. See perldoc -f dump",
1715            },
1716        );
1717
1718        signatures.insert(
1719            "dbmopen",
1720            BuiltinSignature {
1721                signatures: vec!["dbmopen HASH, DBNAME, MASK"],
1722                documentation:
1723                    "Opens a DBM file and ties it to a hash. Returns true on success or false on failure. Deprecated; see perldoc -f dbmopen",
1724            },
1725        );
1726
1727        signatures.insert(
1728            "dbmclose",
1729            BuiltinSignature {
1730                signatures: vec!["dbmclose HASH"],
1731                documentation:
1732                    "Closes a DBM file previously opened with dbmopen. Returns true on success or false on failure. Deprecated; see perldoc -f dbmclose",
1733            },
1734        );
1735
1736        signatures.insert(
1737            "vec",
1738            BuiltinSignature {
1739                signatures: vec!["vec EXPR, OFFSET, BITS"],
1740                documentation: "Accesses bit vector",
1741            },
1742        );
1743
1744        signatures.insert(
1745            "prototype",
1746            BuiltinSignature {
1747                signatures: vec!["prototype FUNCTION"],
1748                documentation: "Returns function prototype",
1749            },
1750        );
1751
1752        signatures.insert(
1753            "lock",
1754            BuiltinSignature {
1755                signatures: vec!["lock THING"],
1756                documentation: "Locks shared variable",
1757            },
1758        );
1759
1760        // ===== UTF-8 Encoding Functions =====
1761        // Core utf8:: namespace functions for explicit encoding control. These
1762        // manipulate the SvUTF8 flag on scalars and are documented in perldoc utf8.
1763        signatures.insert(
1764            "utf8::encode",
1765            BuiltinSignature {
1766                signatures: vec!["utf8::encode SCALAR"],
1767                documentation: concat!(
1768                    "Converts the internal representation of SCALAR from Unicode to UTF-8 bytes ",
1769                    "in-place; clears the UTF-8 flag. Returns nothing (void) ",
1770                    "(see perldoc utf8)"
1771                ),
1772            },
1773        );
1774
1775        signatures.insert(
1776            "utf8::decode",
1777            BuiltinSignature {
1778                signatures: vec!["utf8::decode SCALAR"],
1779                documentation: concat!(
1780                    "Attempts to convert SCALAR in-place from UTF-8 bytes to Unicode; sets the ",
1781                    "UTF-8 flag and returns true on success, or leaves SCALAR unchanged and ",
1782                    "returns false on malformed input (see perldoc utf8)"
1783                ),
1784            },
1785        );
1786
1787        signatures.insert(
1788            "utf8::is_utf8",
1789            BuiltinSignature {
1790                signatures: vec!["utf8::is_utf8 SCALAR"],
1791                documentation: concat!(
1792                    "Returns true if the UTF-8 flag is set on SCALAR; an internal ",
1793                    "representation detail, rarely needed in application code (see perldoc utf8)"
1794                ),
1795            },
1796        );
1797
1798        signatures.insert(
1799            "utf8::valid",
1800            BuiltinSignature {
1801                signatures: vec!["utf8::valid SCALAR"],
1802                documentation: concat!(
1803                    "Returns true if the internal state of SCALAR is consistent: either well-formed ",
1804                    "extended UTF-8 with the UTF-8 flag on, or held as raw bytes with the flag off. ",
1805                    "Does not modify SCALAR (see perldoc utf8)"
1806                ),
1807            },
1808        );
1809
1810        signatures.insert(
1811            "utf8::upgrade",
1812            BuiltinSignature {
1813                signatures: vec!["utf8::upgrade SCALAR"],
1814                documentation: concat!(
1815                    "Converts SCALAR in-place to Perl's internal UTF-8 representation preserving ",
1816                    "the abstract character sequence; sets the UTF-8 flag and returns the octet ",
1817                    "count (see perldoc utf8)"
1818                ),
1819            },
1820        );
1821
1822        signatures.insert(
1823            "utf8::downgrade",
1824            BuiltinSignature {
1825                signatures: vec!["utf8::downgrade SCALAR, FAIL_OK", "utf8::downgrade SCALAR"],
1826                documentation: concat!(
1827                    "Attempts to convert SCALAR in-place out of Perl's internal UTF-8 encoding; ",
1828                    "clears the UTF-8 flag. Fails if any character is above U+00FF; croaks ",
1829                    "unless FAIL_OK is true, in which case a false value is returned ",
1830                    "(see perldoc utf8)"
1831                ),
1832            },
1833        );
1834
1835        signatures.insert(
1836            "utf8::native_to_unicode",
1837            BuiltinSignature {
1838                signatures: vec!["utf8::native_to_unicode CODEPOINT"],
1839                documentation: concat!(
1840                    "Returns the Unicode code point corresponding to CODEPOINT given in the ",
1841                    "platform's native character set; a no-op on ASCII platforms, relevant on ",
1842                    "EBCDIC (see perldoc utf8)"
1843                ),
1844            },
1845        );
1846
1847        signatures.insert(
1848            "utf8::unicode_to_native",
1849            BuiltinSignature {
1850                signatures: vec!["utf8::unicode_to_native CODEPOINT"],
1851                documentation: concat!(
1852                    "Returns the native code point corresponding to Unicode CODEPOINT on the ",
1853                    "current platform; a no-op on ASCII platforms, relevant on EBCDIC ",
1854                    "(see perldoc utf8)"
1855                ),
1856            },
1857        );
1858
1859        signatures
1860    })
1861}