|
| 1 | +;;; solidity-flycheck.el --- Flycheck integration for solidity emacs mode |
| 2 | + |
| 3 | +;; Copyright (C) 2015-2018 Lefteris Karapetsas |
| 4 | + |
| 5 | +;; Author: Lefteris Karapetsas <lefteris@refu.co> |
| 6 | +;; Keywords: languages |
| 7 | + |
| 8 | +;; This program is free software; you can redistribute it and/or modify |
| 9 | +;; it under the terms of the GNU General Public License as published by |
| 10 | +;; the Free Software Foundation, either version 3 of the License, or |
| 11 | +;; (at your option) any later version. |
| 12 | + |
| 13 | +;; This program is distributed in the hope that it will be useful, |
| 14 | +;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | +;; GNU General Public License for more details. |
| 17 | + |
| 18 | +;; You should have received a copy of the GNU General Public License |
| 19 | +;; along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 20 | + |
| 21 | +;;; Commentary: |
| 22 | + |
| 23 | +;; flycheck integration is taken in a different file to prevent problems |
| 24 | +;; when flycheck is not present on the user's system. |
| 25 | +;; |
| 26 | +;;; Code: |
| 27 | + |
| 28 | +(require 'flycheck) |
| 29 | +(require 'solidity-common) |
| 30 | + |
| 31 | +(defvar flycheck-solidity-checker-executable) |
| 32 | +(defvar flycheck-solium-checker-executable) |
| 33 | + |
| 34 | +(defcustom solidity-flycheck-solc-checker-active nil |
| 35 | + "A boolean flag denoting if solc flycheck checker should be active." |
| 36 | + :group 'solidity |
| 37 | + :type 'boolean |
| 38 | + :safe #'booleanp |
| 39 | + :package-version '(solidity . "0.1.5")) |
| 40 | + |
| 41 | +(defcustom solidity-flycheck-chaining-error-level 'warning |
| 42 | + "The maximum error level at which chaining of checkers will happen. |
| 43 | +
|
| 44 | +This means that this is the error level for which solc checker will allow |
| 45 | +next checkers to run. By default this is the warning level. |
| 46 | +Possible values are: |
| 47 | +
|
| 48 | +`info' |
| 49 | + If any errors higher than info level are found in solc, then solium |
| 50 | + will not run. |
| 51 | +
|
| 52 | +`warning' |
| 53 | + If any errors higher than warning level are found in solc, then solium |
| 54 | + will not run. |
| 55 | +
|
| 56 | +`error' |
| 57 | + If any errors higher than error level are found in solc, then solium |
| 58 | + will not run. |
| 59 | + t |
| 60 | + Solium will always run." |
| 61 | + :group 'solidity |
| 62 | + :type '(choice (const :tag "Chain after info-error level" info) |
| 63 | + (const :tag "Chain after warning-error level" warning) |
| 64 | + (const :tag "Chain after error-error level" error) |
| 65 | + (const :tag "Always chain" t)) |
| 66 | + :package-version '(solidity . "0.1.5") |
| 67 | + :safe #'symbolp) |
| 68 | + |
| 69 | +(defcustom solidity-flycheck-solium-checker-active nil |
| 70 | + "A boolean flag denoting if solium flycheck checker should be active." |
| 71 | + :group 'solidity |
| 72 | + :type 'boolean |
| 73 | + :safe #'booleanp |
| 74 | + :package-version '(solidity . "0.1.5")) |
| 75 | + |
| 76 | +(flycheck-def-option-var flycheck-solidity-solc-addstd-contracts nil solidity-checker |
| 77 | + "Whether to add standard solidity contracts. |
| 78 | +
|
| 79 | +When non-nil, enable add also standard solidity contracts via |
| 80 | +`--add-std'." |
| 81 | + :type 'boolean |
| 82 | + :safe #'booleanp |
| 83 | + :package-version '(solidity-mode . "0.1.3")) |
| 84 | + |
| 85 | +(flycheck-def-option-var flycheck-solidity-solium-soliumrcfile nil solium-check |
| 86 | + "The path to use for soliumrc.json |
| 87 | +
|
| 88 | +The value of this variable is either a string denoting a path to the soliumrc.json |
| 89 | +or nil, to use the current directory. When non-nil, |
| 90 | +we pass the directory to solium via the `--config' option." |
| 91 | + :type '(choice (const :tag "No custom soliumrc" nil) |
| 92 | + (string :tag "Custom soliumrc file location")) |
| 93 | + :safe #'stringp |
| 94 | + :package-version '(solidity-mode . "0.1.4")) |
| 95 | + |
| 96 | +;; add a solidity mode callback to set the executable of solc for flycheck |
| 97 | +;; define solidity's flycheck syntax checker |
| 98 | +;; (let ((next-checkers-val `((,solidity-flycheck-chaining-error-level . solium-checker)))) |
| 99 | +;; (flycheck-define-checker solidity-checker |
| 100 | +;; "A Solidity syntax checker using the solc compiler" |
| 101 | +;; :command ("solc" |
| 102 | +;; (option-flag "--add-std" flycheck-solidity-solc-addstd-contracts) |
| 103 | +;; source-inplace) |
| 104 | +;; :error-patterns |
| 105 | +;; ((error line-start (file-name) ":" line ":" column ":" " Error: " (message)) |
| 106 | +;; (error line-start "Error: " (message)) |
| 107 | +;; (warning line-start (file-name) ":" line ":" column ":" " Warning: " (message))) |
| 108 | +;; :next-checkers next-checkers-val |
| 109 | +;; ;; :next-checkers `((,solidity-flycheck-chaining-error-level . solium-checker)) |
| 110 | +;; :modes solidity-mode |
| 111 | +;; :predicate (lambda () (eq major-mode 'solidity-mode)))) |
| 112 | + |
| 113 | +;; expanded the flycheck-define-checker macro as per advice given in gitter |
| 114 | +;; https://gitter.im/flycheck/flycheck?at=5a43b3a8232e79134d98872b in order to avoid the |
| 115 | +;; next-checkers `'` introduced by the flycheck-define-checker macro |
| 116 | +(progn |
| 117 | + (flycheck-def-executable-var solidity-checker "solc") |
| 118 | + (flycheck-define-command-checker 'solidity-checker "A Solidity syntax checker using the solc compiler" :command |
| 119 | + '("solc" |
| 120 | + (option-flag "--add-std" flycheck-solidity-solc-addstd-contracts) |
| 121 | + source-inplace) |
| 122 | + :error-patterns |
| 123 | + '((error line-start |
| 124 | + (file-name) |
| 125 | + ":" line ":" column ":" " Error: " |
| 126 | + (message)) |
| 127 | + (error line-start "Error: " |
| 128 | + (message)) |
| 129 | + (warning line-start |
| 130 | + (file-name) |
| 131 | + ":" line ":" column ":" " Warning: " |
| 132 | + (message))) |
| 133 | + :modes 'solidity-mode :predicate |
| 134 | + #'(lambda nil |
| 135 | + (eq major-mode 'solidity-mode)) |
| 136 | + :next-checkers |
| 137 | + `((,solidity-flycheck-chaining-error-level . solium-checker)) |
| 138 | + :standard-input 'nil :working-directory 'nil)) |
| 139 | + |
| 140 | +;; define solium flycheck syntax checker |
| 141 | +(flycheck-define-checker solium-checker |
| 142 | + "A Solidity linter using solium" |
| 143 | + :command ("solium" |
| 144 | + (option "--config=" flycheck-solidity-solium-soliumrcfile concat) |
| 145 | + "-f" |
| 146 | + source-inplace) |
| 147 | + :error-patterns |
| 148 | + ((error line-start (zero-or-more " ") line ":" column (zero-or-more " ") "error" (message)) |
| 149 | + (error line-start (zero-or-more not-newline) "[Fatal error]" (message)) |
| 150 | + (warning line-start (zero-or-more " ") line ":" column (zero-or-more " ") "warning" (message))) |
| 151 | + :error-filter |
| 152 | + ;; Add fake line numbers if they are missing in the lint output |
| 153 | + (lambda (errors) |
| 154 | + (dolist (err errors) |
| 155 | + (unless (flycheck-error-line err) |
| 156 | + (setf (flycheck-error-line err) 1))) |
| 157 | + errors) |
| 158 | + :modes solidity-mode |
| 159 | + :predicate (lambda () (eq major-mode 'solidity-mode))) |
| 160 | + |
| 161 | +;; first try to add solium to the checker's list since if we got solc |
| 162 | +;; it must come after it in the list due to it being chained after solc |
| 163 | +(when solidity-flycheck-solium-checker-active |
| 164 | + (if (file-executable-p solidity-solium-path) |
| 165 | + (progn |
| 166 | + (add-to-list 'flycheck-checkers 'solium-checker) |
| 167 | + (setq flycheck-solium-checker-executable solidity-solium-path)) |
| 168 | + (error (format "Solidity Mode Configuration error. Requested solium flycheck integration but can't find solium at: %s" solidity-solium-path)))) |
| 169 | + |
| 170 | +(when solidity-flycheck-solc-checker-active |
| 171 | + (if (file-executable-p solidity-solc-path) |
| 172 | + (progn |
| 173 | + (add-to-list 'flycheck-checkers 'solidity-checker) |
| 174 | + (add-hook 'solidity-mode-hook |
| 175 | + (lambda () |
| 176 | + (let ((solidity-command (concat solidity-solc-path))) |
| 177 | + (setq flycheck-solidity-checker-executable solidity-command))))) |
| 178 | + (error (format "Solidity Mode Configuration error. Requested solc flycheck integration but can't find solc at: %s" solidity-solc-path)))) |
| 179 | + |
| 180 | +(provide 'solidity-flycheck) |
| 181 | +;;; solidity-flycheck.el ends here |
0 commit comments