@ -134,7 +134,9 @@ NAMESPACE-META itself is returned without alterations."
( dolist ( import imports )
;; Namespace must be inferred within the loop, see comments in
;; `phpinspect-add-use-statements-for-missing-types' for context.
( let ( ( namespace ( phpinspect-meta-find-parent-matching-token parent-token #' phpinspect-namespace-p ) ) )
( let ( ( namespace ( if ( phpinspect-namespace-p ( phpinspect-meta-token parent-token ) )
parent-token
( phpinspect-meta-find-parent-matching-token parent-token #' phpinspect-namespace-p ) ) ) )
( unless ( member ( car import ) types )
( when-let ( ( use-meta ( phpinspect-find-use-statement-for-import namespace ( cdr import ) ) ) )
( let ( ( start-point ( phpinspect-meta-start use-meta ) )
@ -161,8 +163,10 @@ determine the scope of the imports (global or local namespace)."
;; Namespace token must be inferred within the loop, as the ancestors of
;; PARENT-TOKEN may change after a buffer reparse (which happens after each
;; insert)
( let* ( ( namespace ( phpinspect-meta-find-parent-matching-token
parent-token #' phpinspect-namespace-p ) )
( let* ( ( namespace ( if ( phpinspect-namespace-p ( phpinspect-meta-token parent-token ) )
parent-token
( phpinspect-meta-find-parent-matching-token
parent-token #' phpinspect-namespace-p ) ) )
( namespace-name ( if namespace
( phpinspect-namespace-name ( phpinspect-meta-token namespace ) )
" " ) ) )
@ -179,6 +183,48 @@ determine the scope of the imports (global or local namespace)."
( phpinspect-add-use-interactive type buffer project namespace )
( phpinspect-buffer-parse buffer 'no-interrupt ) ) ) ) ) )
( defun phpinspect-format-use-statements ( buffer first-meta )
" Format a group of use statements to be sorted in alphabetical
order and have the right amount of whitespace.
BUFFER should be the buffer ( ` phpinspect-buffer-p ' ) the use
statements are located in.
FIRST-META should be the metadata of the first use token of the
group. "
( when first-meta
( let ( ( statements
( list ( cons ( phpinspect-use-name-string ( phpinspect-meta-token first-meta ) )
first-meta ) ) )
( start ( phpinspect-meta-start first-meta ) )
( end ( phpinspect-meta-end first-meta ) )
( current first-meta ) )
( while ( and ( setq current ( phpinspect-meta-find-right-sibling current ) )
( phpinspect-use-p ( phpinspect-meta-token current ) ) )
( setq end ( phpinspect-meta-end current ) )
( push ( cons ( phpinspect-use-name-string ( phpinspect-meta-token current ) )
current )
statements ) )
( sort statements ( lambda ( a b ) ( string< ( car a ) ( car b ) ) ) )
;; Re-insert use statements
( with-current-buffer ( phpinspect-buffer-buffer buffer )
( goto-char start )
( delete-region start end )
( dolist ( statement statements )
( insert ( format " use %s;%c " ( car statement ) ?\n ) ) )
( if ( and ( looking-at " [[:blank:] \n ]+ " ) )
;; Delete excess trailing whitespace (there's more than 2 between the
;; last use statement and the next token)
( when ( < 1 ( - ( match-end 0 ) ( match-beginning 0 ) ) )
( delete-region ( match-beginning 0 ) ( match-end 0 ) )
( insert-char ?\n ) )
;; Insert an extra newline (there's only one between the last use
;; statement and the next token)
( insert-char ?\n ) ) ) ) ) )
( defun phpinspect-fix-imports ( )
" Find types that are used in the current buffer and make sure
that there are import ( \"use\" ) statements for them. "
@ -198,9 +244,34 @@ that there are import (\"use\") statements for them."
( index ( phpinspect--index-tokens
tree nil ( phpinspect-buffer-location-resolver buffer ) ) )
( classes ( alist-get 'classes index ) )
( namespaces ( alist-get 'namespaces index ) )
( imports ( alist-get 'imports index ) )
( project ( phpinspect-buffer-project buffer ) )
( used-types ( alist-get 'used-types index ) ) )
( used-types ( alist-get 'used-types index ) )
class-tokens
namespace-tokens )
;; First collect tokens in the buffer via which the namespace tokens can
;; be found. The edits we do to add imports will invalidate the class
;; region bounds, making this hard to do during the loop that adds them.
( dolist ( namespace namespaces )
( let ( ( region ( alist-get 'location namespace ) ) )
;; Use the first child of the namespace token. The namespace token
;; itself will be tainted and reparsed after every edit (inserted
;; use statement), making its reference useless as it will be in an
;; overlayed tree. The first token in the namespace, however will be
;; adopted into the new tree as long as it isn't altered. This
;; allows a lookup of the new namespace token by getting this
;; token's (newly assigned) parent after every edit.
( push ( cons ( phpinspect-meta-find-first-child-matching-token
( phpinspect-meta-find-parent-matching-token
( phpinspect-bmap-last-token-before-point
( phpinspect-buffer-map buffer )
( + ( phpinspect-region-start region ) 1 ) )
#' phpinspect-namespace-p )
#' phpinspect-word-p )
namespace )
namespace-tokens ) ) )
( phpinspect-add-use-statements-for-missing-types
used-types buffer imports project ( phpinspect-buffer-root-meta buffer ) )
@ -208,24 +279,30 @@ that there are import (\"use\") statements for them."
( phpinspect-remove-unneeded-use-statements
used-types buffer imports ( phpinspect-buffer-root-meta buffer ) )
( dolist ( class classes )
( let* ( ( class-imports ( alist-get 'imports class ) )
( used-types ( alist-get 'used-types class ) )
( class-name ( alist-get 'class-name class ) )
( region ( alist-get 'location class ) )
token-meta )
( setq token-meta ( phpinspect-meta-find-parent-matching-token
( phpinspect-bmap-last-token-before-point
( phpinspect-buffer-map buffer )
( + ( phpinspect-region-start region ) 1 ) )
#' phpinspect-class-p ) )
( phpinspect-format-use-statements
buffer ( phpinspect-find-first-use ( phpinspect-buffer-root-meta buffer ) ) )
( phpinspect-buffer-parse buffer 'no-interrupt )
( dolist ( cell namespace-tokens )
( let* ( ( namespace ( cdr cell ) )
( namespace-name ( car namespace ) )
( token-meta ( car cell ) )
( used-types ( alist-get 'used-types namespace ) )
( namespace-imports ( alist-get 'imports namespace ) ) )
( unless token-meta
( error " Unable to find token for class %s" class -name) )
( error " Unable to find token for namespace %s" namespace -name) )
( phpinspect-add-use-statements-for-missing-types
used-types buffer ( append imports class -imports) project token-meta )
used-types buffer ( append imports namespace -imports) project token-meta )
( phpinspect-remove-unneeded-use-statements
used-types buffer class-imports token-meta ) ) ) ) ) )
used-types buffer namespace-imports token-meta )
( let ( ( parent ( phpinspect-meta-find-parent-matching-token
token-meta #' phpinspect-namespace-or-root-p ) ) )
( phpinspect-format-use-statements buffer ( phpinspect-find-first-use parent ) )
( phpinspect-buffer-parse buffer 'no-interrupt ) ) ) ) ) ) )
( provide 'phpinspect-imports )