From 4e612c0c3ee8629e1099509f3ec69bff785f91a2 Mon Sep 17 00:00:00 2001 From: Eshel Yaron Date: Sun, 4 Dec 2022 19:09:30 +0200 Subject: [PATCH] Use built-in file_autoload_directives/3 to update deps * sweep.pl (sweep_file_missing_dependencies/2): new predicate. * sweeprolog.el (sweeprolog-update-dependencies): use it. * sweeprolog-tests.el: add another test case for sweeprolog-update-dependencies. --- sweep.pl | 36 +++++++++++++++- sweeprolog-tests.el | 32 ++++++++++++++ sweeprolog.el | 101 ++++++++++++++++++++++++-------------------- 3 files changed, 122 insertions(+), 47 deletions(-) diff --git a/sweep.pl b/sweep.pl index 360d933..4c0c12e 100644 --- a/sweep.pl +++ b/sweep.pl @@ -69,7 +69,8 @@ sweep_exportable_predicates/2, sweep_interrupt/0, sweep_string_to_atom/2, - sweep_file_path_in_library/2 + sweep_file_path_in_library/2, + sweep_file_missing_dependencies/2 ]). :- use_module(library(pldoc)). @@ -86,6 +87,7 @@ :- use_module(library(http/html_write)). :- use_module(library(prolog_pack)). :- use_module(library(prolog_deps)). +:- use_module(library(dcg/high_order)). :- if(exists_source(library(help))). :- use_module(library(help)). @@ -908,3 +910,35 @@ strip_mode_and_type(S, N) => strip_type(S, N). strip_type(N:_, N) :- !. strip_type(N, N). + +sweep_file_missing_dependencies(File0, Deps) :- + atom_string(File, File0), + file_autoload_directives(File, Directives, [missing(true)]), + phrase(dep_directives(Directives), Deps). + +dep_directives(Directives) --> sequence(dep_directive, Directives). + +dep_directive(:- use_module(Spec)) --> + !, + { absolute_file_name(Spec, Path0, + [ file_type(prolog), + access(read) + ]), + atom_string(Path0, Path) + }, + [[Path, [], "use_module"]]. +dep_directive(:- Directive) --> + { compound_name_arguments(Directive, Kind0, [Spec, ImportList]), + atom_string(Kind0, Kind), + absolute_file_name(Spec, Path0, + [ file_type(prolog), + access(read) + ]), + atom_string(Path0, Path) + }, + sequence(dep_import(Path, Kind), ImportList). + +dep_import(Path, Kind, PI0) --> + { term_string(PI0, PI) + }, + [[Path, PI, Kind]]. diff --git a/sweeprolog-tests.el b/sweeprolog-tests.el index 7124aee..46a4c61 100644 --- a/sweeprolog-tests.el +++ b/sweeprolog-tests.el @@ -691,6 +691,38 @@ foo :- bar. foo :- Body. ")))) +(ert-deftest update-dependencies-no-autoload () + "Tests making adding a use_module/1 directive." + (let ((temp (make-temp-file "sweeprolog-test" + nil + "pl" + " +:- module(foo, [bar/1]). + +/** Foo + +*/ + +bar(X) :- arithmetic_function(X). +" + ))) + (find-file-literally temp) + (sweeprolog-mode) + (call-interactively #'sweeprolog-update-dependencies) + (should (string= (buffer-string) + " +:- module(foo, [bar/1]). + +/** Foo + +*/ + +:- use_module(library(arithmetic), [ arithmetic_function/1 + ]). + +bar(X) :- arithmetic_function(X). +")))) + (ert-deftest append-dependencies () "Tests making implicit autoloads explicit with existing directive." (let ((temp (make-temp-file "sweeprolog-test" diff --git a/sweeprolog.el b/sweeprolog.el index 514dd3a..88fde91 100644 --- a/sweeprolog.el +++ b/sweeprolog.el @@ -4110,7 +4110,6 @@ valid Prolog atom." "Add explicit dependencies for implicitly autoaloaded predicates." (interactive "" sweeprolog-mode) (let ((existing nil) - (missing nil) (current-directive-beg nil) (current-directive-end nil) (current-directive-file nil)) @@ -4137,57 +4136,67 @@ valid Prolog atom." current-directive-end)) (push (cons current-directive-file (copy-marker (1- end) t)) - existing))) - (`("goal" ("autoload" . ,file) ,functor ,arity) - (let ((autoloaded (list file functor arity))) - (unless (member autoloaded missing) - (push autoloaded missing))))))) - (if missing + existing)))))) + (if-let ((missing + (sweeprolog--query-once "sweep" "sweep_file_missing_dependencies" + (buffer-file-name)))) (progn (dolist (autoloaded missing) (let* ((file (nth 0 autoloaded)) - (functor (nth 1 autoloaded)) - (arity (nth 2 autoloaded)) - (pred (concat (sweeprolog-format-string-as-atom functor) - "/" (number-to-string arity)))) - (message "Adding explicit dependency on %s from %s." - pred file) - (if-let ((marker (cdr (assoc-string file existing)))) + (pred (nth 1 autoloaded)) + (kind (nth 2 autoloaded))) + (if (not pred) (save-mark-and-excursion - (goto-char marker) - (pcase (sweeprolog-last-token-boundaries) - (`(open ,_ ,oend) - (goto-char oend) - (insert " " pred "\n")) - (`(symbol ,_ ,oend) - (let ((point (point))) + (goto-char (point-min)) + (sweeprolog-end-of-top-term) + (while (forward-comment 1)) + (insert ":- " kind "(" + (sweeprolog--query-once "sweep" + "sweep_file_path_in_library" + file) + ").\n\n") + (indent-region-line-by-line (save-excursion + (sweeprolog-beginning-of-top-term) + (point)) + (point))) + (message "Adding explicit dependency on %s from %s." + pred file) + (if-let ((marker (cdr (assoc-string file existing)))) + (save-mark-and-excursion + (goto-char marker) + (pcase (sweeprolog-last-token-boundaries) + (`(open ,_ ,oend) (goto-char oend) - (insert ",") - (goto-char (1+ point)) - (insert pred "\n"))) - (tok - (user-error "Unexpected token %s while looking for import list" - tok))) - (indent-region-line-by-line (save-excursion - (sweeprolog-beginning-of-top-term) - (point)) - (save-excursion - (sweeprolog-end-of-top-term) - (point)))) - (save-mark-and-excursion - (goto-char (point-min)) - (sweeprolog-end-of-top-term) - (while (forward-comment 1)) - (insert ":- autoload(" - (sweeprolog--query-once "sweep" - "sweep_file_path_in_library" - file) - ", [ " pred "\n]).\n\n") - (indent-region-line-by-line (save-excursion - (sweeprolog-beginning-of-top-term) + (insert " " pred "\n")) + (`(symbol ,_ ,oend) + (let ((point (point))) + (goto-char oend) + (insert ",") + (goto-char (1+ point)) + (insert pred "\n"))) + (tok + (user-error "Unexpected token %s while looking for import list" + tok))) + (indent-region-line-by-line (save-excursion + (sweeprolog-beginning-of-top-term) + (point)) + (save-excursion + (sweeprolog-end-of-top-term) + (point)))) + (save-mark-and-excursion + (goto-char (point-min)) + (sweeprolog-end-of-top-term) + (while (forward-comment 1)) + (insert ":- " kind "(" + (sweeprolog--query-once "sweep" + "sweep_file_path_in_library" + file) + ", [ " pred "\n]).\n\n") + (indent-region-line-by-line (save-excursion + (sweeprolog-beginning-of-top-term) + (point)) (point)) - (point)) - (push (cons file (copy-marker (- (point) 5) t)) existing))))) + (push (cons file (copy-marker (- (point) 5) t)) existing)))))) (sweeprolog-analyze-buffer t)) (message "No implicit autoloads found.")))) -- 2.39.2