Replace virtual-directory with more general virtual-fs implementation

WIP-incremental-parsing
Hugo Thunnissen 2 years ago
parent 153ff71fcf
commit ef9a7336cf

@ -24,73 +24,23 @@
;;; Code:
(require 'cl-lib)
(require 'phpinspect-project)
(require 'phpinspect-fs)
(cl-defstruct (phpinspect-autoloader
(:constructor phpinspect-make-autoloader))
(types (make-hash-table :test 'eq)
(project nil
:type phpinspect--project
:documentation "The project that this autoloader can find files for")
(own-types (make-hash-table :test 'eq :size 10000 :rehash-size 10000)
:type hash-table
:documentation "The internal types that can be
autoloaded through this autoloader")
(types (make-hash-table :test 'eq :size 10000 :rehash-size 10000)
:type hash-table
:documentation
"The types that can be autoloaded through this autoloader.")
(strategies nil
:type list
:documentation
"The strategies that this autoloader can employ for its purpose."))
(cl-defstruct (phpinspect-directory
(:constructor phpinspect-make-directory))
(location nil
:type string
:documentation
"The filepath to the directory"))
(cl-defstruct (phpinspect-virtual-directory
(:constructor phpinspect-make-virtual-directory))
(location nil
:type string
:documentation
"The filepath to the directory")
(files (make-hash-table :test 'equal)
:type hash-table
:documentation
"The files in the virtual directory"))
(cl-defgeneric phpinspect-directory-list-files (directory)
"List all PHP files in DIRECTORY")
(cl-defmethod phpinspect-directory-list-files ((dir phpinspect-directory))
"List all PHP files in DIR."
(directory-files-recursively (phpinspect-directory-location dir)
".*.php$"
t ;; Ignore directories that cannot be read
t ;; follow symlinks
))
(cl-defmethod phpinspect-directory-list-files ((dir phpinspect-virtual-directory))
"List all virtual files that DIR contains."
(let ((files))
(maphash (lambda (file _)
(push file files))
(phpinspect-virtual-directory-files dir))
files))
(cl-defgeneric phpinspect-directory-list-files (directory)
"List all PHP files in DIRECTORY")
(cl-defmethod phpinspect-directory-get-location ((dir phpinspect-directory))
"Get location of PHP dir."
(phpinspect-directory-location dir))
(cl-defmethod phpinspect-directory-get-location ((dir phpinspect-virtual-directory))
"List all virtual files that DIR contains."
(phpinspect-virtual-directory-location dir))
(cl-defmethod phpinspect-directory-insert-file-contents ((dir phpinspect-directory)
(file string))
(insert-file-contents file))
(cl-defmethod phpinspect-directory-insert-file-contents ((dir phpinspect-virtual-directory)
(file string))
(insert (gethash file (phpinspect-virtual-directory-files dir))))
"The external types that can be autoloaded through this autoloader."))
(cl-defstruct (phpinspect-psr0
(:constructor phpinspect-make-psr0-generated))
@ -127,25 +77,25 @@
(phpinspect-intern-name
(concat "\\"
(or prefix "")
(replace-regexp-in-string "/"
"\\\\"
(string-remove-suffix
".php"
(string-remove-prefix
(phpinspect-directory-get-location dir)
filename))))))
(replace-regexp-in-string
"/" "\\\\"
(string-remove-suffix
".php"
(string-remove-prefix dir filename))))))
(cl-defmethod phpinspect-al-strategy-fill-typehash ((strategy phpinspect-psr0)
typehash)
fs
typehash)
(dolist (dir (phpinspect-psr0-directories strategy))
(dolist (file (phpinspect-directory-list-files dir))
(dolist (file (phpinspect-fs-directory-files-recursively fs dir "\\.php$"))
(puthash (phpinspect-filename-to-typename dir file) file typehash))))
(cl-defmethod phpinspect-al-strategy-fill-typehash ((strategy phpinspect-psr4)
fs
typehash)
(let ((prefix (phpinspect-psr4-prefix strategy)))
(dolist (dir (phpinspect-psr4-directories strategy))
(dolist (file (phpinspect-directory-list-files dir))
(dolist (file (phpinspect-fs-directory-files-recursively fs dir "\\.php$"))
(puthash (phpinspect-filename-to-typename dir file prefix) file typehash)))))
(provide 'phpinspect-autoload)

@ -0,0 +1,86 @@
;;; phpinspect-fs.el --- PHP parsing and completion package -*- lexical-binding: t; -*-
;; Copyright (C) 2021 Free Software Foundation, Inc
;; Author: Hugo Thunnissen <devel@hugot.nl>
;; Keywords: php, languages, tools, convenience
;; Version: 0
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
(cl-defstruct (phpinspect-fs (:constructor phpinspect-make-fs)))
(cl-defstruct (phpinspect-virtual-fs (:constructor phpinspect-make-virtual-fs))
(files (make-hash-table :test 'equal)
:type hash-table
:documentation
"The files in the virtual filesystem"))
(cl-defgeneric phpinspect-fs-file-exists-p (fs file))
(cl-defgeneric phpinspect-fs-insert-file-contents (fs file))
(cl-defgeneric phpinspect-fs-directory-files (fs directory match))
(cl-defgeneric phpinspect-fs-directory-files-recursively (fs directory match))
(cl-defmethod phpinspect-fs-file-exists-p ((fs phpinspect-fs) file)
(file-exists-p file))
(cl-defmethod phpinspect-fs-file-exists-p ((fs phpinspect-virtual-fs) file)
(and (gethash file (phpinspect-virtual-fs-files fs)) t))
(cl-defmethod phpinspect-fs-insert-file-contents ((fs phpinspect-fs) file)
(insert-file-contents-literally file))
(cl-defmethod phpinspect-fs-insert-file-contents ((fs phpinspect-virtual-fs) file)
(insert (or (gethash file (phpinspect-virtual-fs-files fs)) "")))
(cl-defmethod phpinspect-fs-directory-files ((fs phpinspect-fs) directory &optional match)
(directory-files directory t match t))
(cl-defmethod phpinspect-fs-directory-files ((fs phpinspect-virtual-fs) directory &optional match)
(setq directory (replace-regexp-in-string "[/]+" "/" (concat directory "/")))
(let ((files))
(maphash
(lambda (file _ignored)
(let ((basename (string-remove-prefix directory file)))
(when (and (string-prefix-p directory file)
(string-match-p "^[^/]*$" basename)
(if match (string-match-p match basename) t))
(push file files))))
(phpinspect-virtual-fs-files fs))
files))
(cl-defmethod phpinspect-fs-directory-files-recursively ((fs phpinspect-fs) directory &optional match)
(directory-files-recursively directory
match
t ;; Ignore directories that cannot be read
t ;; follow symlinks
))
(cl-defmethod phpinspect-fs-directory-files-recursively ((fs phpinspect-virtual-fs) directory &optional match)
(setq directory (replace-regexp-in-string "[/]+" "/" (concat directory "/")))
(let ((files))
(maphash
(lambda (file _ignored)
(when (and (string-prefix-p directory file)
(if match (string-match-p match file) t))
(push file files)))
(phpinspect-virtual-fs-files fs))
files))
(provide 'phpinspect-fs)
;;; phpinspect-fs.el ends here

@ -499,6 +499,7 @@ class Thing
(load-file (concat phpinspect-test-directory "/test-worker.el"))
(load-file (concat phpinspect-test-directory "/test-autoload.el"))
(load-file (concat phpinspect-test-directory "/test-fs.el"))
(provide 'phpinspect-test)
;;; phpinspect-test.el ends here

@ -25,35 +25,36 @@
(require 'ert)
(require 'phpinspect-fs)
(require 'phpinspect-autoload)
(ert-deftest phpinspect-psr0-fill-typehash ()
(let* ((directory1 (phpinspect-make-virtual-directory
:location "/home/user/projects/app/src/"))
(directory2 (phpinspect-make-virtual-directory
:location "/home/user/projects/app/lib/"))
(let* ((fs (phpinspect-make-virtual-fs))
(typehash (make-hash-table :size 10 :test 'eq))
(autoload
(phpinspect-make-psr0-generated :prefix "App\\")))
(puthash "/home/user/projects/app/src/App/Services/SuperService.php"
""
(phpinspect-virtual-directory-files directory1))
(phpinspect-virtual-fs-files fs))
(puthash "/home/user/projects/app/src/Kernel.php"
""
(phpinspect-virtual-directory-files directory1))
(phpinspect-virtual-fs-files fs))
(puthash "/home/user/projects/app/src/App/Controller/Banana.php"
""
(phpinspect-virtual-directory-files directory1))
(phpinspect-virtual-fs-files fs))
(puthash "/home/user/projects/app/lib/Mailer_Lib.php"
""
(phpinspect-virtual-directory-files directory2))
(phpinspect-virtual-fs-files fs))
(setf (phpinspect-psr0-directories autoload) (list directory1 directory2))
(setf (phpinspect-psr0-directories autoload) (list "/home/user/projects/app/src/"
"/home/user/projects/app/lib/"))
(phpinspect-al-strategy-fill-typehash autoload typehash)
(phpinspect-al-strategy-fill-typehash autoload fs typehash)
(should-not (hash-table-empty-p typehash))
(should (string= "/home/user/projects/app/src/App/Services/SuperService.php"
(gethash (phpinspect-intern-name "\\App\\Services\\SuperService")
@ -70,32 +71,33 @@
typehash)))))
(ert-deftest phpinspect-psr4-fill-typehash ()
(let* ((directory1 (phpinspect-make-virtual-directory
:location "/home/user/projects/app/src/"))
(directory2 (phpinspect-make-virtual-directory
:location "/home/user/projects/app/lib/"))
(let* ((fs (phpinspect-make-virtual-fs))
(typehash (make-hash-table :size 10 :test 'eq))
(autoload
(phpinspect-make-psr4-generated :prefix "App\\")))
(puthash "/home/user/projects/app/src/Services/SuperService.php"
""
(phpinspect-virtual-directory-files directory1))
(phpinspect-virtual-fs-files fs))
(puthash "/home/user/projects/app/src/Kernel.php"
""
(phpinspect-virtual-directory-files directory1))
(phpinspect-virtual-fs-files fs))
(puthash "/home/user/projects/app/src/Controller/Banana.php"
""
(phpinspect-virtual-directory-files directory1))
(phpinspect-virtual-fs-files fs))
(puthash "/home/user/projects/app/lib/Mailer_Lib.php"
""
(phpinspect-virtual-directory-files directory2))
(phpinspect-virtual-fs-files fs))
(setf (phpinspect-psr4-directories autoload) (list "/home/user/projects/app/src/"
"/home/user/projects/app/lib/"))
(setf (phpinspect-psr4-directories autoload) (list directory1 directory2))
(phpinspect-al-strategy-fill-typehash autoload fs typehash)
(phpinspect-al-strategy-fill-typehash autoload typehash)
(should-not (hash-table-empty-p typehash))
(should (string= "/home/user/projects/app/src/Services/SuperService.php"
(gethash (phpinspect-intern-name "\\App\\Services\\SuperService")

@ -0,0 +1,88 @@
;;; test-autoload.el --- Unit tests for phpinspect.el -*- lexical-binding: t; -*-
;; Copyright (C) 2021 Free Software Foundation, Inc.
;; Author: Hugo Thunnissen <devel@hugot.nl>
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;;
;;; Code:
(require 'phpinspect-fs)
(ert-deftest phpinspect-virtual-fs-file-exists-p ()
(let ((fs (phpinspect-make-virtual-fs)))
(puthash "/test/test.txt" "contents" (phpinspect-virtual-fs-files fs))
(should (phpinspect-fs-file-exists-p fs "/test/test.txt"))))
(ert-deftest phpinspect-virtual-fs-insert-file-contents ()
(let ((fs (phpinspect-make-virtual-fs)))
(puthash "/test/test.txt" "contents" (phpinspect-virtual-fs-files fs))
(with-temp-buffer
(phpinspect-fs-insert-file-contents fs "/test/test.txt")
(should (string= "contents" (buffer-string))))
(with-temp-buffer
(phpinspect-fs-insert-file-contents fs "/test/nonexistant")
(should (string= "" (buffer-string))))))
(ert-deftest phpinspect-virtual-fs-directory-files-and-recursively ()
(let ((fs (phpinspect-make-virtual-fs)))
(puthash "/test/test.txt" "contents" (phpinspect-virtual-fs-files fs))
(puthash "/a/b/c/dee.match" "contents" (phpinspect-virtual-fs-files fs))
(puthash "/a/b/c/cee.match" "contents" (phpinspect-virtual-fs-files fs))
(puthash "/a/b/c/aaa.match" "contents" (phpinspect-virtual-fs-files fs))
(puthash "/a/b/c/nope.nomatch" "contents" (phpinspect-virtual-fs-files fs))
(puthash "/a/b/d/jee.match" "contents" (phpinspect-virtual-fs-files fs))
(let ((files (phpinspect-fs-directory-files fs "/test/")))
(should (equal '("/test/test.txt") files)))
(let ((files (phpinspect-fs-directory-files fs "/a/b/c")))
(should (member "/a/b/c/dee.match" files))
(should (member "/a/b/c/cee.match" files))
(should (member "/a/b/c/aaa.match" files))
(should (member "/a/b/c/nope.nomatch" files)))
(let ((files (phpinspect-fs-directory-files fs "/a/b/c" "\\.match$")))
(should (member "/a/b/c/dee.match" files))
(should (member "/a/b/c/cee.match" files))
(should (member "/a/b/c/aaa.match" files))
(should (not (member "/a/b/c/nope.nomatch" files))))
(let ((files (phpinspect-fs-directory-files-recursively fs "/a/b" "\\.match$")))
(should (member "/a/b/c/dee.match" files))
(should (member "/a/b/c/cee.match" files))
(should (member "/a/b/c/aaa.match" files))
(should (not (member "/a/b/c/nope.nomatch" files))))
(let ((files (phpinspect-fs-directory-files-recursively fs "/a/b")))
(should (member "/a/b/c/dee.match" files))
(should (member "/a/b/c/cee.match" files))
(should (member "/a/b/c/aaa.match" files))
(should (member "/a/b/c/nope.nomatch" files))
(should (member "/a/b/d/jee.match" files)))
(let ((files (phpinspect-fs-directory-files-recursively fs "/a/b" "\\.match$")))
(should (member "/a/b/c/dee.match" files))
(should (member "/a/b/c/cee.match" files))
(should (member "/a/b/c/aaa.match" files))
(should (not (member "/a/b/c/nope.nomatch" files)))
(should (member "/a/b/d/jee.match" files)))))
Loading…
Cancel
Save