patch 8.2.0725: Vim9: cannot call a function declared later in Vim9 script
Problem: Vim9: cannot call a function declared later in Vim9 script.
Solution: Make two passes through the script file.
diff --git a/src/scriptfile.c b/src/scriptfile.c
index 155ab14..ba74a8a 100644
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -998,6 +998,8 @@
int error; // TRUE if LF found after CR-LF
#endif
#ifdef FEAT_EVAL
+ garray_T lines_ga; // lines read in previous pass
+ int use_lines_ga; // next line to get from "lines_ga"
linenr_T breakpoint; // next line with breakpoint or zero
char_u *fname; // name of sourced file
int dbg_tick; // debug_tick when breakpoint was set
@@ -1017,6 +1019,24 @@
}
/*
+ * Get the grow array to store script lines in.
+ */
+ garray_T *
+source_get_line_ga(void *cookie)
+{
+ return &((struct source_cookie *)cookie)->lines_ga;
+}
+
+/*
+ * Set the index to start reading from the grow array with script lines.
+ */
+ void
+source_use_line_ga(void *cookie)
+{
+ ((struct source_cookie *)cookie)->use_lines_ga = 0;
+}
+
+/*
* Return the address holding the debug tick for a source cookie.
*/
int *
@@ -1235,6 +1255,9 @@
cookie.finished = FALSE;
#ifdef FEAT_EVAL
+ ga_init2(&cookie.lines_ga, sizeof(char_u *), 200);
+ cookie.use_lines_ga = -1;
+
// Check if this script has a breakpoint.
cookie.breakpoint = dbg_find_breakpoint(TRUE, fname_exp, (linenr_T)0);
cookie.fname = fname_exp;
@@ -1447,6 +1470,9 @@
vim_free(cookie.nextline);
vim_free(firstline);
convert_setup(&cookie.conv, NULL, NULL);
+#ifdef FEAT_EVAL
+ ga_clear_strings(&cookie.lines_ga);
+#endif
if (trigger_source_post)
apply_autocmds(EVENT_SOURCEPOST, fname_exp, fname_exp, FALSE, curbuf);
@@ -1702,6 +1728,31 @@
// one now.
if (sp->finished)
line = NULL;
+#ifdef FEAT_EVAL
+ else if (sp->use_lines_ga >= 0)
+ {
+ // Get a line that was read in ex_vim9script().
+ for (;;)
+ {
+ if (sp->use_lines_ga >= sp->lines_ga.ga_len)
+ {
+ line = NULL;
+ break;
+ }
+ else
+ {
+ line = ((char_u **)(sp->lines_ga.ga_data))[sp->use_lines_ga];
+ ((char_u **)(sp->lines_ga.ga_data))[sp->use_lines_ga] = NULL;
+ ++sp->use_lines_ga;
+ if (line != NULL)
+ break;
+ // Skip NULL lines, they are equivalent to blank lines.
+ ++sp->sourcing_lnum;
+ }
+ }
+ SOURCING_LNUM = sp->sourcing_lnum + 1;
+ }
+#endif
else if (sp->nextline == NULL)
line = get_one_sourceline(sp);
else