diff --git a/verilog-ext-tags.el b/verilog-ext-tags.el index c7edb72..e387fb2 100644 --- a/verilog-ext-tags.el +++ b/verilog-ext-tags.el @@ -236,6 +236,71 @@ Meant to be used for `xref' backend." (string-trim (buffer-substring-no-properties (line-beginning-position) (line-end-position)))) +;;; Tree-sitter +(defconst verilog-ext-tags-definitions-tree-sitter-re + (regexp-opt + '("module_declaration" + "interface_declaration" + "program_declaration" + "package_declaration" + "class_declaration" + "function_declaration" + "task_declaration" + "class_constructor_declaration" + "local_parameter_declaration" + "data_declaration" + ;; INFO: These two below are only included add items to the defs table for capf + "module_instantiation" + "interface_instantiation" + ))) + +(defconst verilog-ext-tags-definitions-tree-sitter-elements-with-items-re + (regexp-opt + '("module_declaration" + "interface_declaration" + "program_declaration" + "package_declaration" + "class_declaration" + ))) + +;; TODO: Instead of traversing it sequentially, do similarly to how it's done for imenu with the sparse tree +;; and use the parent argument accordingly. This way should be much easier and probably more efficient. +(defun verilog-ext-tags-table-push-definitions-tree-sitter (table &optional file) + "" + (let ((nodes (verilog-ts-nodes-current-buffer verilog-ext-tags-definitions-tree-sitter-re))) + (dolist (node nodes) + (goto-char (treesit-node-start node)) + (verilog-ext-tags-table-push-tag table + ;; TODO: Might not work for some cases: e.g: @ test/files/common/uvm_component.svh:1498 + ;; TODO: Doesn't work either for external defined methods, fetches the class_qualifier instead of the + ;; e.g function void uvm_component::do_end_tr (uvm_transaction tr, -> fetches uvm_component instead of do_end_tr + (verilog-ts--node-identifier-name node) + (treesit-node-type node) + (verilog-ext-tags-desc) + file + ;; TODO: This last argument is the parent. It is used in the builtin recursive function + ;; for dot completion to populate the :items property, with elements of modules and class items/methods + (verilog-ts--node-identifier-name (verilog-ts--node-has-parent-recursive "\\(\\(class\\|package\\)_declaration\\|\\(module\\|interface\\)_")) + (treesit-node-text (treesit-node-parent node) :no-prop) + )))) + +(defun verilog-ext-tags-table-push-references-tree-sitter (table &optional file) + "" + (let ((nodes (verilog-ts-nodes-current-buffer "simple_identifier")) + tag type desc data) + (dolist (node nodes) + (goto-char (treesit-node-start node)) + + (verilog-ext-tags-table-push-tag table + (treesit-node-text node :no-prop) + nil + (verilog-ext-tags-desc) + file))) + ;; TODO: Filter references that already exist as definitions! + ;; Same as in `verilog-ext-tags-get-references' + ) + + (provide 'verilog-ext-tags) ;;; verilog-ext-tags.el ends here diff --git a/verilog-ext-workspace.el b/verilog-ext-workspace.el index 7b6484f..78eb663 100644 --- a/verilog-ext-workspace.el +++ b/verilog-ext-workspace.el @@ -69,6 +69,12 @@ If set to nil default to search for current project files." :group 'verilog-ext-workspace :type 'string) +(defcustom verilog-ext-workspace-tags-backend 'builtin + "Verilog-ext tags extraction backend." + :type '(choice (const :tag "Tree-sitter" tree-sitter) + (const :tag "Built-in" builtin)) + :group 'verilog-ext) + (defun verilog-ext-workspace-root () "Return directory of current workspace root." @@ -260,16 +266,24 @@ With current-prefix or VERBOSE, dump output log." (append-to-file (concat msg "\n") nil log-file)) (message "%s" msg) (insert-file-contents file) - (verilog-mode) - (cond (;; Top-block based-file (module/interface/package/program) - (save-excursion (verilog-re-search-forward verilog-ext-top-re nil :no-error)) - (verilog-ext-tags-table-push-definitions 'top-items table file)) - ;; No top-blocks class-based file - ((save-excursion (verilog-ext-find-class-fwd)) - (verilog-ext-tags-table-push-definitions 'classes table file)) - ;; Default, - (t (dolist (defs '(declarations tf structs)) - (verilog-ext-tags-table-push-definitions defs table file)))) + (cond (;; Tree-sitter + (eq verilog-ext-workspace-tags-backend 'tree-sitter) + (verilog-ts-mode) + (verilog-ext-tags-table-push-definitions-tree-sitter table file)) + (;; Builtin + (eq verilog-ext-workspace-tags-backend 'builtin) + (verilog-mode) + (cond (;; Top-block based-file (module/interface/package/program) + (save-excursion (verilog-re-search-forward verilog-ext-top-re nil :no-error)) + (verilog-ext-tags-table-push-definitions 'top-items table file)) + ;; No top-blocks class-based file + ((save-excursion (verilog-ext-find-class-fwd)) + (verilog-ext-tags-table-push-definitions 'classes table file)) + ;; Default, + (t (dolist (defs '(declarations tf structs)) + (verilog-ext-tags-table-push-definitions defs table file))))) + (t ; Fallback error + (error "Wrong backend for `verilog-ext-workspace-tags-backend'"))) (setq num-files-processed (1+ num-files-processed)))) (setq verilog-ext-workspace-tags-defs-table table) (setq verilog-ext-workspace-cache-tags-defs table) ; Update cache @@ -286,8 +300,16 @@ With current-prefix or VERBOSE, dump output log." (append-to-file (concat msg "\n") nil log-file)) (message "%s" msg) (insert-file-contents file) - (verilog-mode) - (verilog-ext-tags-table-push-references table verilog-ext-workspace-tags-defs-table file) + (cond (;; Tree-sitter + (eq verilog-ext-workspace-tags-backend 'tree-sitter) + (verilog-ts-mode) + (verilog-ext-tags-table-push-references-tree-sitter table file)) + (;; Builtin + (eq verilog-ext-workspace-tags-backend 'builtin) + (verilog-mode) + (verilog-ext-tags-table-push-references table verilog-ext-workspace-tags-defs-table file)) + (t + (error "Wrong backend for `verilog-ext-workspace-tags-backend'"))) (setq verilog-ext-workspace-tags-refs-table table)) (setq num-files-processed (1+ num-files-processed))) (setq verilog-ext-workspace-cache-tags-refs table) ; Update cache @@ -304,6 +326,7 @@ With current-prefix or VERBOSE, dump output log." `(lambda () ,(async-inject-variables verilog-ext-async-inject-variables-re) (require 'verilog-ext) + (require 'verilog-ts-mode) (verilog-ext-workspace-get-tags ,verbose)) (lambda (result) (message "Finished collection tags!")