branch: externals/phpinspect
commit 84ddaf1dc2ea250cff363a09a240925dc68dc3b3
Author: Hugo Thunnissen <[email protected]>
Commit: Hugo Thunnissen <[email protected]>
Fix all byte compilation warnings and errors (for real this time (probably))
---
benchmarks/parse-file.el | 17 +-
compile.bash | 9 +
phpinspect-autoload.el | 20 +-
phpinspect-bmap.el | 8 +
phpinspect-buffer.el | 3 +-
phpinspect-cache.el | 43 +++-
phpinspect-changeset.el | 14 +-
phpinspect-class-struct.el | 68 +++++++
phpinspect-class.el | 12 +-
phpinspect-edtrack.el | 170 ++++++++--------
phpinspect-eldoc.el | 3 +-
phpinspect-imports.el | 8 +-
phpinspect-index.el | 70 +------
phpinspect-parse-context.el | 21 +-
phpinspect-parser.el | 448 +++++++++++++++++++++--------------------
phpinspect-pipeline.el | 2 +-
phpinspect-project.el | 170 +++++++++-------
phpinspect-resolve.el | 10 +-
phpinspect-resolvecontext.el | 32 +--
phpinspect-suggest.el | 2 +-
phpinspect-toc.el | 3 +-
phpinspect-token-predicates.el | 26 ++-
phpinspect-type.el | 69 +++++++
phpinspect-util.el | 73 +++----
phpinspect-worker.el | 89 +-------
test/phpinspect-test.el | 2 +-
test/test-autoload.el | 22 +-
test/test-class.el | 4 +-
test/test-index.el | 2 +-
test/test-parse-context.el | 2 +-
test/test-parser.el | 4 +-
test/test-resolvecontext.el | 2 +-
32 files changed, 763 insertions(+), 665 deletions(-)
diff --git a/benchmarks/parse-file.el b/benchmarks/parse-file.el
index 604ba2e833..960b601aa4 100644
--- a/benchmarks/parse-file.el
+++ b/benchmarks/parse-file.el
@@ -12,7 +12,7 @@
(insert-file-contents (concat here "/Response.php"))
(message "Incremental parse (warmup):")
- (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t)
+ (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t :bmap
(phpinspect-make-bmap))
(benchmark 1 '(phpinspect-parse-current-buffer)))
(let ((bmap (phpinspect-make-bmap))
@@ -24,13 +24,19 @@
(garbage-collect)
(message "Incremental parse (no edits):")
- (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t
:bmap bmap2 :previous-bmap bmap :edtrack (phpinspect-make-edtrack))
+ (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t
+ :bmap bmap2
+ :previous-bmap bmap
+ :edtrack
(phpinspect-make-edtrack))
(benchmark 1 '(phpinspect-parse-current-buffer)))
(garbage-collect)
(message "Incremental parse repeat (no edits):")
- (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t
:previous-bmap bmap2 :edtrack (phpinspect-make-edtrack))
+ (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t
+ :bmap
(phpinspect-make-bmap)
+ :previous-bmap bmap2
+ :edtrack
(phpinspect-make-edtrack))
(benchmark 1 '(phpinspect-parse-current-buffer)))
(garbage-collect)
@@ -64,7 +70,10 @@
;;(profiler-start 'cpu)
(message "Incremental parse after 2 more edits:")
- (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t
:previous-bmap bmap-after :edtrack edtrack)
+ (phpinspect-with-parse-context (phpinspect-make-pctx :bmap
(phpinspect-make-bmap)
+ :incremental t
+ :previous-bmap
bmap-after
+ :edtrack edtrack)
(benchmark 1 '(phpinspect-parse-current-buffer)))
;; (save-current-buffer
diff --git a/compile.bash b/compile.bash
new file mode 100644
index 0000000000..32ca4cd2cb
--- /dev/null
+++ b/compile.bash
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+for file in ./*.el; do
+ cask emacs -batch -L . --eval '(setq byte-compile-error-on-warn t)' -f
batch-byte-compile "$file" || break
+done
+
+if ! [[ -n 'NO_REMOVE_ELC' ]]; then
+ rm ./*.elc
+fi
diff --git a/phpinspect-autoload.el b/phpinspect-autoload.el
index f0a2ceb6e8..995ec2f903 100644
--- a/phpinspect-autoload.el
+++ b/phpinspect-autoload.el
@@ -24,7 +24,6 @@
;;; Code:
(require 'cl-lib)
-(require 'phpinspect-project)
(require 'phpinspect-fs)
(require 'phpinspect-util)
(require 'phpinspect-pipeline)
@@ -72,9 +71,12 @@
(:constructor phpinspect-make-autoloader))
(refresh-thread nil
:type thread)
- (project nil
- :type phpinspect-project
- :documentation "The project that this autoloader can find files
for")
+ (fs nil
+ :type phpinspect-fs)
+ (file-indexer nil
+ :type function)
+ (project-root-resolver nil
+ :type function)
(own-types (make-hash-table :test 'eq :size 10000 :rehash-size 10000)
:type hash-table
:documentation "The internal types that can be
@@ -160,9 +162,9 @@ bareword typenames."))
(cl-defmethod phpinspect-al-strategy-execute ((strat phpinspect-files))
(phpinspect--log "indexing files list: %s" (phpinspect-files-list strat))
- (let* ((project (phpinspect-autoloader-project (phpinspect-files-autoloader
strat))))
+ (let* ((indexer (phpinspect-autoloader-file-indexer
(phpinspect-files-autoloader strat))))
(phpinspect-pipeline (phpinspect-files-list strat)
- :into (phpinspect-project-add-file-index :with-context project))))
+ :into (funcall :with-context indexer))))
(cl-defmethod phpinspect-autoloader-put-type-bag ((al phpinspect-autoloader)
(type-fqn symbol))
(let* ((type-name (phpinspect-intern-name
@@ -175,7 +177,7 @@ bareword typenames."))
(cl-defmethod phpinspect-iterate-composer-jsons
((al phpinspect-autoloader) file)
- (let* ((fs (phpinspect-project-fs (phpinspect-autoloader-project al)))
+ (let* ((fs (phpinspect-autoloader-fs al))
(project-root (file-name-directory (cdr file)))
json autoload batch)
@@ -254,8 +256,8 @@ bareword typenames."))
(cl-defmethod phpinspect-autoloader-refresh ((autoloader
phpinspect-autoloader) &optional async-callback)
"Refresh autoload definitions by reading composer.json files
from the project and vendor folders."
- (let* ((project-root (phpinspect-project-root (phpinspect-autoloader-project
autoloader)))
- (fs (phpinspect-project-fs (phpinspect-autoloader-project
autoloader))))
+ (let* ((project-root (funcall (phpinspect-autoloader-project-root-resolver
autoloader)))
+ (fs (phpinspect-autoloader-fs autoloader)))
(setf (phpinspect-autoloader-type-name-fqn-bags autoloader)
(make-hash-table :test 'eq :size 3000 :rehash-size 3000))
(setf (phpinspect-autoloader-own-types autoloader)
diff --git a/phpinspect-bmap.el b/phpinspect-bmap.el
index a2ad9ec39c..d38dd9b513 100644
--- a/phpinspect-bmap.el
+++ b/phpinspect-bmap.el
@@ -26,6 +26,7 @@
(require 'phpinspect-splayt)
(require 'phpinspect-meta)
(require 'phpinspect-changeset)
+(require 'phpinspect-parse-context)
(require 'phpinspect-util)
(require 'compat)
(require 'phpinspect-token-predicates)
@@ -217,6 +218,13 @@
(setf (phpinspect-bmap-last-token-start bmap) start)
(push token-meta (phpinspect-bmap-token-stack bmap))))
+(define-inline phpinspect-pctx-register-token (pctx token start end)
+ (inline-letevals (pctx)
+ (inline-quote
+ (phpinspect-bmap-register
+ (phpinspect-pctx-bmap ,pctx) ,start ,end ,token
(phpinspect-pctx-consume-whitespace ,pctx)))))
+
+
(defsubst phpinspect-overlay-p (overlay)
(and (listp overlay)
(eq 'overlay (car overlay))))
diff --git a/phpinspect-buffer.el b/phpinspect-buffer.el
index 67cf60f3f3..fee8228adc 100644
--- a/phpinspect-buffer.el
+++ b/phpinspect-buffer.el
@@ -23,6 +23,7 @@
;;; Code:
+(require 'phpinspect-class)
(require 'phpinspect-parser)
(require 'phpinspect-bmap)
(require 'phpinspect-edtrack)
@@ -77,7 +78,7 @@ linked with."
(let* ((map (phpinspect-make-bmap))
(buffer-map (phpinspect-buffer-map buffer))
(ctx (phpinspect-make-pctx
- :interrupt-predicate (unless no-interrupt
#'input-pending-p)
+ :interrupt-predicate (unless no-interrupt
#'phpinspect--input-pending-p)
:bmap map
:incremental t
:previous-bmap buffer-map
diff --git a/phpinspect-cache.el b/phpinspect-cache.el
index 1b947744f5..9bc2e8ca21 100644
--- a/phpinspect-cache.el
+++ b/phpinspect-cache.el
@@ -65,6 +65,13 @@ currently opened projects."
((cache phpinspect--cache) (project-root string))
(gethash project-root (phpinspect--cache-projects cache)))
+(defun phpinspect-get-or-create-cached-project-class (project-root class-fqn)
+ (when project-root
+ (let ((project (phpinspect--cache-get-project-create
+ (phpinspect--get-or-create-global-cache)
+ project-root)))
+ (phpinspect-project-get-class-create project class-fqn))))
+
(cl-defmethod phpinspect--cache-get-project-create
((cache phpinspect--cache) (project-root string))
"Get a project that is located in PROJECT-ROOT from CACHE.
@@ -78,11 +85,43 @@ then returned."
:root project-root
:worker (phpinspect-make-dynamic-worker))
(phpinspect--cache-projects cache)))
- (let ((autoloader (phpinspect-make-autoloader :project project)))
- (setf (phpinspect-project-autoload project) autoloader)
+ (let ((autoloader (phpinspect-make-autoloader
+ :fs (phpinspect-project-fs project)
+ :file-indexer (phpinspect-project-make-file-indexer
project)
+ :project-root-resolver
(phpinspect-project-make-root-resolver project)))) (setf
(phpinspect-project-autoload project) autoloader)
(phpinspect-autoloader-refresh autoloader)
(phpinspect-project-enqueue-include-dirs project)))
project))
+(defun phpinspect-project-enqueue-include-dirs (project)
+ (interactive (list (phpinspect--cache-get-project-create
+ (phpinspect--get-or-create-global-cache)
+ (phpinspect-current-project-root))))
+ (let ((dirs (alist-get 'include-dirs
+ (alist-get (phpinspect-project-root project)
+ phpinspect-projects
+ nil nil #'string=))))
+ (dolist (dir dirs)
+ (message "enqueueing dir %s" dir)
+ (phpinspect-worker-enqueue
+ (phpinspect-project-worker project)
+ (phpinspect-make-index-dir-task :dir dir :project project)))))
+
+(defun phpinspect-project-add-include-dir (dir)
+ "Configure DIR as an include dir for the current project."
+ (interactive (list (read-directory-name "Include Directory: ")))
+ (custom-set-variables '(phpinspect-projects))
+ (let ((existing
+ (alist-get (phpinspect-current-project-root) phpinspect-projects nil
#'string=)))
+ (if existing
+ (push dir (alist-get 'include-dirs existing))
+ (push `(,(phpinspect-current-project-root) . ((include-dirs . (,dir))))
phpinspect-projects)))
+
+ (customize-save-variable 'phpinspect-projects phpinspect-projects)
+
+ (phpinspect-project-enqueue-include-dirs
(phpinspect--cache-get-project-create
+
(phpinspect--get-or-create-global-cache)
+
(phpinspect-current-project-root))))
+
(provide 'phpinspect-cache)
;;; phpinspect.el ends here
diff --git a/phpinspect-changeset.el b/phpinspect-changeset.el
index 7f19ed2201..406a9ba359 100644
--- a/phpinspect-changeset.el
+++ b/phpinspect-changeset.el
@@ -23,6 +23,9 @@
;;; Code:
+(eval-when-compile
+ (require 'phpinspect-meta))
+
(define-inline phpinspect-make-changeset (meta)
(inline-letevals (meta)
(inline-quote
@@ -48,17 +51,6 @@
(define-inline phpinspect-changeset-meta (set)
(inline-quote (car (nthcdr 5 ,set))))
-(define-inline phpinspect-meta-with-changeset (meta &rest body)
- (declare (indent 1))
- (inline-letevals (meta)
- (push 'progn body)
- (inline-quote
- (progn
- (when phpinspect-parse-context
- (phpinspect-pctx-register-changeset
- phpinspect-parse-context (phpinspect-make-changeset ,meta)))
- ,body))))
-
(define-inline phpinspect-changeset-revert (changeset)
(inline-letevals (changeset)
(inline-quote
diff --git a/phpinspect-class-struct.el b/phpinspect-class-struct.el
new file mode 100644
index 0000000000..9b91aaa0c2
--- /dev/null
+++ b/phpinspect-class-struct.el
@@ -0,0 +1,68 @@
+;;; phpinspect-class-struct.el --- PHP parsing and completion package -*-
lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc
+
+;; Author: Hugo Thunnissen <[email protected]>
+;; 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--class (:constructor
phpinspect--make-class-generated))
+ (project nil
+ :type phpinspect-project
+ :documentaton
+ "The project that this class belongs to")
+ (index nil
+ :type phpinspect--indexed-class
+ :documentation
+ "The index that this class is derived from")
+ (methods (make-hash-table :test 'eq :size 20 :rehash-size 20)
+ :type hash-table
+ :documentation
+ "All methods, including those from extended classes.")
+ (static-methods (make-hash-table :test 'eq :size 20 :rehash-size 20)
+ :type hash-table
+ :documentation
+ "All static methods this class provides,
+ including those from extended classes.")
+ (name nil
+ :type phpinspect--type)
+ (variables nil
+ :type list
+ :documentation
+ "Variables that belong to this class.")
+ (extended-classes nil
+ :type list
+ :documentation
+ "All extended/implemented classes.")
+ (subscriptions (make-hash-table :test #'eq :size 10 :rehash-size 1.5)
+ :type hash-table
+ :documentation
+ "A list of subscription functions that should be
+ called whenever anything about this class is
+ updated")
+ (declaration nil)
+ (initial-index nil
+ :type bool
+ :documentation
+ "A boolean indicating whether or not this class
+ has been indexed yet."))
+
+(provide 'phpinspect-class-struct)
diff --git a/phpinspect-class.el b/phpinspect-class.el
index d5e7221bf3..d40a90282b 100644
--- a/phpinspect-class.el
+++ b/phpinspect-class.el
@@ -26,10 +26,11 @@
(require 'phpinspect-type)
(cl-defstruct (phpinspect--class (:constructor
phpinspect--make-class-generated))
- (project nil
- :type phpinspect-project
- :documentaton
- "The project that this class belongs to")
+ (class-retriever nil
+ :type lambda
+ :documentaton
+ "A function that returns classes for types
+(should accept `phpinspect--type' as argument)")
(index nil
:type phpinspect--indexed-class
:documentation
@@ -76,8 +77,7 @@
#'phpinspect--class-p
(mapcar
(lambda (class-name)
- (phpinspect-project-get-class-create (phpinspect--class-project
class)
- class-name))
+ (funcall (phpinspect--class-class-retriever class) class-name))
extensions)))
(dolist (extended (phpinspect--class-extended-classes class))
diff --git a/phpinspect-edtrack.el b/phpinspect-edtrack.el
index bd065932ca..45baa3acb7 100644
--- a/phpinspect-edtrack.el
+++ b/phpinspect-edtrack.el
@@ -26,6 +26,7 @@
(require 'phpinspect-util)
(eval-when-compile
+ (require 'phpinspect-meta)
(phpinspect--declare-log-group 'edtrack))
(cl-defstruct (phpinspect-edtrack (:constructor phpinspect-make-edtrack))
@@ -40,44 +41,9 @@
:type integer
:documentation "Last registered edit start position"))
-(defsubst phpinspect-edtrack-make-taint-iterator (track)
- (cons (car (phpinspect-edtrack-taint-pool track))
- (cl-copy-list (cdr (phpinspect-edtrack-taint-pool track)))))
-
-(define-inline phpinspect-taint-iterator-current (iter)
- (inline-quote (car ,iter)))
-
-(define-inline phpinspect-taint-iterator-follow (iter pos)
- (inline-letevals (iter pos)
- (inline-quote
- (or (while (and (phpinspect-taint-iterator-current ,iter)
- (> ,pos (phpinspect-taint-end
- (phpinspect-taint-iterator-current ,iter))))
- (setf (phpinspect-taint-iterator-current ,iter) (pop (cdr ,iter))))
- (phpinspect-taint-iterator-current ,iter)))))
-
-(define-inline phpinspect-taint-iterator-token-is-tainted-p (iter meta)
- (inline-letevals (iter meta)
- (inline-quote
- (and (phpinspect-taint-iterator-follow ,iter (phpinspect-meta-start
,meta))
- (phpinspect-taint-overlaps-meta
- (phpinspect-taint-iterator-current ,iter) ,meta)))))
-
-(define-inline phpinspect-taint-iterator-region-is-tainted-p (iter start end)
- (inline-letevals (iter start end)
- (inline-quote
- (and (phpinspect-taint-iterator-follow ,iter ,start)
- (phpinspect-taint-overlaps-region
- (phpinspect-taint-iterator-current ,iter) ,start ,end)))))
-
(defsubst phpinspect-edit-original-end (edit)
(or (caar edit) 0))
-(defsubst phpinspect-edit-end (edit)
- (let ((end (or (caar edit) 0))
- (previous-edit (cdr edit)))
- (+ end (phpinspect-edit-delta previous-edit))))
-
(defsubst phpinspect-edit-delta (edit)
(let ((delta (or (cdar edit) 0))
(previous-edit edit))
@@ -85,6 +51,11 @@
(setq delta (+ delta (cdar previous-edit))))
delta))
+(defsubst phpinspect-edit-end (edit)
+ (let ((end (or (caar edit) 0))
+ (previous-edit (cdr edit)))
+ (+ end (phpinspect-edit-delta previous-edit))))
+
(defsubst phpinspect-edtrack-original-position-at-point (track point)
(let ((edit (phpinspect-edtrack-edits track))
(encroached)
@@ -113,48 +84,14 @@
(- pos encroached)
pos)))
+(define-inline phpinspect-taint-start (taint)
+ (inline-quote (car ,taint)))
-(defsubst phpinspect-edtrack-register-edit (track start end pre-change-length)
- (phpinspect--log
- "Edtrack registered change: [start: %d, end: %d, pre-change-length: %d]"
- start end pre-change-length)
-
- (let ((original-start (phpinspect-edtrack-original-position-at-point track
start)))
- (phpinspect-edtrack-register-taint
- track original-start (+ original-start pre-change-length)))
+(define-inline phpinspect-taint-end (taint)
+ (inline-quote (cdr ,taint)))
- (let ((edit-before (phpinspect-edtrack-edits track)))
- (while (and edit-before (< end (phpinspect-edit-end edit-before)))
- (setq edit-before (cdr edit-before)))
-
- (let ((delta ;; The delta of this edit.
- (- (- end start) pre-change-length))
- new-edit)
- (setq new-edit (cons
- ;; The end location of the edited region, before being
- ;; edited, with the delta edits that happened at
preceding
- ;; points in the buffer subtratted. This corresponds
with
- ;; the original position of the region end before the
- ;; buffer was ever edited.
- (phpinspect-edtrack-original-position-at-point
- track (+ start pre-change-length))
- delta))
- (if edit-before
- (progn
- (setcdr edit-before (cons (car edit-before) (cdr edit-before)))
- (setcar edit-before new-edit))
- (if (phpinspect-edtrack-edits track)
- (push new-edit (cdr (last (phpinspect-edtrack-edits track))))
- (push new-edit (phpinspect-edtrack-edits track)))))))
-
-(defsubst phpinspect-taint-start (taint)
- (car taint))
-
-(defsubst phpinspect-taint-end (taint)
- (cdr taint))
-
-(defsubst phpinspect-make-taint (start end)
- (cons start end))
+(define-inline phpinspect-make-taint (start end)
+ (inline-quote (cons ,start ,end)))
(defsubst phpinspect-taint-overlaps-point (taint point)
(and (> (phpinspect-taint-end taint) point)
@@ -180,15 +117,6 @@
(phpinspect-meta-overlaps-point meta (phpinspect-taint-start taint))
(phpinspect-meta-overlaps-point meta (phpinspect-taint-end taint))))
-(defsubst phpinspect-edtrack-clear-taint-pool (track)
- (setf (phpinspect-edtrack-taint-pool track) nil))
-
-(defsubst phpinspect-edtrack-clear (track)
- (setf (phpinspect-edtrack-edits track) nil)
- (setf (phpinspect-edtrack-last-edit track) nil)
- (setf (phpinspect-edtrack-last-edit-start track) -1)
- (phpinspect-edtrack-clear-taint-pool track))
-
(defsubst phpinspect-edtrack-register-taint (track start end)
(let ((pool (phpinspect-edtrack-taint-pool track))
(idx 0)
@@ -229,5 +157,79 @@
(t
(push taint (phpinspect-edtrack-taint-pool track))))))
+(defsubst phpinspect-edtrack-register-edit (track start end pre-change-length)
+ (phpinspect--log
+ "Edtrack registered change: [start: %d, end: %d, pre-change-length: %d]"
+ start end pre-change-length)
+
+ (let ((original-start (phpinspect-edtrack-original-position-at-point track
start)))
+ (phpinspect-edtrack-register-taint
+ track original-start (+ original-start pre-change-length)))
+
+ (let ((edit-before (phpinspect-edtrack-edits track)))
+ (while (and edit-before (< end (phpinspect-edit-end edit-before)))
+ (setq edit-before (cdr edit-before)))
+
+ (let ((delta ;; The delta of this edit.
+ (- (- end start) pre-change-length))
+ new-edit)
+ (setq new-edit (cons
+ ;; The end location of the edited region, before being
+ ;; edited, with the delta edits that happened at
preceding
+ ;; points in the buffer subtratted. This corresponds
with
+ ;; the original position of the region end before the
+ ;; buffer was ever edited.
+ (phpinspect-edtrack-original-position-at-point
+ track (+ start pre-change-length))
+ delta))
+ (if edit-before
+ (progn
+ (setcdr edit-before (cons (car edit-before) (cdr edit-before)))
+ (setcar edit-before new-edit))
+ (if (phpinspect-edtrack-edits track)
+ (push new-edit (cdr (last (phpinspect-edtrack-edits track))))
+ (push new-edit (phpinspect-edtrack-edits track)))))))
+
+
+(defsubst phpinspect-edtrack-clear-taint-pool (track)
+ (setf (phpinspect-edtrack-taint-pool track) nil))
+
+(defsubst phpinspect-edtrack-clear (track)
+ (setf (phpinspect-edtrack-edits track) nil)
+ (setf (phpinspect-edtrack-last-edit track) nil)
+ (setf (phpinspect-edtrack-last-edit-start track) -1)
+ (phpinspect-edtrack-clear-taint-pool track))
+
+
+(defsubst phpinspect-edtrack-make-taint-iterator (track)
+ (cons (car (phpinspect-edtrack-taint-pool track))
+ (cl-copy-list (cdr (phpinspect-edtrack-taint-pool track)))))
+
+(define-inline phpinspect-taint-iterator-current (iter)
+ (inline-quote (car ,iter)))
+
+(define-inline phpinspect-taint-iterator-follow (iter pos)
+ (inline-letevals (iter pos)
+ (inline-quote
+ (or (while (and (phpinspect-taint-iterator-current ,iter)
+ (> ,pos (phpinspect-taint-end
+ (phpinspect-taint-iterator-current ,iter))))
+ (setf (phpinspect-taint-iterator-current ,iter) (pop (cdr ,iter))))
+ (phpinspect-taint-iterator-current ,iter)))))
+
+(define-inline phpinspect-taint-iterator-token-is-tainted-p (iter meta)
+ (inline-letevals (iter meta)
+ (inline-quote
+ (and (phpinspect-taint-iterator-follow ,iter (phpinspect-meta-start
,meta))
+ (phpinspect-taint-overlaps-meta
+ (phpinspect-taint-iterator-current ,iter) ,meta)))))
+
+(define-inline phpinspect-taint-iterator-region-is-tainted-p (iter start end)
+ (inline-letevals (iter start end)
+ (inline-quote
+ (and (phpinspect-taint-iterator-follow ,iter ,start)
+ (phpinspect-taint-overlaps-region
+ (phpinspect-taint-iterator-current ,iter) ,start ,end)))))
+
(provide 'phpinspect-edtrack)
;;; phpinspect-edtrack.el ends here
diff --git a/phpinspect-eldoc.el b/phpinspect-eldoc.el
index b60bb885d2..0de18be472 100644
--- a/phpinspect-eldoc.el
+++ b/phpinspect-eldoc.el
@@ -24,8 +24,9 @@
;;; Code:
(require 'phpinspect-util)
(require 'phpinspect-meta)
-(require 'phpinspect-parser)
+(require 'phpinspect-token-predicates)
(require 'phpinspect-resolve)
+(require 'phpinspect-buffer)
(defvar phpinspect-eldoc-word-width 14
"The maximum width of words in eldoc strings.")
diff --git a/phpinspect-imports.el b/phpinspect-imports.el
index df37ec6195..fb42af3ffc 100644
--- a/phpinspect-imports.el
+++ b/phpinspect-imports.el
@@ -25,7 +25,7 @@
;;; Code:
-(require 'phpinspect-parser)
+(require 'phpinspect-token-predicates)
(require 'phpinspect-index)
(require 'phpinspect-autoload)
(require 'phpinspect-buffer)
@@ -80,15 +80,13 @@ buffer position to insert the use statement at."
(format "use %s;%c" fqn ?\n))
(let* ((first-token (phpinspect-meta-first-child
(phpinspect-buffer-root-meta buffer)))
token-after)
- (message "First token %s" (phpinspect-meta-string first-token))
(when (and (phpinspect-word-p (phpinspect-meta-token first-token))
(string= "declare" (cadr (phpinspect-meta-token
first-token))))
(progn
(setq token-after first-token)
(while (and token-after (not (phpinspect-terminator-p
(phpinspect-meta-token
token-after))))
- (setq token-after (phpinspect-meta-find-right-sibling
token-after))
- (message "Token after: %s" (phpinspect-meta-string
token-after)))))
+ (setq token-after (phpinspect-meta-find-right-sibling
token-after)))))
(if token-after
(phpinspect-insert-at-point
(phpinspect-meta-end token-after) (format "%c%cuse %s;%c" ?\n
?\n fqn ?\n))
@@ -155,8 +153,6 @@ that there are import (\"use\") statements for them."
(class-name (alist-get 'class-name class))
(region (alist-get 'location class))
token-meta)
- (message "Region: %s" region)
- (message "index: %s" index)
(setq token-meta (phpinspect-meta-find-parent-matching-token
(phpinspect-bmap-last-token-before-point
(phpinspect-buffer-map buffer)
diff --git a/phpinspect-index.el b/phpinspect-index.el
index 6c76a526b5..a4b7c919bd 100644
--- a/phpinspect-index.el
+++ b/phpinspect-index.el
@@ -25,9 +25,8 @@
(require 'cl-lib)
(require 'phpinspect-util)
-(require 'phpinspect-project)
(require 'phpinspect-type)
-(require 'phpinspect-parser)
+(require 'phpinspect-token-predicates)
(defun phpinspect--function-from-scope (scope)
(cond ((and (phpinspect-static-p (cadr scope))
@@ -158,15 +157,6 @@ function (think \"new\" statements, return types etc.)."
(defun phpinspect-doc-block-p (token)
(phpinspect-token-type-p token :doc-block))
-(defun phpinspect--get-class-name-from-token (class-token)
- (let ((subtoken (seq-find (lambda (word)
- (and (phpinspect-word-p word)
- (not (string-match
- (concat "^"
(phpinspect-handler-regexp class-keyword))
- (concat (cadr word) " ")))))
- (cadr class-token))))
- (cadr subtoken)))
-
(defsubst phpinspect--index-method-annotations (type-resolver comment)
(let ((annotations (seq-filter #'phpinspect-method-annotation-p comment))
@@ -195,40 +185,6 @@ function (think \"new\" statements, return types etc.)."
methods)))))
methods))
-(defun phpinspect--index-class-declaration (decl type-resolver)
- ;; Find out what the class extends or implements
- (let (encountered-extends encountered-implements encountered-class
- class-name extends implements used-types)
- (dolist (word decl)
- (if (phpinspect-word-p word)
- (cond ((string= (cadr word) "extends")
- (phpinspect--log "Class %s extends other classes" class-name)
- (setq encountered-extends t))
- ((string= (cadr word) "implements")
- (setq encountered-extends nil)
- (phpinspect--log "Class %s implements in interface"
class-name)
- (setq encountered-implements t))
- ((string= (cadr word) "class")
- (setq encountered-class t))
- (t
- (phpinspect--log "Calling Resolver from index-class on %s"
(cadr word))
- (cond (encountered-extends
- (push (funcall type-resolver (phpinspect--make-type
- :name (cadr word)))
- extends)
- (push (cadr word) used-types))
- (encountered-implements
- (push (funcall type-resolver (phpinspect--make-type
- :name (cadr word)))
- implements)
- (push (cadr word) used-types))
- (encountered-class
- (setq class-name (funcall type-resolver
(phpinspect--make-type :name (cadr word)))
- encountered-class nil)))))))
-
- (list class-name extends implements used-types)))
-
-
(defun phpinspect--index-class (imports type-resolver location-resolver class
&optional doc-block)
"Create an alist with relevant attributes of a parsed class."
(phpinspect--log "INDEXING CLASS")
@@ -395,22 +351,6 @@ NAMESPACE will be assumed the root namespace if not
provided"
(setq comment-before nil))))
indexed))
-(defun phpinspect--use-to-type (use)
- (let* ((fqn (cadr (cadr use)))
- (type (phpinspect--make-type :name (if (string-match "^\\\\" fqn)
- fqn
- (concat "\\" fqn))
- :fully-qualified t))
- (type-name (if (and (phpinspect-word-p (caddr use))
- (string= "as" (cadr (caddr use))))
- (cadr (cadddr use))
- (progn (string-match "[^\\]+$" fqn)
- (match-string 0 fqn)))))
- (cons (phpinspect-intern-name type-name) type)))
-
-(defun phpinspect--uses-to-types (uses)
- (mapcar #'phpinspect--use-to-type uses))
-
(defun phpinspect--index-namespace (namespace type-resolver-factory
location-resolver)
(let* (used-types
(index
@@ -530,14 +470,6 @@ Return value is a list of the types that are \"newed\"."
nil))
'(phpinspect--root-index)))
-(defun phpinspect-get-or-create-cached-project-class (project-root class-fqn)
- (when project-root
- (let ((project (phpinspect--cache-get-project-create
- (phpinspect--get-or-create-global-cache)
- project-root)))
- (phpinspect-project-get-class-create project class-fqn))))
-
-
(cl-defmethod phpinspect-index-get-class
((index (head phpinspect--root-index)) (class-name phpinspect--type))
(alist-get class-name (alist-get 'classes index)
diff --git a/phpinspect-parse-context.el b/phpinspect-parse-context.el
index bc0744416f..a42add3402 100644
--- a/phpinspect-parse-context.el
+++ b/phpinspect-parse-context.el
@@ -26,7 +26,6 @@
(require 'phpinspect-util)
(require 'phpinspect-meta)
(require 'phpinspect-changeset)
-(require 'phpinspect-bmap)
(defvar phpinspect-parse-context nil
"An instance of `phpinspect-pctx' that is used when
@@ -55,7 +54,7 @@ thrown.")
:documentation "Metadata change sets executed during this parse")
(edtrack nil
:type phpinspect-edtrack)
- (bmap (phpinspect-make-bmap)
+ (bmap nil
:type phpinspect-bmap)
(previous-bmap nil
:type phpinspect-bmap)
@@ -94,6 +93,18 @@ thrown.")
(progn
(push ,changeset (phpinspect-pctx-changesets ,pctx)))))
+(define-inline phpinspect-meta-with-changeset (meta &rest body)
+ (declare (indent 1))
+ (inline-letevals (meta)
+ (push 'progn body)
+ (inline-quote
+ (progn
+ (when phpinspect-parse-context
+ (phpinspect-pctx-register-changeset
+ phpinspect-parse-context (phpinspect-make-changeset ,meta)))
+ ,body))))
+
+
(define-inline phpinspect-pctx-check-interrupt (pctx)
(inline-letevals (pctx)
(inline-quote
@@ -108,12 +119,6 @@ thrown.")
(phpinspect-pctx-cancel ,pctx)
(throw 'phpinspect-parse-interrupted nil))))))
-(define-inline phpinspect-pctx-register-token (pctx token start end)
- (inline-letevals (pctx)
- (inline-quote
- (phpinspect-bmap-register
- (phpinspect-pctx-bmap ,pctx) ,start ,end ,token
(phpinspect-pctx-consume-whitespace ,pctx)))))
-
(define-inline phpinspect-pctx-register-whitespace (pctx whitespace)
(inline-quote
(setf (phpinspect-pctx-whitespace-before ,pctx) ,whitespace)))
diff --git a/phpinspect-parser.el b/phpinspect-parser.el
index 34561a25e5..59b9aa3220 100644
--- a/phpinspect-parser.el
+++ b/phpinspect-parser.el
@@ -53,14 +53,15 @@ If STRING has text properties, they are stripped."
(set-text-properties 0 length nil value)
(list token-keyword value)))
-(defun phpinspect-handler-func-name (handler-name)
- (intern (concat "phpinspect--" (symbol-name handler-name) "-handler")))
+(eval-when-compile
+ (defun phpinspect-handler-func-name (handler-name)
+ (intern (concat "phpinspect--" (symbol-name handler-name) "-handler")))
-(defun phpinspect-handler-regexp-func-name (handler-name)
- (intern (concat "phpinspect--" (symbol-name handler-name)
"-handler-regexp")))
+ (defun phpinspect-handler-regexp-func-name (handler-name)
+ (intern (concat "phpinspect--" (symbol-name handler-name)
"-handler-regexp")))
-(defun phpinspect-parser-func-name (name &optional suffix)
- (intern (concat "phpinspect--parse-" (symbol-name name) (if suffix (concat
"-" suffix) ""))))
+ (defun phpinspect-parser-func-name (name &optional suffix)
+ (intern (concat "phpinspect--parse-" (symbol-name name) (if suffix (concat
"-" suffix) "")))))
(defmacro phpinspect-defhandler (name arguments docstring attribute-alist
&rest body)
"Define a parser handler that becomes available for use with
phpinspect-parse.
@@ -130,8 +131,9 @@ You can purge the parser cache with
\\[phpinspect-purge-parser-cache]."
(put (quote ,inline-name) 'phpinspect--handler t))))
-(defun phpinspect-make-parser-function (name tree-type handlers &optional
delimiter-predicate)
- "Create a parser function using the handlers by names defined in
HANDLER-LIST.
+(eval-when-compile
+ (defun phpinspect-make-parser-function (name tree-type handlers &optional
delimiter-predicate)
+ "Create a parser function using the handlers by names defined in
HANDLER-LIST.
See also `phpinspect-defhandler`.
@@ -148,170 +150,170 @@ loop exits. An example use case of this is to
determine the end
of a statement. You can use `phpinspect-terminator-p` as
delimiter predicate and have parsing stop when the last parsed
token is \";\", which marks the end of a statement in PHP."
- (let ((delimiter-predicate (if (symbolp delimiter-predicate)
- `(quote ,delimiter-predicate)
- delimiter-predicate)))
- `(defsubst ,(phpinspect-parser-func-name name "simple") (buffer max-point
&optional skip-over continue-condition &rest _ignored)
- (with-current-buffer buffer
- (let* ((tokens (cons ,tree-type nil))
- (tokens-rear tokens)
- token
- (delimiter-predicate (when (functionp ,delimiter-predicate)
,delimiter-predicate)))
- (when skip-over (forward-char skip-over))
- (while (and (< (point) max-point)
- (if continue-condition (funcall continue-condition) t)
- (not (if delimiter-predicate
- (funcall delimiter-predicate (car (last
tokens)))
- nil)))
- (cond ,@(mapcar
- (lambda (handler)
- `((looking-at (,(phpinspect-handler-regexp-func-name
handler)))
- (setq token (,(phpinspect-handler-func-name handler)
(match-string 0) max-point))
- (when token
- (setq tokens-rear (setcdr tokens-rear (cons token
nil))))))
- handlers)
- (t (forward-char))))
-
- ;; Return
- tokens)))))
-
-
-(defun phpinspect-make-incremental-parser-function (name tree-type handlers
&optional delimiter-predicate)
- "Like `phpinspect-make-parser-function', but returned function
+ (let ((delimiter-predicate (if (symbolp delimiter-predicate)
+ `(quote ,delimiter-predicate)
+ delimiter-predicate)))
+ `(defsubst ,(phpinspect-parser-func-name name "simple") (buffer
max-point &optional skip-over continue-condition &rest _ignored)
+ (with-current-buffer buffer
+ (let* ((tokens (cons ,tree-type nil))
+ (tokens-rear tokens)
+ token
+ (delimiter-predicate (when (functionp ,delimiter-predicate)
,delimiter-predicate)))
+ (when skip-over (forward-char skip-over))
+ (while (and (< (point) max-point)
+ (if continue-condition (funcall continue-condition) t)
+ (not (if delimiter-predicate
+ (funcall delimiter-predicate (car (last
tokens)))
+ nil)))
+ (cond ,@(mapcar
+ (lambda (handler)
+ `((looking-at (,(phpinspect-handler-regexp-func-name
handler)))
+ (setq token (,(phpinspect-handler-func-name
handler) (match-string 0) max-point))
+ (when token
+ (setq tokens-rear (setcdr tokens-rear (cons
token nil))))))
+ handlers)
+ (t (forward-char))))
+
+ ;; Return
+ tokens)))))
+
+
+ (defun phpinspect-make-incremental-parser-function (name tree-type handlers
&optional delimiter-predicate)
+ "Like `phpinspect-make-parser-function', but returned function
is able to reuse an already parsed tree."
-(let ((delimiter-predicate (if (symbolp delimiter-predicate)
- `(quote ,delimiter-predicate)
- delimiter-predicate)))
- `(defsubst ,(phpinspect-parser-func-name name "incremental") (context
buffer max-point &optional skip-over continue-condition root)
- (with-current-buffer buffer
- (let* ((tokens (cons ,tree-type nil))
- (tokens-rear tokens)
- (root-start (point))
- (bmap (phpinspect-pctx-bmap context))
- (previous-bmap (phpinspect-pctx-previous-bmap context))
- (edtrack (phpinspect-pctx-edtrack context))
- (taint-iterator (when edtrack
(phpinspect-edtrack-make-taint-iterator edtrack)))
- (check-interrupt (phpinspect-pctx-interrupt-predicate context))
-
- ;; Loop variables
- (start-position)
- (original-position)
- (current-end-position)
- (existing-meta)
- (delta)
- (token)
- (delimiter-predicate (when (functionp ,delimiter-predicate)
,delimiter-predicate)))
- (when skip-over (forward-char skip-over))
- (phpinspect-pctx-save-whitespace context
- (while (and (< (point) max-point)
- (if continue-condition (funcall continue-condition) t)
- (not (if delimiter-predicate
- (funcall delimiter-predicate (car (last
tokens)))
- nil)))
- (when check-interrupt
- (phpinspect-pctx-check-interrupt context))
-
- (setq start-position (point))
- (cond ((and previous-bmap edtrack
- (setq existing-meta
- (phpinspect-bmap-token-starting-at
- previous-bmap
- (setq original-position
-
(phpinspect-edtrack-original-position-at-point edtrack start-position))))
- (not (or (phpinspect-root-p (phpinspect-meta-token
existing-meta))
-
(phpinspect-taint-iterator-token-is-tainted-p taint-iterator existing-meta))))
- (setq delta (- start-position original-position)
- current-end-position (+ (phpinspect-meta-end
existing-meta) delta)
- token (phpinspect-meta-token existing-meta))
-
- ;;(message "Reusing token %s at point %s"
(phpinspect-meta-string existing-meta) (point))
- ;; Re-register existing token
- (phpinspect-bmap-overlay
- bmap previous-bmap existing-meta delta
- (phpinspect-pctx-consume-whitespace context))
-
- (goto-char current-end-position)
-
- ;; Skip over whitespace after so that we don't do a full
- ;; run down all of the handlers during the next iteration
- (when (looking-at (phpinspect-handler-regexp whitespace))
- (,(phpinspect-handler-func-name 'whitespace)
(match-string 0))))
- ,@(mapcar
- (lambda (handler)
- `((looking-at (,(phpinspect-handler-regexp-func-name
handler)))
- (setq token (,(phpinspect-handler-func-name
handler) (match-string 0) max-point))
- (when token
- (phpinspect-pctx-register-token context token
start-position (point)))))
- handlers)
- (t (forward-char)))
- (when token
- (setq tokens-rear (setcdr tokens-rear (cons token nil)))
- (setq token nil))))
- (when root
- (phpinspect-pctx-register-token context tokens root-start
(point)))
-
- ;; Return
- tokens)))))
-
-(cl-defstruct (phpinspect-parser (:constructor phpinspect-make-parser))
- (name 'root
- :type symbol
- :read-only t)
- (tree-keyword "root"
- :type string
- :read-only t
- :documentation "Name of the keyword that is used as car of the
+ (let ((delimiter-predicate (if (symbolp delimiter-predicate)
+ `(quote ,delimiter-predicate)
+ delimiter-predicate)))
+ `(defsubst ,(phpinspect-parser-func-name name "incremental") (context
buffer max-point &optional skip-over continue-condition root)
+ (with-current-buffer buffer
+ (let* ((tokens (cons ,tree-type nil))
+ (tokens-rear tokens)
+ (root-start (point))
+ (bmap (phpinspect-pctx-bmap context))
+ (previous-bmap (phpinspect-pctx-previous-bmap context))
+ (edtrack (phpinspect-pctx-edtrack context))
+ (taint-iterator (when edtrack
(phpinspect-edtrack-make-taint-iterator edtrack)))
+ (check-interrupt (phpinspect-pctx-interrupt-predicate
context))
+
+ ;; Loop variables
+ (start-position)
+ (original-position)
+ (current-end-position)
+ (existing-meta)
+ (delta)
+ (token)
+ (delimiter-predicate (when (functionp ,delimiter-predicate)
,delimiter-predicate)))
+ (when skip-over (forward-char skip-over))
+ (phpinspect-pctx-save-whitespace context
+ (while (and (< (point) max-point)
+ (if continue-condition (funcall continue-condition)
t)
+ (not (if delimiter-predicate
+ (funcall delimiter-predicate (car (last
tokens)))
+ nil)))
+ (when check-interrupt
+ (phpinspect-pctx-check-interrupt context))
+
+ (setq start-position (point))
+ (cond ((and previous-bmap edtrack
+ (setq existing-meta
+ (phpinspect-bmap-token-starting-at
+ previous-bmap
+ (setq original-position
+
(phpinspect-edtrack-original-position-at-point edtrack start-position))))
+ (not (or (phpinspect-root-p
(phpinspect-meta-token existing-meta))
+
(phpinspect-taint-iterator-token-is-tainted-p taint-iterator existing-meta))))
+ (setq delta (- start-position original-position)
+ current-end-position (+ (phpinspect-meta-end
existing-meta) delta)
+ token (phpinspect-meta-token existing-meta))
+
+ ;;(message "Reusing token %s at point %s"
(phpinspect-meta-string existing-meta) (point))
+ ;; Re-register existing token
+ (phpinspect-bmap-overlay
+ bmap previous-bmap existing-meta delta
+ (phpinspect-pctx-consume-whitespace context))
+
+ (goto-char current-end-position)
+
+ ;; Skip over whitespace after so that we don't do a
full
+ ;; run down all of the handlers during the next
iteration
+ (when (looking-at (phpinspect-handler-regexp
whitespace))
+ (,(phpinspect-handler-func-name 'whitespace)
(match-string 0))))
+ ,@(mapcar
+ (lambda (handler)
+ `((looking-at
(,(phpinspect-handler-regexp-func-name handler)))
+ (setq token (,(phpinspect-handler-func-name
handler) (match-string 0) max-point))
+ (when token
+ (phpinspect-pctx-register-token context token
start-position (point)))))
+ handlers)
+ (t (forward-char)))
+ (when token
+ (setq tokens-rear (setcdr tokens-rear (cons token nil)))
+ (setq token nil))))
+ (when root
+ (phpinspect-pctx-register-token context tokens root-start
(point)))
+
+ ;; Return
+ tokens)))))
+
+ (cl-defstruct (phpinspect-parser (:constructor phpinspect-make-parser))
+ (name 'root
+ :type symbol
+ :read-only t)
+ (tree-keyword "root"
+ :type string
+ :read-only t
+ :documentation "Name of the keyword that is used as car of
the
root token, in string form without \":\" prefix.")
- (handlers '(array tag equals list comma
- attribute-reference variable
- assignment-operator whitespace scope-keyword
- static-keyword const-keyword use-keyword
- class-keyword function-keyword word terminator
- here-doc string comment block)
- :type list
- :read-only t
- :documentation "A list of symbols referring to the
+ (handlers '(array tag equals list comma
+ attribute-reference variable
+ assignment-operator whitespace scope-keyword
+ static-keyword const-keyword use-keyword
+ class-keyword function-keyword word terminator
+ here-doc string comment block)
+ :type list
+ :read-only t
+ :documentation "A list of symbols referring to the
handlers that this parser uses.")
- (delimiter-predicate nil
- :type function
- :read-only t
- :documentation "A predicate function that is passed each
+ (delimiter-predicate nil
+ :type function
+ :read-only t
+ :documentation "A predicate function that is passed
each
parsed token. When the predicate returns a non-nil value, the parser stops
executing.")
- (func nil
- :type function
- :documentation "The parser function.")
- (incremental-func nil
- :type function
- :documentation "Incemental parser function"))
-
-(cl-defmethod phpinspect-parser-compile ((parser phpinspect-parser))
- "Create/return parser function."
- (or (phpinspect-parser-func parser)
- (setf (phpinspect-parser-func parser)
- (phpinspect-make-parser-function
- (phpinspect-parser-name parser)
- (intern (concat ":" (phpinspect-parser-tree-keyword parser)))
- (phpinspect-parser-handlers parser)
- (phpinspect-parser-delimiter-predicate parser)))))
-
-(cl-defmethod phpinspect-parser-compile-incremental ((parser
phpinspect-parser))
- "Like `phpinspect-parser-compile', but for an incremental
+ (func nil
+ :type function
+ :documentation "The parser function.")
+ (incremental-func nil
+ :type function
+ :documentation "Incemental parser function"))
+
+ (cl-defmethod phpinspect-parser-compile ((parser phpinspect-parser))
+ "Create/return parser function."
+ (or (phpinspect-parser-func parser)
+ (setf (phpinspect-parser-func parser)
+ (phpinspect-make-parser-function
+ (phpinspect-parser-name parser)
+ (intern (concat ":" (phpinspect-parser-tree-keyword parser)))
+ (phpinspect-parser-handlers parser)
+ (phpinspect-parser-delimiter-predicate parser)))))
+
+ (cl-defmethod phpinspect-parser-compile-incremental ((parser
phpinspect-parser))
+ "Like `phpinspect-parser-compile', but for an incremental
version of the parser function."
- (or (phpinspect-parser-incremental-func parser)
- (setf (phpinspect-parser-incremental-func parser)
- (phpinspect-make-incremental-parser-function
- (phpinspect-parser-name parser)
- (intern (concat ":" (phpinspect-parser-tree-keyword parser)))
- (phpinspect-parser-handlers parser)
- (phpinspect-parser-delimiter-predicate parser)))))
-
-(cl-defmethod phpinspect-parser-compile-entry ((parser phpinspect-parser))
- (let ((func-name (phpinspect-parser-func-name (phpinspect-parser-name
parser)))
- (incremental-name (phpinspect-parser-func-name (phpinspect-parser-name
parser) "incremental"))
- (simple-name (phpinspect-parser-func-name (phpinspect-parser-name
parser) "simple")))
- `(defun ,func-name (buffer max-point &optional skip-over
continue-condition root)
- "Parse BUFFER, starting at point and ending at MAX-POINT.
+ (or (phpinspect-parser-incremental-func parser)
+ (setf (phpinspect-parser-incremental-func parser)
+ (phpinspect-make-incremental-parser-function
+ (phpinspect-parser-name parser)
+ (intern (concat ":" (phpinspect-parser-tree-keyword parser)))
+ (phpinspect-parser-handlers parser)
+ (phpinspect-parser-delimiter-predicate parser)))))
+
+ (cl-defmethod phpinspect-parser-compile-entry ((parser phpinspect-parser))
+ (let ((func-name (phpinspect-parser-func-name (phpinspect-parser-name
parser)))
+ (incremental-name (phpinspect-parser-func-name
(phpinspect-parser-name parser) "incremental"))
+ (simple-name (phpinspect-parser-func-name (phpinspect-parser-name
parser) "simple")))
+ `(defun ,func-name (buffer max-point &optional skip-over
continue-condition root)
+ "Parse BUFFER, starting at point and ending at MAX-POINT.
If SKIP-OVER is non-nil, it must be a number of characters that
to skip over before starting to parse.
@@ -326,10 +328,12 @@ returned token tree. So the parser should register the
metadata
of the root of its returned tree itself, before
returning. Currently, token metadata is only registered when
parsing incrementally."
- (if (and phpinspect-parse-context
- (phpinspect-pctx-incremental phpinspect-parse-context))
- (,incremental-name phpinspect-parse-context buffer max-point
skip-over continue-condition root)
- (,simple-name buffer max-point skip-over continue-condition root)))))
+ (if (and phpinspect-parse-context
+ (phpinspect-pctx-incremental phpinspect-parse-context))
+ (,incremental-name phpinspect-parse-context buffer max-point
skip-over continue-condition root)
+ (,simple-name buffer max-point skip-over continue-condition
root)))))
+
+ ) ;; End of eval-when-compile
(defmacro phpinspect-defparser (name &rest parameters)
(declare (indent 1))
@@ -342,19 +346,20 @@ parsing incrementally."
(simple-name (phpinspect-parser-func-name name "simple"))
(incremental-name (phpinspect-parser-func-name name "incremental")))
- `(let ((parser (phpinspect-make-parser ,@parameters)))
- (defconst ,simple-name nil)
- (defconst ,incremental-name nil)
+ `(eval-when-compile
+ (let ((parser (phpinspect-make-parser ,@parameters)))
+ (defconst ,simple-name nil)
+ (defconst ,incremental-name nil)
- (put (quote ,simple-name) 'phpinspect--parser t)
- (put (quote ,incremental-name) 'phpinspect--incremental-parser t)
+ (put (quote ,simple-name) 'phpinspect--parser t)
+ (put (quote ,incremental-name) 'phpinspect--incremental-parser t)
- (setf ,simple-name parser)
- (setf ,incremental-name parser)
+ (setf ,simple-name parser)
+ (setf ,incremental-name parser)
- ;; Stub function to please the byte compiler (real function will be
- ;; defined by `phpinspect-define-parser-functions'.
- (defun ,func-name (_buffer _max-point &optional _continue-condition
_root)))))
+ ;; Stub function to please the byte compiler (real function will be
+ ;; defined by `phpinspect-define-parser-functions'.
+ (defun ,func-name (_buffer _max-point &optional _skip-over
_continue-condition _root))))))
(define-inline phpinspect-parser-func-bound-p (symbol)
(inline-quote (get ,symbol 'phpinspect--parser)))
@@ -410,6 +415,40 @@ parsing incrementally."
(let ((name (phpinspect-handler-regexp-func-name handler-name)))
`(,name)))
+(phpinspect-defhandler variable (start-token &rest _ignored)
+ "Handler for tokens indicating reference to a variable"
+ ((regexp . "\\$"))
+ (forward-char (length start-token))
+ (if (looking-at (phpinspect-handler-regexp word))
+ (phpinspect-munch-token-without-attribs (match-string 0) :variable)
+ (list :variable nil)))
+
+(phpinspect-defparser list
+ :tree-keyword "list"
+ :handlers '(array tag equals list comma
+ attribute-reference variable assignment-operator
+ whitespace function-keyword word terminator here-doc
+ string comment block-without-scopes))
+
+(phpinspect-defhandler list (start-token max-point)
+ "Handler for php syntactic lists (Note: this does not include
+datatypes like arrays, merely lists that are of a syntactic
+nature like argument lists"
+ ((regexp . "("))
+ (let* ((complete-list nil)
+ (php-list (phpinspect--parse-list
+ (current-buffer)
+ max-point
+ (length start-token)
+ (lambda () (not (and (char-equal (char-after) ?\)) (setq
complete-list t)))))))
+
+ (if complete-list
+ ;; Prevent parent-lists (if any) from exiting by skipping over the
+ ;; ")" character
+ (forward-char)
+ (setcar php-list :incomplete-list))
+ php-list))
+
(defsubst phpinspect--parse-annotation-parameters (parameter-amount)
(let* ((words)
(list-regexp (phpinspect-handler-regexp list))
@@ -498,13 +537,6 @@ parsing incrementally."
(let ((end-position (line-end-position)))
(phpinspect--parse-comment (current-buffer) end-position)))))
-(phpinspect-defhandler variable (start-token &rest _ignored)
- "Handler for tokens indicating reference to a variable"
- ((regexp . "\\$"))
- (forward-char (length start-token))
- (if (looking-at (phpinspect-handler-regexp word))
- (phpinspect-munch-token-without-attribs (match-string 0) :variable)
- (list :variable nil)))
(phpinspect-defhandler class-variable (start-token &rest _ignored)
"Handler for tokens indicating reference to a variable"
@@ -703,31 +735,6 @@ Returns the consumed text string without face properties."
nil t)
(buffer-substring-no-properties start-point (- (point)
1)))))))))
-(phpinspect-defparser list
- :tree-keyword "list"
- :handlers '(array tag equals list comma
- attribute-reference variable assignment-operator
- whitespace function-keyword word terminator here-doc
- string comment block-without-scopes))
-
-(phpinspect-defhandler list (start-token max-point)
- "Handler for php syntactic lists (Note: this does not include
-datatypes like arrays, merely lists that are of a syntactic
-nature like argument lists"
- ((regexp . "("))
- (let* ((complete-list nil)
- (php-list (phpinspect--parse-list
- (current-buffer)
- max-point
- (length start-token)
- (lambda () (not (and (char-equal (char-after) ?\)) (setq
complete-list t)))))))
-
- (if complete-list
- ;; Prevent parent-lists (if any) from exiting by skipping over the
- ;; ")" character
- (forward-char)
- (setcar php-list :incomplete-list))
- php-list))
(phpinspect-defparser declaration
:tree-keyword "declaration"
@@ -855,13 +862,6 @@ the properties of the class"
function-keyword word terminator here-doc string
comment
tag block))
-(defun phpinspect-parse-buffer-until-point (buffer point)
- (with-current-buffer buffer
- (save-excursion
- (goto-char (point-min))
- (re-search-forward "<\\?php\\|<\\?" nil t)
- (phpinspect--parse-root (current-buffer) point nil nil 'root))))
-
(defun phpinspect-parse-current-buffer ()
(phpinspect-parse-buffer-until-point
(current-buffer)
@@ -878,7 +878,15 @@ the properties of the class"
(phpinspect-parse-current-buffer)))
;; Define all registered parser functions
-(phpinspect-define-parser-functions)
+(eval-and-compile
+ (phpinspect-define-parser-functions))
+
+(defun phpinspect-parse-buffer-until-point (buffer point)
+ (with-current-buffer buffer
+ (save-excursion
+ (goto-char (point-min))
+ (re-search-forward "<\\?php\\|<\\?" nil t)
+ (phpinspect--parse-root (current-buffer) point nil nil 'root))))
(provide 'phpinspect-parser)
;;; phpinspect-parser.el ends here
diff --git a/phpinspect-pipeline.el b/phpinspect-pipeline.el
index 6084c6550d..d13c66725f 100644
--- a/phpinspect-pipeline.el
+++ b/phpinspect-pipeline.el
@@ -129,7 +129,7 @@ directories."
(define-inline phpinspect-pipeline-pause ()
"Pause the current pipeline thread"
(inline-quote
- (if (input-pending-p)
+ (if (phpinspect--input-pending-p)
(let ((mx (make-mutex)))
(phpinspect-thread-pause
phpinspect-pipeline-pause-time mx (make-condition-variable mx
"phpinspect-pipeline-pause")))
diff --git a/phpinspect-project.el b/phpinspect-project.el
index 6f8b228fff..dded436c0c 100644
--- a/phpinspect-project.el
+++ b/phpinspect-project.el
@@ -23,6 +23,10 @@
;;; Code:
+(require 'phpinspect-project-struct)
+(require 'phpinspect-autoload)
+(require 'phpinspect-worker)
+(require 'phpinspect-index)
(require 'phpinspect-class)
(require 'phpinspect-type)
(require 'phpinspect-fs)
@@ -45,47 +49,6 @@ serious performance hits. Enable at your own risk (:")
(set (make-local-variable 'phpinspect--buffer-project) (funcall
phpinspect-project-root-function)))
phpinspect--buffer-project)
-(cl-defstruct (phpinspect-project (:constructor phpinspect--make-project))
- (class-index (make-hash-table :test 'eq :size 100 :rehash-size 1.5)
- :type hash-table
- :documentation
- "A `hash-table` that contains all of the currently
-indexed classes in the project")
- (function-index (make-hash-table :test 'eq :size 100 :rehash-size 2.0)
- :type hash-table
- :documentation
- "A hash able that contains all of the currently indexed
functions
-in the project")
- (function-token-index (make-hash-table :test 'eq :size 100 :rehash-size 1.5))
- (fs nil
- :type phpinspect-fs
- :documentation
- "The filesystem object through which this project's files
-can be accessed.")
- (autoload nil
- :type phpinspect-autoload
- :documentation
- "The autoload object through which this project's type
-definitions can be retrieved")
- (worker (progn
- (unless (featurep 'phpinspect-worker)
- (require 'phpinspect-worker))
- (phpinspect-make-dynamic-worker))
- :type phpinspect-worker
- :documentation
- "The worker that this project may queue tasks for")
- (root nil
- :type string
- :documentation
- "The root directory of this project")
- (purged nil
- :type boolean
- :documentation "Whether or not the project has been purged or not.
-Projects get purged when they are removed from the global cache.")
- (file-watchers (make-hash-table :test #'equal :size 10000 :rehash-size 10000)
- :type hash-table
- :documentation "All active file watchers in this project,
-indexed by the absolute paths of the files they're watching."))
(cl-defmethod phpinspect-project-purge ((project phpinspect-project))
"Disable all background processes for project and put it in a `purged`
state."
@@ -197,7 +160,8 @@ indexed by the absolute paths of the files they're
watching."))
(class (gethash class-name
(phpinspect-project-class-index project))))
(unless class
- (setq class (phpinspect--make-class-generated :project project)))
+ (setq class (phpinspect--make-class-generated
+ :class-retriever (phpinspect-project-make-class-retriever
project))))
(when index-imports
(phpinspect-project-enqueue-imports
@@ -215,7 +179,8 @@ indexed by the absolute paths of the files they're
watching."))
(cl-defmethod phpinspect-project-create-class
((project phpinspect-project) (class-fqn phpinspect--type))
- (let ((class (phpinspect--make-class-generated :project project)))
+ (let ((class (phpinspect--make-class-generated
+ :class-retriever (phpinspect-project-make-class-retriever
project))))
(phpinspect-project-set-class project class-fqn class)
class))
@@ -283,20 +248,6 @@ before the search is executed."
(cl-defmethod phpinspect-project-add-file-index ((project phpinspect-project)
(filename string))
(phpinspect-project-add-index project (phpinspect-project-index-file project
filename)))
-(defun phpinspect-project-enqueue-include-dirs (project)
- (interactive (list (phpinspect--cache-get-project-create
- (phpinspect--get-or-create-global-cache)
- (phpinspect-current-project-root))))
- (let ((dirs (alist-get 'include-dirs
- (alist-get (phpinspect-project-root project)
- phpinspect-projects
- nil nil #'string=))))
- (dolist (dir dirs)
- (message "enqueueing dir %s" dir)
- (phpinspect-worker-enqueue
- (phpinspect-project-worker project)
- (phpinspect-make-index-dir-task :dir dir :project project)))))
-
(defcustom phpinspect-projects nil
"PHPInspect Projects."
:type '(alist :key-type string
@@ -304,22 +255,95 @@ before the search is executed."
:options ((include-dirs (repeat string)))))
:group 'phpinspect)
-(defun phpinspect-project-add-include-dir (dir)
- "Configure DIR as an include dir for the current project."
- (interactive (list (read-directory-name "Include Directory: ")))
- (custom-set-variables '(phpinspect-projects))
- (let ((existing
- (alist-get (phpinspect-current-project-root) phpinspect-projects nil
#'string=)))
- (if existing
- (push dir (alist-get 'include-dirs existing))
- (push `(,(phpinspect-current-project-root) . ((include-dirs . (,dir))))
phpinspect-projects)))
-
- (customize-save-variable 'phpinspect-projects phpinspect-projects)
-
- (phpinspect-project-enqueue-include-dirs
(phpinspect--cache-get-project-create
-
(phpinspect--get-or-create-global-cache)
-
(phpinspect-current-project-root))))
-
+(defun phpinspect-project-make-file-indexer (project)
+ (lambda (filename)
+ (phpinspect-project-add-file-index project filename)))
+
+(defun phpinspect-project-make-root-resolver (project)
+ (lambda () (phpinspect-project-root project)))
+
+(defun phpinspect-project-make-class-retriever (project)
+ (lambda (type) (phpinspect-project-get-class-create project type)))
+
+;;; INDEX TASK
+(cl-defstruct (phpinspect-index-task
+ (:constructor phpinspect-make-index-task-generated))
+ "Represents an index task that can be executed by a `phpinspect-worker`."
+ (project nil
+ :type phpinspect-project
+ :documentation
+ "The project that the task should be executed for.")
+ (type nil
+ :type phpinspect--type
+ :documentation
+ "The type whose file should be indexed."))
+
+(cl-defgeneric phpinspect-make-index-task ((project phpinspect-project)
+ (type phpinspect--type))
+ (phpinspect-make-index-task-generated
+ :project project
+ :type type))
+
+(cl-defmethod phpinspect-task-project ((task phpinspect-index-task))
+ (phpinspect-index-task-project task))
+
+
+(cl-defmethod phpinspect-task= ((task1 phpinspect-index-task) (task2
phpinspect-index-task))
+ (and (eq (phpinspect-index-task-project task1)
+ (phpinspect-index-task-project task2))
+ (phpinspect--type= (phpinspect-index-task-type task1)
(phpinspect-index-task-type task2))))
+
+(cl-defmethod phpinspect-task-execute ((task phpinspect-index-task)
+ (worker phpinspect-worker))
+ "Execute index TASK for WORKER."
+ (let ((project (phpinspect-index-task-project task))
+ (is-native-type (phpinspect--type-is-native
+ (phpinspect-index-task-type task))))
+ (phpinspect--log "Indexing class %s for project in %s as task."
+ (phpinspect-index-task-type task)
+ (phpinspect-project-root project))
+
+ (cond (is-native-type
+ (phpinspect--log "Skipping indexation of native type %s as task"
+ (phpinspect-index-task-type task))
+
+ ;; We can skip pausing when a native type is encountered
+ ;; and skipped, as we haven't done any intensive work that
+ ;; may cause hangups.
+ (setf (phpinspect-worker-skip-next-pause worker) t))
+ (t
+ (let* ((type (phpinspect-index-task-type task))
+ (root-index (phpinspect-project-index-type-file project
type)))
+ (when root-index
+ (phpinspect-project-add-index project root-index)))))))
+
+;;; INDEX FILE TASK
+(cl-defstruct (phpinspect-index-dir-task (:constructor
phpinspect-make-index-dir-task))
+ "A task for the indexation of files"
+ (project nil
+ :type phpinspect-project)
+ (dir nil
+ :type string))
+
+(cl-defmethod phpinspect-task=
+ ((task1 phpinspect-index-dir-task) (task2 phpinspect-index-dir-task))
+ (and (eq (phpinspect-index-dir-task-project task1)
+ (phpinspect-index-dir-task-project task2))
+ (string= (phpinspect-index-dir-task-dir task1)
+ (phpinspect-index-dir-task-dir task2))))
+
+(cl-defmethod phpinspect-task-project ((task phpinspect-index-dir-task))
+ (phpinspect-index-dir-task-project task))
+
+(cl-defmethod phpinspect-task-execute ((task phpinspect-index-dir-task)
+ (_worker phpinspect-worker))
+ (phpinspect--log "Entering..")
+ (let* ((project (phpinspect-index-dir-task-project task))
+ (fs (phpinspect-project-fs project))
+ (dir (phpinspect-index-dir-task-dir task)))
+ (phpinspect--log "Indexing directory %s" dir)
+ (phpinspect-pipeline (phpinspect-fs-directory-files-recursively fs dir
"\\.php$")
+ :into (phpinspect-project-add-file-index :with-context project))))
(provide 'phpinspect-project)
;;; phpinspect-project.el ends here
diff --git a/phpinspect-resolve.el b/phpinspect-resolve.el
index 76e2159249..2c722c77ae 100644
--- a/phpinspect-resolve.el
+++ b/phpinspect-resolve.el
@@ -24,8 +24,9 @@
;;; Code:
(require 'phpinspect-resolvecontext)
+(require 'phpinspect-cache)
(require 'phpinspect-type)
-(require 'phpinspect-parser)
+(require 'phpinspect-token-predicates)
(cl-defstruct (phpinspect--assignment
(:constructor phpinspect--make-assignment))
@@ -36,13 +37,6 @@
:type phpinspect-token
:documentation "The token that is assigned from"))
-(define-inline phpinspect-statement-introduction-p (token)
- (inline-letevals (token)
- (inline-quote
- (or (phpinspect-return-p ,token)
- (phpinspect-end-of-statement-p ,token)
- (phpinspect-function-p ,token)))))
-
(defsubst phpinspect-block-or-list-p (token)
(or (phpinspect-block-p token)
(phpinspect-list-p token)))
diff --git a/phpinspect-resolvecontext.el b/phpinspect-resolvecontext.el
index 2a95575d99..557069eba4 100644
--- a/phpinspect-resolvecontext.el
+++ b/phpinspect-resolvecontext.el
@@ -24,12 +24,31 @@
;;; Code:
(require 'phpinspect-bmap)
+(require 'phpinspect-cache)
(require 'phpinspect-project)
-(require 'phpinspect-parser)
+(require 'phpinspect-token-predicates)
(require 'phpinspect-type)
(require 'phpinspect-meta)
(require 'phpinspect-util)
+
+(defsubst phpinspect-blocklike-p (token)
+ (or (phpinspect-block-p token)
+ (phpinspect-function-p token)
+ (phpinspect-class-p token)
+ (phpinspect-namespace-p token)))
+
+(defsubst phpinspect-return-p (token)
+ (and (phpinspect-word-p token)
+ (string= "return" (cadr token))))
+
+(define-inline phpinspect-statement-introduction-p (token)
+ (inline-letevals (token)
+ (inline-quote
+ (or (phpinspect-return-p ,token)
+ (phpinspect-end-of-statement-p ,token)
+ (phpinspect-function-p ,token)))))
+
(cl-defstruct (phpinspect--resolvecontext
(:constructor phpinspect--make-resolvecontext))
(subject nil
@@ -55,17 +74,6 @@
(push enclosing-token (phpinspect--resolvecontext-enclosing-tokens
resolvecontext)))
-
-(defsubst phpinspect-blocklike-p (token)
- (or (phpinspect-block-p token)
- (phpinspect-function-p token)
- (phpinspect-class-p token)
- (phpinspect-namespace-p token)))
-
-(defsubst phpinspect-return-p (token)
- (and (phpinspect-word-p token)
- (string= "return" (cadr token))))
-
(defun phpinspect-find-statement-before-point (bmap meta point)
(let ((children (reverse (phpinspect-meta-find-children-before meta point)))
token previous-siblings)
diff --git a/phpinspect-suggest.el b/phpinspect-suggest.el
index aff9c81312..d94b8854e8 100644
--- a/phpinspect-suggest.el
+++ b/phpinspect-suggest.el
@@ -25,7 +25,7 @@
(require 'phpinspect-resolvecontext)
(require 'phpinspect-resolve)
-(require 'phpinspect-parser)
+(require 'phpinspect-token-predicates)
(require 'phpinspect-type)
(require 'phpinspect-project)
(require 'phpinspect-class)
diff --git a/phpinspect-toc.el b/phpinspect-toc.el
index f27f6dfda0..b8f7d4e89a 100644
--- a/phpinspect-toc.el
+++ b/phpinspect-toc.el
@@ -24,7 +24,8 @@
;;; Code:
(require 'phpinspect-splayt)
-(require 'phpinspect-parser)
+(eval-when-compile
+ (require 'phpinspect-meta))
(defun phpinspect-make-toc (&optional tree)
(let ((table (make-hash-table :test #'eq :size 20 :rehash-size 2.0)))
diff --git a/phpinspect-token-predicates.el b/phpinspect-token-predicates.el
index f03883deb2..9ae912dc3e 100644
--- a/phpinspect-token-predicates.el
+++ b/phpinspect-token-predicates.el
@@ -56,10 +56,6 @@ Type can be any of the token types returned by
(phpinspect-comma-p token)
(phpinspect-html-p token)))
-(defsubst phpinspect-end-of-statement-p (token)
- (or (phpinspect-end-of-token-p token)
- (phpinspect-block-p token)))
-
(defsubst phpinspect-incomplete-block-p (token)
(phpinspect-token-type-p token :incomplete-block))
@@ -67,6 +63,10 @@ Type can be any of the token types returned by
(or (phpinspect-token-type-p token :block)
(phpinspect-incomplete-block-p token)))
+(defsubst phpinspect-end-of-statement-p (token)
+ (or (phpinspect-end-of-token-p token)
+ (phpinspect-block-p token)))
+
(defun phpinspect-end-of-use-p (token)
(or (phpinspect-block-p token)
(phpinspect-end-of-token-p token)))
@@ -170,11 +170,10 @@ Type can be any of the token types returned by
(or (phpinspect-token-type-p token :array)
(phpinspect-incomplete-array-p token)))
-(defsubst phpinspect-incomplete-root-p (token)
- (and (phpinspect-root-p token)
- (seq-find #'phpinspect-incomplete-token-p (cdr token))))
+(defsubst phpinspect-root-p (object)
+ (phpinspect-token-type-p object :root))
-(defsubst phpinspect-incomplete-token-p (token)
+(defun phpinspect-incomplete-token-p (token)
(or (phpinspect-incomplete-root-p token)
(phpinspect-incomplete-class-p token)
(phpinspect-incomplete-block-p token)
@@ -185,6 +184,10 @@ Type can be any of the token types returned by
(phpinspect-incomplete-method-p token)
(phpinspect-incomplete-namespace-p token)))
+(defun phpinspect-incomplete-root-p (token)
+ (and (phpinspect-root-p token)
+ (seq-find #'phpinspect-incomplete-token-p (cdr token))))
+
(defun phpinspect--static-terminator-p (token)
(or (phpinspect-function-p token)
(phpinspect-end-of-token-p token)))
@@ -214,9 +217,6 @@ Type can be any of the token types returned by
(and (phpinspect-word-p token) (string= (car (last token)) "use")))
-(defsubst phpinspect-root-p (object)
- (phpinspect-token-type-p object :root))
-
(defsubst phpinspect-namespace-or-root-p (object)
(or (phpinspect-namespace-p object)
(phpinspect-root-p object)))
@@ -247,4 +247,8 @@ Type can be any of the token types returned by
"Apply inverse of `phpinspect-class-p' to TOKEN."
(not (phpinspect-class-p token)))
+(defsubst phpinspect-probably-token-p (token)
+ (and (listp token)
+ (keywordp (car token))))
+
(provide 'phpinspect-token-predicates)
diff --git a/phpinspect-type.el b/phpinspect-type.el
index fbc941524e..abb2e44a54 100644
--- a/phpinspect-type.el
+++ b/phpinspect-type.el
@@ -24,6 +24,11 @@
;;; Code:
(require 'phpinspect-util)
+(require 'phpinspect-token-predicates)
+
+(eval-when-compile
+ (require 'phpinspect-parser))
+
(cl-defstruct (phpinspect--type
(:constructor phpinspect--make-type-generated)
@@ -279,5 +284,69 @@ mutability of the variable")
(not (or (phpinspect--variable-static-p variable)
(phpinspect--variable-const-p variable))))
+(defun phpinspect--use-to-type (use)
+ (let* ((fqn (cadr (cadr use)))
+ (type (phpinspect--make-type :name (if (string-match "^\\\\" fqn)
+ fqn
+ (concat "\\" fqn))
+ :fully-qualified t))
+ (type-name (if (and (phpinspect-word-p (caddr use))
+ (string= "as" (cadr (caddr use))))
+ (cadr (cadddr use))
+ (progn (string-match "[^\\]+$" fqn)
+ (match-string 0 fqn)))))
+ (cons (phpinspect-intern-name type-name) type)))
+
+(defun phpinspect--uses-to-types (uses)
+ (mapcar #'phpinspect--use-to-type uses))
+
+(defun phpinspect--get-class-name-from-token (class-token)
+ (let ((subtoken (seq-find (lambda (word)
+ (and (phpinspect-word-p word)
+ (not (string-match
+ (concat "^"
(phpinspect--class-keyword-handler-regexp))
+ (concat (cadr word) " ")))))
+ (cadr class-token))))
+ (cadr subtoken)))
+
+(defun phpinspect--index-class-declaration (decl type-resolver)
+ ;; Find out what the class extends or implements
+ (let (encountered-extends encountered-implements encountered-class
+ class-name extends implements used-types)
+ (dolist (word decl)
+ (if (phpinspect-word-p word)
+ (cond ((string= (cadr word) "extends")
+ (phpinspect--log "Class %s extends other classes" class-name)
+ (setq encountered-extends t))
+ ((string= (cadr word) "implements")
+ (setq encountered-extends nil)
+ (phpinspect--log "Class %s implements in interface"
class-name)
+ (setq encountered-implements t))
+ ((string= (cadr word) "class")
+ (setq encountered-class t))
+ (t
+ (phpinspect--log "Calling Resolver from index-class on %s"
(cadr word))
+ (cond (encountered-extends
+ (push (funcall type-resolver (phpinspect--make-type
+ :name (cadr word)))
+ extends)
+ (push (cadr word) used-types))
+ (encountered-implements
+ (push (funcall type-resolver (phpinspect--make-type
+ :name (cadr word)))
+ implements)
+ (push (cadr word) used-types))
+ (encountered-class
+ (setq class-name (funcall type-resolver
(phpinspect--make-type :name (cadr word)))
+ encountered-class nil)))))))
+
+ (list class-name extends implements used-types)))
+
+(defun phpinspect-namespace-name (namespace)
+ (or (and (phpinspect-namespace-p namespace)
+ (phpinspect-word-p (cadr namespace))
+ (cadadr namespace))
+ ""))
+
(provide 'phpinspect-type)
;;; phpinspect-type.el ends here
diff --git a/phpinspect-util.el b/phpinspect-util.el
index ca5b971243..0f6e6ad279 100644
--- a/phpinspect-util.el
+++ b/phpinspect-util.el
@@ -31,31 +31,6 @@ PHP. Used to optimize string comparison.")
'("composer.json" "composer.lock" ".git" ".svn" ".hg")
"List of files that could indicate a project root directory.")
-(defun phpinspect--find-project-root (&optional start-file)
- "(Attempt to) Find the root directory of the visited PHP project.
-If a found project root has a parent directory called \"vendor\",
-the search continues upwards. See also
-`phpinspect--locate-dominating-project-file'.
-
-If START-FILE is provided, searching starts at the directory
-level of START-FILE in stead of `default-directory`."
- (let ((project-file (phpinspect--locate-dominating-project-file
- (or start-file default-directory))))
- (phpinspect--log "Checking for project root at %s" project-file)
- (when project-file
- (let* ((directory (file-name-directory project-file))
- (directory-slugs (split-string (expand-file-name directory) "/")))
- (if (not (member "vendor" directory-slugs))
- (expand-file-name directory)
- ;; else. Only continue if the parent directory is not "/"
- (let ((parent-without-vendor
- (string-join (seq-take-while (lambda (s) (not (string= s
"vendor" )))
- directory-slugs)
- "/")))
- (when (not (or (string= parent-without-vendor "/")
- (string= parent-without-vendor "")))
- (phpinspect--find-project-root parent-without-vendor))))))))
-
(defvar phpinspect--debug nil
"Enable debug logs for phpinspect by setting this variable to true")
@@ -65,10 +40,10 @@ level of START-FILE in stead of `default-directory`."
(message "Enabled phpinspect logging.")
(message "Disabled phpinspect logging.")))
-(defvar phpinspect-log-groups nil)
-(defvar phpinspect-enabled-log-groups nil)
-
-(defvar-local phpinspect--current-log-group nil)
+(eval-and-compile
+ (defvar phpinspect-log-groups nil)
+ (defvar phpinspect-enabled-log-groups nil)
+ (defvar-local phpinspect--current-log-group nil))
(define-inline phpinspect--declare-log-group (group)
(unless (and (inline-const-p group) (symbolp (inline-const-val group)))
@@ -109,6 +84,31 @@ level of START-FILE in stead of `default-directory`."
(interactive)
(setq phpinspect-enabled-log-groups nil))
+(defun phpinspect--find-project-root (&optional start-file)
+ "(Attempt to) Find the root directory of the visited PHP project.
+If a found project root has a parent directory called \"vendor\",
+the search continues upwards. See also
+`phpinspect--locate-dominating-project-file'.
+
+If START-FILE is provided, searching starts at the directory
+level of START-FILE in stead of `default-directory`."
+ (let ((project-file (phpinspect--locate-dominating-project-file
+ (or start-file default-directory))))
+ (phpinspect--log "Checking for project root at %s" project-file)
+ (when project-file
+ (let* ((directory (file-name-directory project-file))
+ (directory-slugs (split-string (expand-file-name directory) "/")))
+ (if (not (member "vendor" directory-slugs))
+ (expand-file-name directory)
+ ;; else. Only continue if the parent directory is not "/"
+ (let ((parent-without-vendor
+ (string-join (seq-take-while (lambda (s) (not (string= s
"vendor" )))
+ directory-slugs)
+ "/")))
+ (when (not (or (string= parent-without-vendor "/")
+ (string= parent-without-vendor "")))
+ (phpinspect--find-project-root parent-without-vendor))))))))
+
(defsubst phpinspect-intern-name (name)
(intern name phpinspect-name-obarray))
@@ -251,6 +251,10 @@ context for completion."
(json-key-type 'string))
,@body))
+(defun phpinspect--input-pending-p (&optional check-timers)
+ (unless noninteractive
+ (input-pending-p check-timers)))
+
(defun phpinspect-thread-pause (pause-time mx continue)
"Pause current thread using MX and CONTINUE for PAUSE-TIME idle seconds.
@@ -265,16 +269,5 @@ CONTINUE must be a condition-variable"
(with-mutex mx (condition-wait continue))
(phpinspect--log "Thread '%s' continuing execution" (thread-name
(current-thread))))
-(defun phpinspect-namespace-name (namespace)
- (or (and (phpinspect-namespace-p namespace)
- (phpinspect-word-p (cadr namespace))
- (cadadr namespace))
- ""))
-
-
-(defsubst phpinspect-probably-token-p (token)
- (and (listp token)
- (keywordp (car token))))
-
(provide 'phpinspect-util)
;;; phpinspect-util.el ends here
diff --git a/phpinspect-worker.el b/phpinspect-worker.el
index 60977c0e48..b9bfe4fc39 100644
--- a/phpinspect-worker.el
+++ b/phpinspect-worker.el
@@ -1,4 +1,4 @@
-;;; phpinspect-worker.el --- PHP parsing and completion package -*-
lexical-binding: t; -*-
+;; phpinspect-worker.el --- PHP parsing and completion package -*-
lexical-binding: t; -*-
;; Copyright (C) 2021 Free Software Foundation, Inc
@@ -25,7 +25,7 @@
(require 'cl-lib)
(require 'phpinspect-util)
-(require 'phpinspect-project)
+(require 'phpinspect-project-struct)
(require 'phpinspect-index)
(require 'phpinspect-class)
(require 'phpinspect-queue)
@@ -75,7 +75,7 @@ on the worker independent of dynamic variables during
testing.")
(cl-defmethod phpinspect-resolve-dynamic-worker ((_worker
phpinspect-dynamic-worker))
phpinspect-worker)
-(defsubst phpinspect-make-dynamic-worker ()
+(defun phpinspect-make-dynamic-worker ()
(phpinspect-make-dynamic-worker-generated))
(defsubst phpinspect-make-worker ()
@@ -148,7 +148,7 @@ already present in the queue."
;; Pause for a second after indexing something, to allow user
input to
;; interrupt the thread.
- (unless (or (not (input-pending-p))
+ (unless (or (not (phpinspect--input-pending-p))
(phpinspect-worker-skip-next-pause worker))
(phpinspect-thread-pause phpinspect-worker-pause-time mx
continue))
(setf (phpinspect-worker-skip-next-pause worker) nil)))
@@ -225,86 +225,5 @@ already present in the queue."
(cl-defgeneric phpinspect-task-project (task)
"The project that this task belongs to.")
-
-;;; INDEX TASK
-(cl-defstruct (phpinspect-index-task
- (:constructor phpinspect-make-index-task-generated))
- "Represents an index task that can be executed by a `phpinspect-worker`."
- (project nil
- :type phpinspect-project
- :documentation
- "The project that the task should be executed for.")
- (type nil
- :type phpinspect--type
- :documentation
- "The type whose file should be indexed."))
-
-(cl-defgeneric phpinspect-make-index-task ((project phpinspect-project)
- (type phpinspect--type))
- (phpinspect-make-index-task-generated
- :project project
- :type type))
-
-(cl-defmethod phpinspect-task-project ((task phpinspect-index-task))
- (phpinspect-index-task-project task))
-
-
-(cl-defmethod phpinspect-task= ((task1 phpinspect-index-task) (task2
phpinspect-index-task))
- (and (eq (phpinspect-index-task-project task1)
- (phpinspect-index-task-project task2))
- (phpinspect--type= (phpinspect-index-task-type task1)
(phpinspect-index-task-type task2))))
-
-(cl-defmethod phpinspect-task-execute ((task phpinspect-index-task)
- (worker phpinspect-worker))
- "Execute index TASK for WORKER."
- (let ((project (phpinspect-index-task-project task))
- (is-native-type (phpinspect--type-is-native
- (phpinspect-index-task-type task))))
- (phpinspect--log "Indexing class %s for project in %s as task."
- (phpinspect-index-task-type task)
- (phpinspect-project-root project))
-
- (cond (is-native-type
- (phpinspect--log "Skipping indexation of native type %s as task"
- (phpinspect-index-task-type task))
-
- ;; We can skip pausing when a native type is encountered
- ;; and skipped, as we haven't done any intensive work that
- ;; may cause hangups.
- (setf (phpinspect-worker-skip-next-pause worker) t))
- (t
- (let* ((type (phpinspect-index-task-type task))
- (root-index (phpinspect-project-index-type-file project
type)))
- (when root-index
- (phpinspect-project-add-index project root-index)))))))
-
-;;; INDEX FILE TASK
-(cl-defstruct (phpinspect-index-dir-task (:constructor
phpinspect-make-index-dir-task))
- "A task for the indexation of files"
- (project nil
- :type phpinspect-project)
- (dir nil
- :type string))
-
-(cl-defmethod phpinspect-task=
- ((task1 phpinspect-index-dir-task) (task2 phpinspect-index-dir-task))
- (and (eq (phpinspect-index-dir-task-project task1)
- (phpinspect-index-dir-task-project task2))
- (string= (phpinspect-index-dir-task-dir task1)
- (phpinspect-index-dir-task-dir task2))))
-
-(cl-defmethod phpinspect-task-project ((task phpinspect-index-dir-task))
- (phpinspect-index-dir-task-project task))
-
-(cl-defmethod phpinspect-task-execute ((task phpinspect-index-dir-task)
- (_worker phpinspect-worker))
- (phpinspect--log "Entering..")
- (let* ((project (phpinspect-index-dir-task-project task))
- (fs (phpinspect-project-fs project))
- (dir (phpinspect-index-dir-task-dir task)))
- (phpinspect--log "Indexing directory %s" dir)
- (phpinspect-pipeline (phpinspect-fs-directory-files-recursively fs dir
"\\.php$")
- :into (phpinspect-project-add-file-index :with-context project))))
-
(provide 'phpinspect-worker)
;;; phpinspect-worker.el ends here
diff --git a/test/phpinspect-test.el b/test/phpinspect-test.el
index 88f2070ca0..c1ca0725d9 100644
--- a/test/phpinspect-test.el
+++ b/test/phpinspect-test.el
@@ -217,7 +217,7 @@
(ert-deftest phpinspect-resolve-type-from-context ()
- (let* ((pctx (phpinspect-make-pctx :incremental t))
+ (let* ((pctx (phpinspect-make-pctx :incremental t :bmap
(phpinspect-make-bmap)))
(code "
namespace Amazing;
diff --git a/test/test-autoload.el b/test/test-autoload.el
index 876f12add7..481c06e337 100644
--- a/test/test-autoload.el
+++ b/test/test-autoload.el
@@ -1,4 +1,4 @@
-;; test-autoload.el --- Unit tests for phpinspect.el -*- lexical-binding: t;
-*-
+; test-autoload.el --- Unit tests for phpinspect.el -*- lexical-binding: t;
-*-
;; Copyright (C) 2021 Free Software Foundation, Inc.
@@ -31,7 +31,11 @@
(ert-deftest phpinspect-find-composer-json-files ()
(let* ((fs (phpinspect-make-virtual-fs))
(autoloader (phpinspect-make-autoloader
- :project (phpinspect--make-project :root "/root" :fs
fs))))
+ :fs fs
+ :project-root-resolver (lambda () "/root")
+ :file-indexer
+ (phpinspect-project-make-file-indexer
+ (phpinspect--make-project :root "/root" :fs fs)))))
(phpinspect-virtual-fs-set-file fs
"/root/composer.json"
"{ \"autoload\": { \"psr-4\": {\"WoW\\\\Dwarves\\\\\": \"src/\"}}}")
@@ -57,9 +61,14 @@
(ert-deftest phpinspect-autoload-composer-json-iterator ()
(let* ((fs (phpinspect-make-virtual-fs))
(autoloader (phpinspect-make-autoloader
- :project (phpinspect--make-project :root "/root" :fs
fs)))
+ :fs fs
+ :project-root-resolver (lambda () "/root")
+ :file-indexer
+ (phpinspect-project-make-file-indexer
+ (phpinspect--make-project :root "/root" :fs fs))))
result error)
+
(phpinspect-virtual-fs-set-file fs
"/root/composer.json"
"{ \"autoload\": { \"psr-4\": {\"WoW\\\\Dwarves\\\\\": \"src/\"}}}")
@@ -92,7 +101,10 @@
(ert-deftest phpinspect-al-strategy-execute ()
(let* ((fs (phpinspect-make-virtual-fs))
(project (phpinspect--make-project :root "/project/root" :fs fs))
- (autoloader (phpinspect-make-autoloader :project project))
+ (autoloader (phpinspect-make-autoloader
+ :fs fs
+ :project-root-resolver (lambda () "/project/root")
+ :file-indexer (phpinspect-project-make-file-indexer
project)))
result error)
(setf (phpinspect-project-autoload project) autoloader)
@@ -131,7 +143,7 @@
"<?php class FilesList { function list() {} }")
(phpinspect-virtual-fs-set-file
- fs "/project/root/vendor/not-runescape/wow/src/TestClass.php" "")
+ fs "/project/root/vendor/not-runescape/wow/src/TestClass.php" "")
(phpinspect-pipeline (phpinspect-find-composer-json-files fs
"/project/root")
:async (lambda (res err)
diff --git a/test/test-class.el b/test/test-class.el
index 0dbfb88319..35c0ea7f36 100644
--- a/test/test-class.el
+++ b/test/test-class.el
@@ -101,7 +101,9 @@
(should (= 1 (length (hash-table-values (phpinspect--class-subscriptions
other-class)))))))
(ert-deftest phpinspect--class-update-declaration ()
- (let ((class (phpinspect--make-class-generated :project
(phpinspect--make-project))))
+ (let ((class (phpinspect--make-class-generated
+ :class-retriever (phpinspect-project-make-class-retriever
+ (phpinspect--make-project)))))
(phpinspect--class-update-declaration class '(:declaration (:word "class")
(:word "TestClass")
(:word
"extends") (:word "OtherClass")
(:word
"implements") (:word "ImplClass"))
diff --git a/test/test-index.el b/test/test-index.el
index 7bee75d9bd..ffea7fb505 100644
--- a/test/test-index.el
+++ b/test/test-index.el
@@ -169,7 +169,7 @@ return StaticThing::create(new
ThingFactory())->makeThing((((new Potato())->anti
(alist-get key index2-class))))))
(ert-deftest phpinspect-index-bmap-class ()
- (let* ((pctx (phpinspect-make-pctx :incremental t))
+ (let* ((pctx (phpinspect-make-pctx :incremental t :bmap
(phpinspect-make-bmap)))
(tree))
(with-temp-buffer
(insert-file-contents (concat phpinspect-test-php-file-directory
"/IndexClass1.php"))
diff --git a/test/test-parse-context.el b/test/test-parse-context.el
index b79db41183..82ae1cff77 100644
--- a/test/test-parse-context.el
+++ b/test/test-parse-context.el
@@ -29,7 +29,7 @@
(ert-deftest phpinspect-pctx-cancel ()
(let ((meta (phpinspect-make-meta nil 10 20 " " 'token 'overlay nil))
- (pctx (phpinspect-make-pctx)))
+ (pctx (phpinspect-make-pctx :bmap (phpinspect-make-bmap))))
(phpinspect-with-parse-context pctx
(phpinspect-meta-with-changeset meta
(setf (phpinspect-meta-absolute-start meta) 222)
diff --git a/test/test-parser.el b/test/test-parser.el
index d2ecf947c3..83e5fca60f 100644
--- a/test/test-parser.el
+++ b/test/test-parser.el
@@ -42,7 +42,7 @@
(ert-deftest phpinspect-parse-bmap ()
- (let* ((ctx (phpinspect-make-pctx :incremental t))
+ (let* ((ctx (phpinspect-make-pctx :incremental t :bmap
(phpinspect-make-bmap)))
(code "
class TestClass {
public function getCurrentStatisticAction(): JsonResponse
@@ -73,7 +73,7 @@ class TestClass {
(ert-deftest phpinspect-parse-comma ()
(let* ((code "(,)")
- (ctx (phpinspect-make-pctx :incremental t))
+ (ctx (phpinspect-make-pctx :incremental t :bmap
(phpinspect-make-bmap)))
(parsed (phpinspect-with-parse-context ctx
(phpinspect-parse-string code)))
(comma (cadadr parsed))
diff --git a/test/test-resolvecontext.el b/test/test-resolvecontext.el
index 75c6806af4..894f684080 100644
--- a/test/test-resolvecontext.el
+++ b/test/test-resolvecontext.el
@@ -2,7 +2,7 @@
(require 'phpinspect-resolvecontext)
(ert-deftest phinspect-get-resolvecontext ()
- (let* ((ctx (phpinspect-make-pctx :incremental t))
+ (let* ((ctx (phpinspect-make-pctx :incremental t :bmap
(phpinspect-make-bmap)))
(code "
class TestClass {
public function getCurrentStatisticAction(): JsonResponse