branch: externals/phpinspect
commit ef9a7336cf18f466d2a6629040e55cf957c03443
Author: Hugo Thunnissen <de...@hugot.nl>
Commit: Hugo Thunnissen <de...@hugot.nl>

    Replace virtual-directory with more general virtual-fs implementation
---
 phpinspect-autoload.el  | 94 ++++++++++++-------------------------------------
 phpinspect-fs.el        | 86 ++++++++++++++++++++++++++++++++++++++++++++
 test/phpinspect-test.el |  1 +
 test/test-autoload.el   | 42 +++++++++++-----------
 test/test-fs.el         | 88 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 219 insertions(+), 92 deletions(-)

diff --git a/phpinspect-autoload.el b/phpinspect-autoload.el
index c5721cdc71..98e83d3ae8 100644
--- a/phpinspect-autoload.el
+++ b/phpinspect-autoload.el
@@ -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)
diff --git a/phpinspect-fs.el b/phpinspect-fs.el
new file mode 100644
index 0000000000..e84b155ba8
--- /dev/null
+++ b/phpinspect-fs.el
@@ -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 <de...@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
diff --git a/test/phpinspect-test.el b/test/phpinspect-test.el
index e9fb7efbca..4c4ba1c908 100644
--- a/test/phpinspect-test.el
+++ b/test/phpinspect-test.el
@@ -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
diff --git a/test/test-autoload.el b/test/test-autoload.el
index e38d41d1f8..85df039d13 100644
--- a/test/test-autoload.el
+++ b/test/test-autoload.el
@@ -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")
diff --git a/test/test-fs.el b/test/test-fs.el
new file mode 100644
index 0000000000..c83ebfe24b
--- /dev/null
+++ b/test/test-fs.el
@@ -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 <de...@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)))))

Reply via email to