[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/sweeprolog 8133821499 5/5: FIXED: exporting predicates in
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/sweeprolog 8133821499 5/5: FIXED: exporting predicates in presence of exported operators |
Date: |
Sat, 19 Nov 2022 11:59:31 -0500 (EST) |
branch: elpa/sweeprolog
commit 81338214994998e125b09abf8dbbae05dad53761
Author: Eshel Yaron <me@eshelyaron.com>
Commit: Eshel Yaron <me@eshelyaron.com>
FIXED: exporting predicates in presence of exported operators
* sweep.pl (sweep_exportable_predicates/2): new predicate.
* sweeprolog.el (sweeprolog--module-term)
(sweeprolog--exportable-predicates)
(sweeprolog-analyze-start-exportable)
(sweeprolog-analyze-fragment-exportable): no longer used, deleted.
(sweeprolog-exportable-predicates): new function.
(sweeprolog-read-exportable-predicate): use it.
(sweeprolog-export-predicate): handle exported operators.
---
sweep.pl | 13 ++++-
sweeprolog-tests.el | 70 ++++++++++++++++++++++++++-
sweeprolog.el | 137 ++++++++++++++++++++++++++++------------------------
3 files changed, 155 insertions(+), 65 deletions(-)
diff --git a/sweep.pl b/sweep.pl
index 646cfbc4fe..ec1be7af96 100644
--- a/sweep.pl
+++ b/sweep.pl
@@ -65,7 +65,8 @@
sweep_beginning_of_last_predicate/2,
sweep_atom_collection/2,
sweep_context_callable/2,
- sweep_predicate_completion_candidates/2
+ sweep_predicate_completion_candidates/2,
+ sweep_exportable_predicates/2
]).
:- use_module(library(pldoc)).
@@ -813,3 +814,13 @@ callable_arg(N) :- integer(N), !.
callable_arg(^) :- !.
callable_arg(//) :- !.
callable_arg(:) :- !.
+
+sweep_exportable_predicates(Path0, Preds) :-
+ atom_string(Path, Path0),
+ findall(D,
+ ( xref_defined(Path, D0, _),
+ \+ xref_exported(Path, D0),
+ pi_head(D1, D0),
+ term_string(D1, D)
+ ),
+ Preds).
diff --git a/sweeprolog-tests.el b/sweeprolog-tests.el
index 5decdae002..9bc0ad8286 100644
--- a/sweeprolog-tests.el
+++ b/sweeprolog-tests.el
@@ -217,7 +217,7 @@ bar(Bar) :- baz(Bar).
"
:- module(sweeprolog_test_export_predicate, []).
-%! foo(+Bar) is det
+%! foo(+Bar) is det.
foo(Bar) :- bar(Bar).
")))
@@ -231,11 +231,77 @@ foo(Bar) :- bar(Bar).
:- module(sweeprolog_test_export_predicate, [foo/1 % +Bar
]).
-%! foo(+Bar) is det
+%! foo(+Bar) is det.
foo(Bar) :- bar(Bar).
"))))
+(ert-deftest export-predicate-with-op ()
+ "Test exporting a predicate in presence of an exported operator."
+ (let ((temp (make-temp-file "sweeprolog-test"
+ nil
+ ".pl"
+ "
+:- module(tester,
+ [ instantiate_test_template/4, % +In,+Replacement,-Dict,-Map
+ op(200, fy, @) % @name
+ ]).
+
+%! foo(+Bar) is det.
+
+foo(Bar).
+")))
+ (find-file-literally temp)
+ (sweeprolog-mode)
+ (goto-char (point-max))
+ (backward-word)
+ (call-interactively #'sweeprolog-export-predicate)
+ (should (equal (buffer-string)
+ "
+:- module(tester,
+ [ instantiate_test_template/4, % +In,+Replacement,-Dict,-Map
+ foo/1, % +Bar
+ op(200, fy, @) % @name
+ ]).
+
+%! foo(+Bar) is det.
+
+foo(Bar).
+"
+ ))))
+
+(ert-deftest export-predicate-with-only-op ()
+ "Test exporting a predicate in presence of only exported operators."
+ (let ((temp (make-temp-file "sweeprolog-test"
+ nil
+ ".pl"
+ "
+:- module(tester,
+ [ op(200, fy, @) % @name
+ ]).
+
+%! foo(+Bar) is det.
+
+foo(Bar).
+")))
+ (find-file-literally temp)
+ (sweeprolog-mode)
+ (goto-char (point-max))
+ (backward-word)
+ (call-interactively #'sweeprolog-export-predicate)
+ (should (equal (buffer-string)
+ "
+:- module(tester,
+ [ foo/1, % +Bar
+ op(200, fy, @) % @name
+ ]).
+
+%! foo(+Bar) is det.
+
+foo(Bar).
+"
+ ))))
+
(ert-deftest identifier-at-point ()
"Test recognizing predicate invocations."
(let ((temp (make-temp-file "sweeprolog-test"
diff --git a/sweeprolog.el b/sweeprolog.el
index b514c5be74..74af0879cd 100644
--- a/sweeprolog.el
+++ b/sweeprolog.el
@@ -438,8 +438,6 @@ buffer where the new predicate defintion should be
inserted."
;;;; Local variables
-(defvar-local sweeprolog--module-term nil)
-
(defvar-local sweeprolog--diagnostics nil)
(defvar-local sweeprolog--diagnostics-report-fn nil)
@@ -448,8 +446,6 @@ buffer where the new predicate defintion should be
inserted."
(defvar-local sweeprolog--diagnostics-changes-end nil)
-(defvar-local sweeprolog--exportable-predicates nil)
-
(defvar-local sweeprolog--timer nil)
(defvar-local sweeprolog--analyze-buffer-duration 0.2)
@@ -2009,21 +2005,6 @@ resulting list even when found in the current clause."
:region (cons beg end))
(setq sweeprolog--diagnostics-report-fn nil)))
-(defun sweeprolog-analyze-start-exportable (&rest _)
- (setq sweeprolog--exportable-predicates nil
- sweeprolog--module-term nil))
-
-(defun sweeprolog-analyze-fragment-exportable (beg end arg)
- (pcase arg
- (`("head" ,(rx (or "dynamic "
- "unreferenced"
- "local("))
- ,f ,a)
- (add-to-list 'sweeprolog--exportable-predicates
- (concat f "/" (number-to-string a))))
- (`("goal_term" "built_in" "module" 2)
- (setq sweeprolog--module-term (cons beg end)))))
-
(defun sweeprolog-analyze-fragment-variable (beg end arg)
(pcase arg
((or "var"
@@ -3144,10 +3125,16 @@ predicate definition at or directly above POINT."
(sweeprolog--query-once "sweep" "sweep_local_predicate_export_comment"
(list (buffer-file-name) fun ari)))
+(defun sweeprolog-exportable-predicates ()
+ "Return a list of exportable predicates from the current buffer."
+ (sweeprolog-xref-buffer)
+ (sweeprolog--query-once "sweep" "sweep_exportable_predicates"
+ (buffer-file-name)))
+
(defun sweeprolog-read-exportable-predicate ()
"Read a predicate name that can be exported in the current buffer."
(completing-read sweeprolog-read-exportable-predicate-prompt
- sweeprolog--exportable-predicates))
+ (sweeprolog-exportable-predicates)))
(defun sweeprolog-export-predicate (pred &optional comm)
"Add PRED to the export list of the current module.
@@ -3169,48 +3156,74 @@ non-exported predicates defined in the current buffer."
(sweeprolog-read-exportable-predicate)
(read-string "Export comment: ")))
sweeprolog-mode)
- (add-hook 'sweeprolog-analyze-region-start-hook
- #'sweeprolog-analyze-start-exportable nil t)
- (add-hook 'sweeprolog-analyze-region-fragment-hook
- #'sweeprolog-analyze-fragment-exportable nil t)
- (sweeprolog-analyze-buffer t)
- (remove-hook 'sweeprolog-analyze-region-fragment-hook
- #'sweeprolog-analyze-fragment-exportable t)
- (remove-hook 'sweeprolog-analyze-region-start-hook
- #'sweeprolog-analyze-start-exportable t)
- (unless (member pred sweeprolog--exportable-predicates)
- (user-error "Cannot add %s to export list" pred))
- (if-let ((mbeg (car sweeprolog--module-term))
- (mend (cdr sweeprolog--module-term)))
- (save-excursion
- (goto-char mend)
- (let ((pos (- (point-max) (point))))
- (unless (search-backward "]" (car sweeprolog--module-term) t)
- (user-error "Cannot find export list"))
- (combine-after-change-calls
- (pcase (sweeprolog-last-token-boundaries)
- (`(open ,_ ,_)
- (insert pred)
- (when (and comm (not (string-empty-p comm)))
- (insert " % " comm))
- (insert "\n")
- (indent-region mbeg (1+ (point))))
- (`(symbol ,_ ,oend)
- (let ((point (point)))
- (goto-char oend)
- (insert ",")
- (goto-char (1+ point))
- (insert "\n")
- (backward-char)
- (insert pred)
- (when (and comm (not (string-empty-p comm)))
- (insert " % " comm))
- (indent-region mbeg (- (point-max) pos))
- (align-regexp mbeg (- (point-max) pos) (rx (group
(zero-or-more blank)) "%"))))
- (_ (user-error "Unexpected token while looking for export
list")))))
- (sweeprolog-analyze-buffer t)
- (message "Exported %s" pred))
- (user-error "Buffer is not a module")))
+ (save-restriction
+ (widen)
+ (save-excursion
+ (goto-char (point-min))
+ (unless (or (sweeprolog-at-beginning-of-top-term-p)
+ (sweeprolog-beginning-of-next-top-term))
+ (user-error "No module declaration found"))
+ (let* ((indent-tabs-mode nil)
+ (target-position nil)
+ (module-term-beg nil)
+ (module-term-end nil)
+ (exported-operator nil)
+ (func (lambda (beg end arg)
+ (pcase arg
+ (`("goal_term" "built_in" "module" 2)
+ (setq module-term-beg beg
+ module-term-end end))
+ ((or "list"
+ "empty_list")
+ (when (and (not target-position)
+ (< module-term-beg beg)
+ (< end module-term-end))
+ (setq target-position (1- end))))
+ ("exported_operator"
+ (unless exported-operator
+ (setq exported-operator t
+ target-position beg)))))))
+ (sweeprolog-analyze-term-at-point func)
+ (unless (member pred (sweeprolog-exportable-predicates))
+ (user-error "Cannot add %s to export list" pred))
+ (if target-position
+ (save-excursion
+ (goto-char target-position)
+ (let ((pos (- (point-max) (line-end-position))))
+ (combine-after-change-calls
+ (if exported-operator
+ (progn
+ (insert pred ",\n")
+ (backward-char)
+ (when (and comm (not (string-empty-p comm)))
+ (insert " % " comm))
+ (indent-region module-term-beg (- (point-max) pos))
+ (align-regexp module-term-beg (- (point-max) pos)
+ (rx (group (zero-or-more blank)) "%")))
+ (pcase (sweeprolog-last-token-boundaries)
+ (`(open ,_ ,_)
+ (insert pred)
+ (when (and comm (not (string-empty-p comm)))
+ (insert " % " comm))
+ (insert "\n")
+ (indent-region module-term-beg (1+ (point))))
+ (`(symbol ,_ ,oend)
+ (let ((point (point)))
+ (goto-char oend)
+ (insert ",")
+ (goto-char (1+ point))
+ (insert "\n")
+ (backward-char)
+ (insert pred)
+ (when (and comm (not (string-empty-p comm)))
+ (insert " % " comm))
+ (indent-region module-term-beg (- (point-max) pos))
+ (align-regexp module-term-beg (- (point-max) pos)
+ (rx (group (zero-or-more blank)) "%"))))
+ (tok (user-error "Unexpected token %s while looking for
export list" tok))))))
+ (sweeprolog-analyze-buffer t)
+ (message "Exported %s" pred))
+ (user-error "No export list found"))))))
(defun sweeprolog-align-spaces (&optional _)
"Adjust in-line whitespace between the previous next Prolog tokens.