branch: externals/phps-mode commit e049853a6f4c0edfeb0212e17ee5084657b33813 Author: Christian Johansson <christ...@cvj.se> Commit: Christian Johansson <christ...@cvj.se>
Remove use of lex-analyzer from semantic and instead use custom --- phps-mode-lex-analyzer.el | 116 ++++++++++++++++-------------------------- phps-mode-lexer.el | 20 +++++--- phps-mode.el | 83 +++++++++++++++++------------- test/phps-mode-test-ast.el | 33 ++++++------ test/phps-mode-test-parser.el | 31 +++++------ 5 files changed, 138 insertions(+), 145 deletions(-) diff --git a/phps-mode-lex-analyzer.el b/phps-mode-lex-analyzer.el index 26f814fae3..81fb3abcfa 100644 --- a/phps-mode-lex-analyzer.el +++ b/phps-mode-lex-analyzer.el @@ -26,10 +26,6 @@ (require 'phps-mode-ast-bookkeeping) (require 'phps-mode-ast-imenu) -(require 'semantic) -(require 'semantic/lex) -(require 'semantic/wisent) - (require 'subr-x) @@ -88,6 +84,12 @@ (defvar-local phps-mode-lex-analyzer--parse-error nil "Non-nil means an error.") +(defvar-local phps-mode-lex-analyzer--lexer-index nil + "Index of lex-analyzer.") + +(defvar-local phps-mode-lex-analyzer--lexer-max-index nil + "Max-index of lex-analyzer.") + ;; FUNCTIONS @@ -158,52 +160,33 @@ ;; LEXERS -(define-lex-analyzer phps-mode-lex-analyzer--cached-lex-analyzer - "Return latest processed tokens or else just return one giant error token." - t - - (let ((old-start (point))) - (if phps-mode-lex-analyzer--tokens - (progn - ;; Add all updated tokens to semantic - (phps-mode-debug-message - (message - "Updating semantic lexer tokens from point %s, tokens: %s, point-max: %s" - old-start - phps-mode-lex-analyzer--tokens - (point-max))) - (dolist (token phps-mode-lex-analyzer--tokens) - (let ((start (car (cdr token))) - (end (cdr (cdr token))) - (token-name (car token))) - - ;; Apply syntax color on token - (let ((token-syntax-color - (phps-mode-lex-analyzer--get-token-syntax-color token))) - (if token-syntax-color - (phps-mode-lex-analyzer--set-region-syntax-color start end (list 'font-lock-face token-syntax-color)) - (phps-mode-lex-analyzer--clear-region-syntax-color start end))) - - (semantic-lex-push-token - (semantic-lex-token token-name start end)))) - - (setq semantic-lex-end-point (point-max))) - - (phps-mode-lex-analyzer--set-region-syntax-color - (point-min) - (point-max) - (list 'font-lock-face 'font-lock-warning-face)) - - (semantic-lex-push-token - (semantic-lex-token 'T_ERROR (point-min) (point-max)))))) - ;; If multiple rules match, re2c prefers the longest match. ;; If rules match the same string, the earlier rule has priority. ;; @see http://re2c.org/manual/syntax/syntax.html -(define-lex-analyzer phps-mode-lex-analyzer--re2c-lex-analyzer - "Elisp port of original Zend re2c lexer." - t - (phps-mode-lexer--re2c)) +(defun phps-mode-lex-analyzer--re2c-lex-analyzer () + "Run the Elisp port of original Zend re2c lexer." + (save-excursion + (while + (< + phps-mode-lex-analyzer--lexer-index + phps-mode-lex-analyzer--lexer-max-index) + (goto-char phps-mode-lex-analyzer--lexer-index) + (let ((old-index phps-mode-lex-analyzer--lexer-index)) + (phps-mode-lexer--re2c) + + (unless (or + phps-mode-lexer--generated-new-tokens + (> phps-mode-lex-analyzer--lexer-index old-index)) + (signal + 'phps-lexer-error + '(format + "Failed to lex buffer at position %S" + phps-mode-lex-analyzer--lexer-index))) + + (when phps-mode-lexer--generated-new-tokens + (setq-local + phps-mode-lex-analyzer--lexer-index + (cdr (cdr (car phps-mode-lexer--generated-new-tokens))))))))) (defun phps-mode-lex-analyzer--re2c-run (&optional force-synchronous) "Run lexer, optionally FORCE-SYNCHRONOUS." @@ -254,8 +237,10 @@ (end (cdr (cdr token)))) (let ((token-syntax-color (phps-mode-lex-analyzer--get-token-syntax-color token))) (if token-syntax-color - (phps-mode-lex-analyzer--set-region-syntax-color start end (list 'font-lock-face token-syntax-color)) - (phps-mode-lex-analyzer--clear-region-syntax-color start end))))) + (phps-mode-lex-analyzer--set-region-syntax-color + start end (list 'font-lock-face token-syntax-color)) + (phps-mode-lex-analyzer--clear-region-syntax-color + start end))))) ;; Signal parser error (if any) (when phps-mode-lex-analyzer--parse-error @@ -457,16 +442,6 @@ async async-by-process))) -(define-lex phps-mode-lex-analyzer--cached-lex - "Call lexer analyzer action." - phps-mode-lex-analyzer--cached-lex-analyzer - semantic-lex-default-action) - -(define-lex phps-mode-lex-analyzer--re2c-lex - "Call lexer analyzer action." - phps-mode-lex-analyzer--re2c-lex-analyzer - semantic-lex-default-action) - (defun phps-mode-lex-analyzer--move-states (start diff) "Move lexer states after (or equal to) START with modification DIFF." (when phps-mode-lex-analyzer--states @@ -1120,24 +1095,23 @@ (setq phps-mode-lexer--nest-location-stack nest-location-stack) - - ;; Setup lexer settings - (when (boundp 'phps-mode-syntax-table) - (setq - semantic-lex-syntax-table - phps-mode-syntax-table)) - (setq - semantic-lex-analyzer - #'phps-mode-lex-analyzer--re2c-lex) + (unless end + (setq end (point-max))) + (unless start + (setq start (point-min))) + (setq-local + phps-mode-lex-analyzer--lexer-index + start) + (setq-local + phps-mode-lex-analyzer--lexer-max-index + end) ;; Catch errors to kill generated buffer (let ((got-error t)) (unwind-protect ;; Run lexer or incremental lexer (progn - (if (and start end) - (semantic-lex start end) - (semantic-lex-buffer)) + (phps-mode-lex-analyzer--re2c-lex-analyzer) (setq got-error nil)) (when got-error (kill-buffer)))) diff --git a/phps-mode-lexer.el b/phps-mode-lexer.el index d1baf286cf..60bcc24adb 100644 --- a/phps-mode-lexer.el +++ b/phps-mode-lexer.el @@ -18,12 +18,11 @@ (require 'phps-mode-macros) -(require 'semantic) -(require 'semantic/lex) (require 'subr-x) - -(define-error 'phps-lexer-error "PHPs Lexer Error") +(define-error + 'phps-lexer-error + "PHPs Lexer Error") ;; INITIALIZE SETTINGS @@ -205,11 +204,15 @@ (defun phps-mode-lexer--move-forward (position) "Move forward to POSITION." - (setq semantic-lex-end-point position)) + (setq-local + phps-mode-lex-analyzer--lexer-index + position)) (defun phps-mode-lexer--yyless (points) "Move lexer back POINTS." - (setq semantic-lex-end-point (- semantic-lex-end-point points)) + (setq-local + phps-mode-lex-analyzer--lexer-index + (- phps-mode-lex-analyzer--lexer-index points)) (forward-char (- points))) (defun phps-mode-lexer--inline-char-handler () @@ -289,7 +292,6 @@ end token))) - (semantic-lex-push-token (semantic-lex-token token start end)) (push `(,token ,start . ,end) phps-mode-lexer--generated-tokens) (push `(,token ,start . ,end) phps-mode-lexer--generated-new-tokens) @@ -337,7 +339,9 @@ (setq start (match-beginning 0))) (unless end (setq end (match-end 0))) - (setq semantic-lex-end-point end)) + (setq-local + phps-mode-lex-analyzer--lexer-index + end)) (defmacro phps-mode-lexer--match-macro (states conditions &rest body) "Place in STATES a check for CONDITIONS to execute BODY." diff --git a/phps-mode.el b/phps-mode.el index c886631010..233e86faf2 100644 --- a/phps-mode.el +++ b/phps-mode.el @@ -1,4 +1,4 @@ -;;; phps-mode.el --- Major mode for PHP with Semantic integration -*- lexical-binding: t -*- +;;; phps-mode.el --- Major mode for PHP with code intelligence -*- lexical-binding: t -*- ;; Copyright (C) 2018-2022 Free Software Foundation, Inc. @@ -52,8 +52,6 @@ (require 'phps-mode-lex-analyzer) (require 'phps-mode-syntax-table) -(require 'semantic) - (defvar phps-mode-idle-interval 1 "Idle seconds before running the incremental lexer.") @@ -160,74 +158,89 @@ (insert new-buffer-contents))))) (define-derived-mode phps-mode prog-mode "PHPs" - "Major mode for PHP with Semantic integration." + "Major mode for PHP with code intelligence." ;; Skip comments when navigating via syntax-table - (setq-local parse-sexp-ignore-comments t) + (setq-local + parse-sexp-ignore-comments + t) ;; Font lock ;; This makes it possible to have full control over syntax coloring from the lexer - (setq-local font-lock-keywords-only nil) - (setq-local font-lock-defaults '(nil t)) + (setq-local + font-lock-keywords-only + nil) + (setq-local + font-lock-defaults + '(nil t)) ;; Flymake TODO? ;; (phps-mode-flymake-init) ;; Indentation ;; Indent-region will call this on each line of selected region - (setq-local indent-line-function #'phps-mode-indent-line) + (setq-local + indent-line-function + #'phps-mode-indent-line) ;; Custom Imenu - (setq-local imenu-create-index-function #'phps-mode-lex-analyzer--imenu-create-index) + (setq-local + imenu-create-index-function + #'phps-mode-lex-analyzer--imenu-create-index) ;; Should we follow PSR-2? (when phps-mode-use-psr-2 ;; Code MUST use an indent of 4 spaces - (setq-local tab-width 4) + (setq-local + tab-width + 4) ;; MUST NOT use tabs for indenting - (setq-local indent-tabs-mode nil)) + (setq-local + indent-tabs-mode + nil)) (when phps-mode-use-psr-12 ;; All PHP files MUST use the Unix LF (linefeed) line ending only. - (set-buffer-file-coding-system 'utf-8-unix t t) + (set-buffer-file-coding-system + 'utf-8-unix + t + t) ;; TODO There MUST NOT be trailing whitespace at the end of lines. ;; All PHP files MUST end with a non-blank line, terminated with a single LF. - (setq require-final-newline t)) + (setq-local + require-final-newline + t)) (phps-mode-lex-analyzer--reset-local-variables) ;; Make (comment-region) and (uncomment-region) work - (setq-local comment-region-function #'phps-mode-lex-analyzer--comment-region) - (setq-local uncomment-region-function #'phps-mode-lex-analyzer--uncomment-region) - (setq-local comment-start "// ") - (setq-local comment-end "") + (setq-local + comment-region-function + #'phps-mode-lex-analyzer--comment-region) + (setq-local + uncomment-region-function + #'phps-mode-lex-analyzer--uncomment-region) + (setq-local + comment-start + "// ") + (setq-local + comment-end + "") ;; Support for change detection - (add-hook 'after-change-functions #'phps-mode-lex-analyzer--after-change 0 t) - - ;; Lexer - (setq-local semantic-lex-syntax-table phps-mode-syntax-table) - - ;; Semantic - (setq-local semantic-lex-analyzer #'phps-mode-lex-analyzer--cached-lex-analyzer) - - ;; Set semantic-lex initializer function - (add-hook 'semantic-lex-reset-functions #'phps-mode-lex-analyzer--setup 0 t) + (add-hook + 'after-change-functions + #'phps-mode-lex-analyzer--after-change + 0 + t) ;; Initial run of lexer - (phps-mode-lex-analyzer--re2c-run) - - ;; Run semantic functions for new buffer - (semantic-new-buffer-fcn) - - ;; Disable idle scheduler since we have customized this feature - (when (boundp 'semantic-idle-scheduler-mode) - (setq semantic-idle-scheduler-mode nil))) + (phps-mode-lex-analyzer--re2c-run)) (provide 'phps-mode) ;;; phps-mode.el ends here diff --git a/test/phps-mode-test-ast.el b/test/phps-mode-test-ast.el index 73a33edab7..e33c0bf077 100644 --- a/test/phps-mode-test-ast.el +++ b/test/phps-mode-test-ast.el @@ -12,10 +12,11 @@ (require 'ert) (require 'phps-mode) -(require 'phps-mode-test) (require 'phps-mode-ast) (require 'phps-mode-ast-bookkeeping) (require 'phps-mode-ast-imenu) +(require 'phps-mode-lex-analyzer) +(require 'phps-mode-test) (defun phps-mode-test-ast--should-bookkeep (buffer-contents name bookkeeping) (phps-mode-test-ast--buffer-contents @@ -50,37 +51,37 @@ (buffer-substring-no-properties (point-min) (point-max))) ;; Setup lexer - (setq + (setq-local phps-mode-lexer--generated-tokens nil) - (setq + (setq-local phps-mode-lexer--state 'ST_INITIAL) - (setq + (setq-local phps-mode-lexer--states nil) - (setq + (setq-local phps-mode-lexer--state-stack nil) - (setq + (setq-local phps-mode-lexer--heredoc-label nil) - (setq + (setq-local phps-mode-lexer--heredoc-label-stack nil) - (setq + (setq-local phps-mode-lexer--nest-location-stack nil) ;; Run lexer - (setq - semantic-lex-analyzer - #'phps-mode-lex-analyzer--re2c-lex) - (setq - semantic-lex-syntax-table - phps-mode-syntax-table) - (semantic-lex-buffer) - (setq + (setq-local + phps-mode-lex-analyzer--lexer-index + (point-min)) + (setq-local + phps-mode-lex-analyzer--lexer-max-index + (point-max)) + (phps-mode-lex-analyzer--re2c-lex-analyzer) + (setq-local phps-mode-parser-tokens (phps-mode-lex-analyzer--generate-parser-tokens phps-mode-lexer--generated-tokens)) diff --git a/test/phps-mode-test-parser.el b/test/phps-mode-test-parser.el index 2c081b1e3b..390788bfeb 100644 --- a/test/phps-mode-test-parser.el +++ b/test/phps-mode-test-parser.el @@ -12,6 +12,7 @@ (require 'ert) (require 'phps-mode) +(require 'phps-mode-lex-analyzer) (defun phps-mode-test-parser--buffer-contents (buffer-contents name logic) (with-temp-buffer @@ -23,37 +24,37 @@ (buffer-substring-no-properties (point-min) (point-max))) ;; Setup lexer - (setq + (setq-local phps-mode-lexer--generated-tokens nil) - (setq + (setq-local phps-mode-lexer--state 'ST_INITIAL) - (setq + (setq-local phps-mode-lexer--states nil) - (setq + (setq-local phps-mode-lexer--state-stack nil) - (setq + (setq-local phps-mode-lexer--heredoc-label nil) - (setq + (setq-local phps-mode-lexer--heredoc-label-stack nil) - (setq + (setq-local phps-mode-lexer--nest-location-stack nil) ;; Run lexer - (setq - semantic-lex-analyzer - #'phps-mode-lex-analyzer--re2c-lex) - (setq - semantic-lex-syntax-table - phps-mode-syntax-table) - (semantic-lex-buffer) - (setq + (setq-local + phps-mode-lex-analyzer--lexer-index + (point-min)) + (setq-local + phps-mode-lex-analyzer--lexer-max-index + (point-max)) + (phps-mode-lex-analyzer--re2c-lex-analyzer) + (setq-local phps-mode-parser-tokens (phps-mode-lex-analyzer--generate-parser-tokens phps-mode-lexer--generated-tokens))