Skip to content

Commit

Permalink
[Fix #59] Provide nicer API for creating messages
Browse files Browse the repository at this point in the history
  • Loading branch information
Fuco1 committed Sep 10, 2018
1 parent d13401e commit 3e8da0c
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 109 deletions.
49 changes: 22 additions & 27 deletions elsa-analyser.el
Expand Up @@ -192,10 +192,9 @@ The BINDING should have one of the following forms:
:type (oref val type)))
(unless var
(elsa-state-add-message state
(elsa-make-warning
(format "Assigning to free variable %s"
(symbol-name (elsa-get-name place)))
place))))))
(elsa-make-warning place
"Assigning to free variable %s"
(symbol-name (elsa-get-name place))))))))
(oset form type (oref (-last-item args) type))))

(defun elsa--analyse:cond (form scope state)
Expand Down Expand Up @@ -391,11 +390,10 @@ nullables and the &rest argument into a variadic."
(if function-return-type
(unless (elsa-type-accept function-return-type body-return-type)
(elsa-state-add-message state
(elsa-make-error
(format "Function is expected to return %s but returns %s."
(elsa-type-describe function-return-type)
(elsa-type-describe body-return-type))
(elsa-car form))))
(elsa-make-error (elsa-car form)
"Function is expected to return %s but returns %s."
(elsa-type-describe function-return-type)
(elsa-type-describe body-return-type))))
;; infer the type of the function
(put name 'elsa-type (elsa-function-type
:args arg-types
Expand Down Expand Up @@ -514,21 +512,19 @@ See `elsa--analyse:defvar'."
(num-of-args (length args)))
(if (< num-of-args min)
(elsa-state-add-message state
(elsa-make-error
(format "Function `%s' expects at least %d %s but received %d"
name min
(elsa-pluralize "argument" min)
num-of-args)
head)))
(elsa-make-error head
"Function `%s' expects at least %d %s but received %d"
name min
(elsa-pluralize "argument" min)
num-of-args)))
(if (and (not (eq max 'many))
(> num-of-args max))
(elsa-state-add-message state
(elsa-make-error
(format "Function `%s' expects at most %d %s but received %d"
name max
(elsa-pluralize "argument" max)
num-of-args)
head))))
(elsa-make-error head
"Function `%s' expects at most %d %s but received %d"
name max
(elsa-pluralize "argument" max)
num-of-args))))
;; check the types
(when type
;; analyse the arguments
Expand All @@ -549,12 +545,11 @@ See `elsa--analyse:defvar'."
(unless (or (not expected)
(elsa-type-accept expected actual))
(elsa-state-add-message state
(elsa-make-error
(format "Argument %d accepts type %s but received %s"
(1+ index)
(elsa-type-describe expected)
(elsa-type-describe actual))
head)))))
(elsa-make-error head
"Argument %d accepts type %s but received %s"
(1+ index)
(elsa-type-describe expected)
(elsa-type-describe actual))))))
args
(number-sequence 0 (1- (length args)))))

Expand Down
38 changes: 18 additions & 20 deletions elsa-error.el
Expand Up @@ -68,26 +68,24 @@ In general, we recognize three states: error, warning, notice
(elsa-message-type this)
(oref this message)))

(defun elsa-make-error (message expression)
(elsa-error
:expression expression
:message message
:line (oref expression line)
:column (oref expression column)))

(defun elsa-make-warning (message expression)
(elsa-warning
:expression expression
:message message
:line (oref expression line)
:column (oref expression column)))

(defun elsa-make-notice (message expression)
(elsa-notice
:expression expression
:message message
:line (oref expression line)
:column (oref expression column)))
(defun elsa--make-message (constructor expression format args)
(funcall constructor
:expression expression
:message (apply 'format format args)
:line (oref expression line)
:column (oref expression column)))

(defun elsa-make-error (expression format &rest args)
(declare (indent 1))
(elsa--make-message 'elsa-error expression format args))

(defun elsa-make-warning (expression format &rest args)
(declare (indent 1))
(elsa--make-message 'elsa-warning expression format args))

(defun elsa-make-notice (expression format &rest args)
(declare (indent 1))
(elsa--make-message 'elsa-notice expression format args))

(provide 'elsa-error)
;;; elsa-error.el ends here
55 changes: 22 additions & 33 deletions elsa-extension-elsa.el
Expand Up @@ -28,14 +28,12 @@
(when (and (eq (elsa-get-name head) 'oref)
(eq (elsa-get-name prop) 'sequence))
(elsa-state-add-message state
(elsa-make-notice
"Prefer (elsa-car form) to (car (oref form sequence))."
(elsa-car form))))
(elsa-make-notice (elsa-car form)
"Prefer (elsa-car form) to (car (oref form sequence)).")))
(when (eq (elsa-get-name head) 'elsa-form-sequence)
(elsa-state-add-message state
(elsa-make-notice
"Prefer (elsa-car form) to (car (elsa-form-sequence form))."
(elsa-car form))))))))
(elsa-make-notice (elsa-car form)
"Prefer (elsa-car form) to (car (elsa-form-sequence form)).")))))))

(defclass elsa-check-elsa-prefer-elsa-cdr (elsa-check) ())

Expand All @@ -50,14 +48,12 @@
(when (and (eq (elsa-get-name head) 'oref)
(eq (elsa-get-name prop) 'sequence))
(elsa-state-add-message state
(elsa-make-notice
"Prefer (elsa-cdr form) to (cdr (oref form sequence))."
(elsa-car form))))
(elsa-make-notice (elsa-car form)
"Prefer (elsa-cdr form) to (cdr (oref form sequence)).")))
(when (eq (elsa-get-name head) 'elsa-form-sequence)
(elsa-state-add-message state
(elsa-make-notice
"Prefer (elsa-cdr form) to (cdr (elsa-form-sequence form))."
(elsa-car form))))))))
(elsa-make-notice (elsa-car form)
"Prefer (elsa-cdr form) to (cdr (elsa-form-sequence form)).")))))))

(defclass elsa-check-elsa-prefer-elsa-nth (elsa-check) ())

Expand All @@ -72,14 +68,12 @@
(when (and (eq (elsa-get-name head) 'oref)
(eq (elsa-get-name prop) 'sequence))
(elsa-state-add-message state
(elsa-make-notice
"Prefer (elsa-nth n form) to (nth n (oref form sequence))."
(elsa-car form))))
(elsa-make-notice (elsa-car form)
"Prefer (elsa-nth n form) to (nth n (oref form sequence)).")))
(when (eq (elsa-get-name head) 'elsa-form-sequence)
(elsa-state-add-message state
(elsa-make-notice
"Prefer (elsa-nth n form) to (nth n (elsa-form-sequence form))."
(elsa-car form))))))))
(elsa-make-notice (elsa-car form)
"Prefer (elsa-nth n form) to (nth n (elsa-form-sequence form)).")))))))

(defclass elsa-check-elsa-oref (elsa-check) ())

Expand All @@ -92,29 +86,26 @@
(let* ((prop (elsa-get-name (elsa-nth 2 form))))
(when (eq prop 'type)
(elsa-state-add-message state
(elsa-make-notice
"Prefer (elsa-get-type x) to (oref x type)."
(elsa-car form))))))
(elsa-make-notice (elsa-car form)
"Prefer (elsa-get-type x) to (oref x type).")))))

(defclass elsa-check-elsa-prefer-elsa-form-sequence (elsa-check-elsa-oref) ())

(cl-defmethod elsa-check-check ((_ elsa-check-elsa-prefer-elsa-form-sequence) form scope state)
(let* ((prop (elsa-get-name (elsa-nth 2 form))))
(when (eq prop 'sequence)
(elsa-state-add-message state
(elsa-make-notice
"Prefer (elsa-form-sequence form) to (oref form sequence)."
(elsa-car form))))))
(elsa-make-notice (elsa-car form)
"Prefer (elsa-form-sequence form) to (oref form sequence).")))))

(defclass elsa-check-elsa-prefer-elsa-get-name (elsa-check-elsa-oref) ())

(cl-defmethod elsa-check-check ((_ elsa-check-elsa-prefer-elsa-get-name) form scope state)
(let* ((prop (elsa-get-name (elsa-nth 2 form))))
(when (eq prop 'name)
(elsa-state-add-message state
(elsa-make-notice
"Prefer (elsa-get-name x) to (oref x name)."
(elsa-car form))))))
(elsa-make-notice (elsa-car form)
"Prefer (elsa-get-name x) to (oref x name).")))))

(defun elsa--analyse:elsa-make-type (form scope state)
(elsa--analyse-macro form nil scope state))
Expand All @@ -124,17 +115,15 @@
(lambda (ext)
(unless (ignore-errors (find-library-name (concat "elsa-extension-" (symbol-name (elsa-get-name ext)))))
(elsa-state-add-message state
(elsa-make-error
(format "Extension %s not found." (symbol-name (elsa-get-name ext)))
ext))))))
(elsa-make-error ext
"Extension %s not found." (symbol-name (elsa-get-name ext))))))))

(defun elsa--analyse:register-ruleset (form scope state)
(-each (elsa-cdr form)
(lambda (ruleset)
(unless (functionp (intern (concat "elsa-ruleset-" (symbol-name (elsa-get-name ruleset)))))
(elsa-state-add-message state
(elsa-make-error
(format "Ruleset %s not found." (symbol-name (elsa-get-name ruleset)))
ruleset))))))
(elsa-make-error ruleset
"Ruleset %s not found." (symbol-name (elsa-get-name ruleset))))))))

(provide 'elsa-extension-elsa)
16 changes: 8 additions & 8 deletions elsa-reader.el
Expand Up @@ -436,21 +436,21 @@ This only makes sense for the sequence forms:
(elsa-form-function-call-p reader-form 'cl-defgeneric))
(when (and state (not (eq form-name annotation-name)))
(elsa-state-add-message state
(elsa-make-warning (format "The function name `%s' and the annotation name `%s' do not match"
(symbol-name form-name)
(symbol-name annotation-name))
reader-form)))
(elsa-make-warning reader-form
"The function name `%s' and the annotation name `%s' do not match"
(symbol-name form-name)
(symbol-name annotation-name))))
(elsa-state-add-defun
state
(elsa-get-name (cadr (oref reader-form sequence)))
(eval `(elsa-make-type ,@(cddr comment-form)))))
((elsa-form-function-call-p reader-form 'defvar)
(when (and state (not (eq form-name annotation-name)))
(elsa-state-add-message state
(elsa-make-warning (format "The variable name `%s' and the annotation name `%s' do not match"
(symbol-name form-name)
(symbol-name annotation-name))
reader-form)))
(elsa-make-warning reader-form
"The variable name `%s' and the annotation name `%s' do not match"
(symbol-name form-name)
(symbol-name annotation-name))))
(put (elsa-get-name (cadr (oref reader-form sequence)))
'elsa-type-var
(eval `(elsa-make-type ,@(cddr comment-form))))))))))
Expand Down

0 comments on commit 3e8da0c

Please sign in to comment.