diff options
-rw-r--r-- | CHANGELOG.md | 5 | ||||
-rw-r--r-- | cider-client.el | 47 | ||||
-rw-r--r-- | cider-doc.el | 36 | ||||
-rw-r--r-- | cider-eldoc.el | 6 | ||||
-rw-r--r-- | cider-interaction.el | 59 | ||||
-rw-r--r-- | cider-stacktrace.el | 5 | ||||
-rw-r--r-- | cider-test.el | 2 | ||||
-rw-r--r-- | cider.el | 2 | ||||
-rw-r--r-- | nrepl-client.el | 428 | ||||
-rw-r--r-- | test/cider-tests.el | 48 | ||||
-rw-r--r-- | test/nrepl-bencode-tests.el | 345 |
11 files changed, 679 insertions, 304 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d440eaa..2cc3f23e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,11 @@ are used to translate filenames from/to the nREPL server (default Cygwin impleme ### Changes +* bencode decoder was rewriten: + - nREPL dicts are now plists and accessor api is given by `nrepl-dict-p`, + `nrepl-dict-get` and `nrepl-dict-put`. + - nested stack is used for decoded messages to avoid re-parsing of incomplete messages + - queues are used for incoming strings from the server and for the decoded responses * REPL buffers are now connection buffers for REPL client connections. * Server and client cranking were isolated into `nrepl-start-server-process` and `nrepl-start-client-process`. diff --git a/cider-client.el b/cider-client.el index 0c0e52f9..90f984ec 100644 --- a/cider-client.el +++ b/cider-client.el @@ -169,34 +169,17 @@ loaded." (buffer-local-value 'nrepl-repl-buffer (get-buffer (nrepl-current-connection-buffer))))) -(defun cider--dict-to-alist (val) - "Transforms a nREPL bdecoded dict VAL into an alist. -Simply returns it if it's not a dict." - (if (and (listp val) - (eq (car val) 'dict)) - (-map '-cons-to-list (cdr val)) - val)) - -(defun cider--dict-to-plist (val) - "Transforms a nREPL bdecoded dict VAL into a plist with symbol keys. -Simply returns it if it's not a dict." - (if (and (listp val) - (eq (car val) 'dict)) - (-interleave (-map 'intern (-map 'car (cdr val))) - (-map 'cdr (cdr val))) - val)) - (defun cider--var-choice (var-info) "Prompt to choose from among multiple VAR-INFO candidates, if required. This is needed only when the symbol queried is an unqualified host platform method, and multiple classes have a so-named member. If VAR-INFO does not contain a `candidates' key, it is returned as is." - (let ((candidates (cdadr (assoc "candidates" var-info)))) + (let ((candidates (nrepl-dict-get var-info "candidates"))) (if candidates - (let* ((classes (mapcar (lambda (x) (cdr (assoc "class" x))) candidates)) + (let* ((classes (nrepl-dict-keys candidates)) (choice (completing-read "Member in class: " classes nil t)) - (info (cdr (assoc choice candidates)))) - (cider--dict-to-alist info)) + (info (nrepl-dict-get candidates choice))) + info) var-info))) (defun cider-var-info (var &optional all) @@ -211,25 +194,17 @@ unless ALL is truthy." "ns" (cider-current-ns) "symbol" var)) :value))) - (if all - (cider--dict-to-alist val) - (cider--var-choice - (cider--dict-to-alist val)))))) + (if all val (cider--var-choice val))))) (defun cider-member-info (class member) "Return the CLASS MEMBER's info as an alist with list cdrs." (when (and class member) - (let ((val (plist-get (nrepl-send-sync-request - (list "op" "info" - "session" (nrepl-current-session) - "class" class - "member" member)) - :value))) - (cider--dict-to-alist val)))) - -(defun cider-get-var-attr (var-info attr) - "Return VAR-INFO's ATTR." - (cadr (assoc attr var-info))) + (plist-get (nrepl-send-sync-request + (list "op" "info" + "session" (nrepl-current-session) + "class" class + "member" member)) + :value))) (provide 'cider-client) diff --git a/cider-doc.el b/cider-doc.el index 0c126f9b..879c6d75 100644 --- a/cider-doc.el +++ b/cider-doc.el @@ -285,21 +285,21 @@ Tables are marked to be ignored by line wrap." (defun cider-docview-render-info (buffer info) "Emit into BUFFER formatted INFO for the Clojure or Java symbol." - (let* ((ns (cadr (assoc "ns" info))) - (name (cadr (assoc "name" info))) - (added (cadr (assoc "added" info))) - (depr (cadr (assoc "deprecated" info))) - (macro (cadr (assoc "macro" info))) - (special (cadr (assoc "special-form" info))) - (forms (cadr (assoc "forms-str" info))) - (args (cadr (assoc "arglists-str" info))) - (doc (cadr (assoc "doc" info))) - (url (cadr (assoc "url" info))) - (class (cadr (assoc "class" info))) - (member (cadr (assoc "member" info))) - (javadoc (cadr (assoc "javadoc" info))) - (super (cadr (assoc "super" info))) - (ifaces (cadr (assoc "interfaces" info))) + (let* ((ns (nrepl-dict-get info "ns")) + (name (nrepl-dict-get info "name")) + (added (nrepl-dict-get info "added")) + (depr (nrepl-dict-get info "deprecated")) + (macro (nrepl-dict-get info "macro")) + (special (nrepl-dict-get info "special-form")) + (forms (nrepl-dict-get info "forms-str")) + (args (nrepl-dict-get info "arglists-str")) + (doc (nrepl-dict-get info "doc")) + (url (nrepl-dict-get info "url")) + (class (nrepl-dict-get info "class")) + (member (nrepl-dict-get info "member")) + (javadoc (nrepl-dict-get info "javadoc")) + (super (nrepl-dict-get info "super")) + (ifaces (nrepl-dict-get info "interfaces")) (clj-name (if ns (concat ns "/" name) name)) (java-name (if member (concat class "/" member) class))) (with-current-buffer buffer @@ -351,14 +351,14 @@ Tables are marked to be ignored by line wrap." (newline)) (let ((beg (point-min)) (end (point-max))) - (dolist (x info) - (put-text-property beg end (car x) (cadr x))))) + (cl-loop for x on info by #'cddr + do (put-text-property beg end (car x) (cadr x))))) (current-buffer)))) (defun cider-docview-render (buffer symbol info) "Emit into BUFFER formatted documentation for SYMBOL's INFO." (with-current-buffer buffer - (let ((javadoc (cadr (assoc "javadoc" info))) + (let ((javadoc (nrepl-dict-get info "javadoc")) (inhibit-read-only t)) (cider-docview-mode) diff --git a/cider-eldoc.el b/cider-eldoc.el index 23163aac..8ab2e5f7 100644 --- a/cider-eldoc.el +++ b/cider-eldoc.el @@ -96,14 +96,14 @@ POS is the index of current argument." "Return the arglist for THING." (when (nrepl-op-supported-p "info") (let* ((var-info (cider-var-info thing t)) - (candidates (cdadr (assoc "candidates" var-info)))) + (candidates (cdr (nrepl-dict-get var-info "candidates")))) (if candidates (->> candidates - (-map (lambda (x) (cdr (assoc "arglists-str" x)))) + (-map (lambda (x) (nrepl-dict-get "arglists-str" x))) (-map 'read) -flatten -distinct) - (let ((arglists (cider-get-var-attr var-info "arglists-str"))) + (let ((arglists (nrepl-dict-get var-info "arglists-str"))) (when arglists (read arglists))))))) diff --git a/cider-interaction.el b/cider-interaction.el index 0ca4a3a5..a71c376c 100644 --- a/cider-interaction.el +++ b/cider-interaction.el @@ -176,24 +176,27 @@ Signal an error if it is not supported." "Retrieve the underlying connection's Java version." (with-current-buffer (nrepl-current-connection-buffer) (when nrepl-versions - (cdr (assoc "version-string" (assoc "java" nrepl-versions)))))) + (-> nrepl-versions + (nrepl-dict-get "java") + (nrepl-dict-get "version-string"))))) (defun cider--clojure-version () "Retrieve the underlying connection's Clojure version." (with-current-buffer (nrepl-current-connection-buffer) (when nrepl-versions - (let* ((version-dict (assoc "clojure" nrepl-versions)) - (major (cdr (assoc "major" version-dict))) - (minor (cdr (assoc "minor" version-dict))) - (incremental (cdr (assoc "incremental" version-dict)))) + (let* ((version-dict (nrepl-dict-get nrepl-versions "clojure")) + (major (nrepl-dict-get version-dict "major")) + (minor (nrepl-dict-get version-dict "minor")) + (incremental (nrepl-dict-get version-dict "incremental"))) (format "%s.%s.%s" major minor incremental))))) (defun cider--nrepl-version () "Retrieve the underlying connection's nREPL version." (with-current-buffer (nrepl-current-connection-buffer) (when nrepl-versions - (cdr (assoc "version-string" (assoc "nrepl" nrepl-versions)))))) - + (-> nrepl-versions + (nrepl-dict-get "nrepl") + (nrepl-dict-get "version-string"))))) (defun cider--check-middleware-compatibility-callback (buffer) "A callback to check if the middleware used is compatible with CIDER." @@ -670,7 +673,7 @@ existing file ending with URL has been found." not found." (cider-ensure-op-supported "info") (-when-let* ((info (cider-var-info var)) - (file (cadr (assoc "file" info)))) + (file (nrepl-dict-get info "file"))) (cider-find-file file))) (defun cider-jump-to (buffer &optional pos other-buffer) @@ -710,20 +713,20 @@ When called interactively, this operates on point." "Jump to location give by INFO. INFO object is returned by `cider-var-info' or `cider-member-info'. OTHER-BUFFER is passed to `cider-jamp-to'." - (-if-let* ((line (cadr (assoc "line" info))) - (file (cadr (assoc "file" info))) + (-if-let* ((line (nrepl-dict-get info "line")) + (file (nrepl-dict-get info "file")) (buffer (unless (cider--tooling-file-p file) (cider-find-file file)))) (cider-jump-to buffer (cons line nil) other-buffer) ;; var was created interactively and has no file info - (-if-let* ((ns (cadr (assoc "ns" info))) - (name (cadr (assoc "name" info))) - (buffer (cider-find-buffer ns)) - (pos (cider-locate-def name buffer line))) - (cider-jump-to buffer pos other-buffer) - (-if-let (name (cadr (assoc "name" info))) - (message "No location found for %s" name) - (message "No source info"))))) + (-if-let* ((ns (nrepl-dict-get info "ns")) + (name (nrepl-dict-get info "name")) + (buffer (cider-find-buffer ns)) + (pos (cider-locate-def name buffer line))) + (cider-jump-to buffer pos other-buffer) + (-if-let (name (nrepl-dict-get info "name")) + (message "No location found for %s" name) + (message "No source info"))))) (defun cider-jump-to-var (&optional var line) "Jump to the definition of VAR, optionally at a specific LINE. @@ -803,9 +806,9 @@ Currently we annotate macros, special-forms and functions, as it's not obvious from their names alone which is which." (if cider-annotate-completion-candidates (-when-let (info (cider-var-info symbol)) - (let ((macro (cadr (assoc "macro" info))) - (special (cadr (assoc "special-form" info))) - (args (cadr (assoc "arglists-str" info)))) + (let ((macro (nrepl-dict-get info "macro")) + (special (nrepl-dict-get info "special-form")) + (args (nrepl-dict-get info "arglists-str"))) (cond (macro " <m>") (special " <s>") @@ -830,8 +833,8 @@ as it's not obvious from their names alone which is which." Returns the cons of the buffer itself and the location of VAR's definition in the buffer." (-when-let* ((info (cider-var-info var)) - (file (cadr (assoc "file" info))) - (line (cadr (assoc "line" info))) + (file (nrepl-dict-get info "file")) + (line (nrepl-dict-get info "line")) (buffer (cider-find-file file))) (with-current-buffer buffer (save-excursion @@ -852,7 +855,7 @@ in the buffer." (when symbol-name (cider-ensure-op-supported "info") (let* ((info (cider-var-info symbol-name)) - (url (cadr (assoc "javadoc" info)))) + (url (nrepl-dict-get info "javadoc"))) (if url (browse-url url) (error "No Javadoc available for %s" symbol-name))))) @@ -1620,8 +1623,8 @@ under point, prompts for a var." (defun cider-grimoire-web-lookup (symbol) "Look up the grimoire documentation for SYMBOL." (-if-let (var-info (cider-var-info symbol)) - (let ((name (cider-get-var-attr var-info "name")) - (ns (cider-get-var-attr var-info "ns"))) + (let ((name (nrepl-dict-get var-info "name")) + (ns (nrepl-dict-get var-info "ns"))) ;; TODO: add a whitelist of supported namespaces (browse-url (cider-grimoire-url name ns (cider--clojure-version)))) (message "Symbol %s not resolved" symbol))) @@ -1643,8 +1646,8 @@ under point, prompts for a var." (defun cider-grimoire-lookup (symbol) "Look up the grimoire documentation for SYMBOL." (-if-let (var-info (cider-var-info symbol)) - (let ((name (cider-get-var-attr var-info "name")) - (ns (cider-get-var-attr var-info "ns")) + (let ((name (nrepl-dict-get var-info "name")) + (ns (nrepl-dict-get var-info "ns")) (url-request-method "GET") (url-request-extra-headers `(("Content-Type" . "text/plain")))) ;; TODO: add a whitelist of supported namespaces diff --git a/cider-stacktrace.el b/cider-stacktrace.el index 8127b370..2de15ff9 100644 --- a/cider-stacktrace.el +++ b/cider-stacktrace.el @@ -403,10 +403,9 @@ it wraps to 0." (method (button-get button 'method)) (info (or (and var (cider-var-info var)) (and class method (cider-member-info class method)) - `(("file" ,(button-get button 'file))))) + `(dict "file" ,(button-get button 'file)))) ;; stacktrace returns more accurate line numbers - (info (cons `("line" ,(button-get button 'line)) - info))) + (info (nrepl-dict-put info "line" (button-get button 'line)))) (cider--jump-to-loc-from-info info t))) (defun cider-stacktrace-jump () diff --git a/cider-test.el b/cider-test.el index 47311601..5f9b9d65 100644 --- a/cider-test.el +++ b/cider-test.el @@ -267,7 +267,7 @@ With the actual value, the outermost '(not ...)' s-expression is removed." "Emit into BUFFER report detail for the TEST assertion." (with-current-buffer buffer (nrepl-dbind-response test (var context type message expected actual error) - (cider-propertize-region (cider--dict-to-plist test) + (cider-propertize-region (cdr test) (cider-insert (capitalize type) (cider-test-type-face type) nil " in ") (cider-insert var 'font-lock-function-name-face t) (when context (cider-insert context 'font-lock-doc-face t)) @@ -10,7 +10,7 @@ ;; Steve Purcell <steve@sanityinc.com> ;; URL: http://www.github.com/clojure-emacs/cider ;; Version: 0.8.0-cvs -;; Package-Requires: ((clojure-mode "2.0.0") (cl-lib "0.3") (dash "2.4.1") (pkg-info "0.4") (emacs "24")) +;; Package-Requires: ((clojure-mode "2.0.0") (cl-lib "0.3") (dash "2.4.1") (pkg-info "0.4") (emacs "24") (queue "0.1.1")) ;; Keywords: languages, clojure, cider ;; This program is free software: you can redistribute it and/or modify diff --git a/nrepl-client.el b/nrepl-client.el index 0a26fd80..a987079c 100644 --- a/nrepl-client.el +++ b/nrepl-client.el @@ -8,29 +8,29 @@ ;; Bozhidar Batsov <bozhidar@batsov.com> ;; Hugo Duncan <hugo@hugoduncan.org> ;; Steve Purcell <steve@sanityinc.com> - +;; ;; 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 <http://www.gnu.org/licenses/>. - +;; ;; This file is not part of GNU Emacs. - +;; ;;; Commentary: - +;; ;; Provides an Emacs Lisp client to connect to Clojure nREPL servers. ;; ;; A connection is an abstract idea of the communication between Emacs (client) -;; and nREPL server. On Emacs side connections are represented by two running -;; processes. The two processes are the server process and client process. Each +;; and nREPL server. On Emacs side connections are represented by two running +;; processes. The two processes are the server process and client process. Each ;; of these is represented by it's own process buffer, filter and sentinel. ;; ;; The nREPL communication process can be broadly represented as follows: @@ -40,22 +40,22 @@ ;; ;; 2) Server's process filter (`nrepl-server-filter') detects the connection ;; port from the first plain text response from server and starts -;; communication process as another Emacs subprocess. This is the nREPL -;; client process (`nrepl-client-filter'). All requests and responses +;; communication process as another Emacs subprocess. This is the nREPL +;; client process (`nrepl-client-filter'). All requests and responses ;; handling happen through this client connection. ;; ;; 3) Requests are sent by `nrepl-send-request' and -;; `nrepl-send-sync-request'. Request is simply a list containing a +;; `nrepl-send-sync-request'. Request is simply a list containing a ;; requested operation name and the parameters required by the -;; operation. Each request has an associated callback that is called once -;; the response for the request has arrived. Besides the above functions +;; operation. Each request has an associated callback that is called once +;; the response for the request has arrived. Besides the above functions ;; there are specialized request senders for each type of common -;; operations. Examples are `nrepl-request:eval', `nrepl-request:clone', +;; operations. Examples are `nrepl-request:eval', `nrepl-request:clone', ;; `nrepl-request:describe'. ;; ;; 4) Responses from the server are decoded in `nrepl-client-filter' and are ;; physically represented by alists whose structure depends on the type of -;; the response. After having been decoded, the data from the response is +;; the response. After having been decoded, the data from the response is ;; passed over to the callback that was registered by the original ;; request. ;; @@ -70,6 +70,7 @@ (require 'ewoc) (require 'cl-lib) (require 'cider-util) +(require 'queue) ;;; Custom @@ -129,7 +130,7 @@ on remote connections. The arguments are dir and port. The return value should be an `plist` of the form -(:proc-buffer-name \"*buf*\" :hostname \"hostname\" :port 1234)" + (:proc-buffer-name \"*buf*\" :hostname \"hostname\" :port 1234)" :type 'function :group 'nrepl) @@ -148,7 +149,6 @@ buffer will be hidden." (defconst nrepl-connection-buffer-name-template "*nrepl-connection%s*") (defconst nrepl-server-buffer-name-template "*nrepl-server%s*") (defconst nrepl-on-connection-buffer-name-template "*nrepl-on-connection%s*") -(defconst nrepl-decoder-buffer-name-template "*nrepl-decoder%s*") (defun nrepl-format-buffer-name-template (buffer-name-template designation) "Apply the DESIGNATION to the corresponding BUFFER-NAME-TEMPLATE." @@ -200,14 +200,6 @@ PROJECT-DIR, HOST and PORT are as in `nrepl-make-buffer-name'." (nrepl-make-buffer-name nrepl-on-connection-buffer-name-template project-dir host port))) -(defun nrepl-decoder-buffer-name (&optional project-dir host port) - "Return the name of the buffer used for bencode decoding. -PROJECT-DIR, HOST and PORT are as in `nrepl-make-buffer-name'." - ;; this might go away if bdecode is rewriten by direct decoding of the sring - (nrepl--make-hidden-name - (nrepl-make-buffer-name nrepl-decoder-buffer-name-template - project-dir host port))) - ;;; Buffer Local Declarations @@ -215,7 +207,6 @@ PROJECT-DIR, HOST and PORT are as in `nrepl-make-buffer-name'." (defvar-local nrepl-connection-buffer nil) (defvar-local nrepl-server-buffer nil) (defvar-local nrepl-repl-buffer nil) -(defvar-local nrepl-decoder-buffer nil) (defvar-local nrepl-endpoint nil) (defvar-local nrepl-project-dir nil) (defvar-local nrepl-on-connection-buffer nil) @@ -250,115 +241,239 @@ To be used for tooling calls (i.e. completion, eldoc, etc)") "Version information received from the describe op.") +;;; nREPL dict + +(defun nrepl-dict-p (object) + "Return t if OBJECT is a nREPL dict." + (and (listp object) + (eq (car object) 'dict))) + +(defun nrepl-dict-get (dict key) + "Get from DICT value associated with KEY. +If dict is nil, return nil." + (when dict + (if (nrepl-dict-p dict) + (lax-plist-get (cdr dict) key) + (error "Not a nREPL dict object: %s" dict)))) + +(defun nrepl-dict-put (dict key value) + "Associate in DICT, KEY to VALUE. +Return new dict. Dict is modified by side effects." + (if (null dict) + (list 'dict key value) + (if (not (nrepl-dict-p dict)) + (error "Not a nREPL dict object: %s" dict) + (setcdr dict (lax-plist-put (cdr dict) key value)) + dict))) + +(defun nrepl-dict-keys (dict) + "Return all the keys in the nREPL dict." + (if (nrepl-dict-p dict) + (cl-loop for l on (cdr dict) by #'cddr + collect (car l)) + (error "Not a nREPL dict."))) + + +(defun nrepl--cons (car list-or-dict) + "Generic cons of CAR to LIST-OR-DICT." + (if (eq (car list-or-dict) 'dict) + (cons 'dict (cons car (cdr list-or-dict))) + (cons car list-or-dict))) + +(defun nrepl--nreverse (list-or-dict) + "Generic `nreverse' which works on LIST-OR-DICT." + (if (eq (car list-or-dict) 'dict) + (cons 'dict (nreverse (cdr list-or-dict))) + (nreverse list-or-dict))) + +(defun nrepl--push (obj stack) + "Cons OBJ to the top element of the STACK." + ;; stack is assumed to be a list + (if (eq (caar stack) 'dict) + (cons (cons 'dict (cons obj (cdar stack))) + (cdr stack)) + (cons (if (null stack) + obj + (cons obj (car stack))) + (cdr stack)))) + + ;;; Bencode -;; Adapted from http://www.emacswiki.org/emacs-en/bencode.el -;; and modified to work with utf-8 -(defun nrepl-bdecode-buffer () - "Decode a bencoded string in the current buffer starting at point." - (cond ((looking-at "i\\(-?[0-9]+\\)e") - (goto-char (match-end 0)) - (string-to-number (match-string 1))) - ((looking-at "\\([0-9]+\\):") - (goto-char (match-end 0)) - (let ((start (point)) - (end (byte-to-position (+ (position-bytes (point)) - (string-to-number (match-string 1)))))) - (goto-char end) - (buffer-substring start end))) - ((looking-at "l") - (goto-char (match-end 0)) - (let (result item) - ;; check for the end sentinel, setq returns the value - (while (not (eq :end (setq item (nrepl-bdecode-buffer)))) - (setq result (cons item result))) - (nreverse result))) - ((looking-at "d") - (goto-char (match-end 0)) - (let (dict key item) - ;; check for the end sentinel, setq returns the value - (while (not (eq :end (setq item (nrepl-bdecode-buffer)))) - (if key - (setq dict (cons (cons key item) dict) - key nil) - (unless (stringp item) - (error "Dictionary keys have to be strings: %s" item)) - (setq key item))) - (cons 'dict (nreverse dict)))) - ((looking-at "e") - (goto-char (match-end 0)) - ;; This line used to return nil and checks above checked for - ;; falsiness to indicate the end of a list/dict, but that - ;; meant that nil/() was unable to pass through without - ;; shorting the algorithm. Now we return an :end keyword - ;; as a sentinel value and check for equality. - :end) - (t - (error "Cannot decode message: %s" (buffer-substring (point-min) (point-max)))))) - -(defun nrepl-bdecode-string (str) - "Decode bencoded STR." +(cl-defstruct (nrepl-response-queue + (:include queue) + (:constructor nil) + (:constructor nrepl-response-queue (&optional stub))) + stub) + +(put 'nrepl-response-queue 'function-documentation + "Create queue object used by nREPL to store decoded server requests. +The STUB slot stores a stack of nested, incompletely parsed objects.") + +(defun nrepl--bdecode-list (&optional stack) + "Decode a bencode list or dict starting at point. +STACK is as in `nrepl--bdecode-1'." + ;; skip leading l or d + (forward-char 1) + (let* ((istack (nrepl--bdecode-1 stack)) + (pos0 (point)) + (info (car istack))) + (while (null info) + (setq istack (nrepl--bdecode-1 (cdr istack)) + pos0 (point) + info (car istack))) + (cond ((eq info :e) + (cons nil (cdr istack))) + ((eq info :stub) + (goto-char pos0) + istack) + (t istack)))) + +(defun nrepl--bdecode-1 (&optional stack) + "Decode one elementary bencode object starting at point. +Bencoded object is either list, dict, integer or string. See +http://en.wikipedia.org/wiki/Bencode#Encoding_algorithm for the encoding +rules. + +STACK is a list of so far decoded components of the current message. Car +of STACK is the innermost incompletely decoded object. The algorithm pops +this list when inner object was completely decoded or grows it by one when +new list or dict was encountered. + +The returned value is of the form (INFO . STACK) where INFO is +:stub, nil, :end or :eob and STACK is either an incomplete parsing state as +above (INFO is :stub, nil or :eob) or a list of one component representing +the completely decoded message (INFO is :end). INFO is nil when an +elementary non-root object was successfully decoded. INFO is :end when this +object is a root list or dict." + (cond + ;; list + ((eq (char-after) ?l) + (nrepl--bdecode-list (cons () stack))) + ;; dict + ((eq (char-after) ?d) + (nrepl--bdecode-list (cons '(dict) stack))) + ;; end of a list or a dict + ((eq (char-after) ?e) + (forward-char 1) + (cons (if (cdr stack) :e :end) + (nrepl--push (nrepl--nreverse (car stack)) + (cdr stack)))) + ;; string + ((looking-at "\\([0-9]+\\):") + (let ((pos0 (point)) + (beg (goto-char (match-end 0))) + (end (byte-to-position (+ (position-bytes (point)) + (string-to-number (match-string 1)))))) + (if (null end) + (progn (goto-char pos0) + (cons :stub stack)) + (goto-char end) + (cons nil (nrepl--push (buffer-substring-no-properties beg end) + stack))))) + ;; integer + ((looking-at "i\\(-?[0-9]+\\)e") + (goto-char (match-end 0)) + (cons nil (nrepl--push (string-to-number (match-string 1)) + stack))) + ;; should happen in tests only as eobp is checked in nrepl-bdecode. + ((eobp) + (cons :eob stack)) + ;; truncation in the middle of an integer or in 123: string prefix + ((looking-at "[0-9i]") + (cons :stub stack)) + ;; else, throw a quiet error + (t + (message "Invalid bencode message detected. See %s buffer." + nrepl-message-buffer-name) + (nrepl-log-message + (format "Decoder error at position %d ('%s'):" + (point) (buffer-substring (point) (min (+ (point) 10) (point-max))))) + (nrepl-log-message (buffer-string)) + (ding) + ;; Ensure loop break and clean queues' states in nrepl-bdecode: + (goto-char (point-max)) + (cons :end nil)))) + +(defun nrepl--bdecode-message (&optional stack) + "Decode one full message starting at point. +STACK is as in `nrepl--bdecode-1'. Return a cons (INFO . STACK)." + (let* ((istack (nrepl--bdecode-1 stack)) + (info (car istack)) + (stack (cdr istack))) + (while (or (null info) + (eq info :e)) + (setq istack (nrepl--bdecode-1 stack) + info (car istack) + stack (cdr istack))) + istack)) + +(defun nrepl-bdecode (string-q &optional response-q) + "Decode STRING-Q and place the results into RESPONSE-Q. +STRING-Q is either a queue of strings or a string. RESPONSE-Q is a queue of +server requests (nREPL dicts). STRING-Q and RESPONSE-Q are modified by side +effects. + +Return a cons (STRING-Q . RESPONSE-Q) where STRING-Q is the original queue +containing the remainder of the input strings which could not be +decoded. RESPONSE-Q is the original queue with successfully decoded messages +enqueued and with slot STUB containing a nested stack of an incompletely +decoded message or nil if the strings were completely decoded." (with-temp-buffer - (save-excursion - (insert str)) - (let ((result '())) - (while (not (eobp)) - (setq result (cons (nrepl-bdecode-buffer) result))) - (nreverse result)))) - -(defun nrepl-bencode-object (obj) - "Encode OBJ using bencode." + (if (queue-p string-q) + (while (queue-head string-q) + (insert (queue-dequeue string-q))) + (insert string-q) + (setq string-q (queue-create))) + (goto-char 1) + (unless response-q + (setq response-q (nrepl-response-queue))) + (let ((istack (nrepl--bdecode-message + (nrepl-response-queue-stub response-q)))) + (while (and (eq (car istack) :end) + (not (eobp))) + (queue-enqueue response-q (cadr istack)) + (setq istack (nrepl--bdecode-message))) + (unless (eobp) + (queue-enqueue string-q (buffer-substring (point) (point-max)))) + (if (not (eq (car istack) :end)) + (setf (nrepl-response-queue-stub response-q) (cdr istack)) + (queue-enqueue response-q (cadr istack)) + (setf (nrepl-response-queue-stub response-q) nil)) + (cons string-q response-q)))) + +(defun nrepl-bencode (object) + "Encode OBJECT with bencode. +Integers, lists and nrepl-dicts are treated according to bencode +specification. Everything else is encoded as string." (cond - ((integerp obj) (format "i%de" obj)) - ((listp obj) (format "l%se" (apply 'concat (-map 'nrepl-bencode-object obj)))) - (t (format "%s:%s" (string-bytes obj) obj)))) - -(defun nrepl-bencode (message) - "Encode MESSAGE with bencode." - (concat "d" (apply 'concat (mapcar 'nrepl-bencode-object message)) "e")) - -(defun nrepl-decode-current-buffer () - "Decode the data in the current buffer. -Remove the processed data from the buffer if the decode successful." - (let* ((start (point-min)) - (end (point-max)) - (data (buffer-substring-no-properties start end))) - (prog1 - (nrepl-bdecode-string data) - (delete-region start end)))) - + ((integerp object) (format "i%de" object)) + ((nrepl-dict-p object) (format "d%se" (apply 'concat (-map 'nrepl-bencode (cdr object))))) + ((listp object) (format "l%se" (apply 'concat (-map 'nrepl-bencode object)))) + (t (format "%s:%s" (string-bytes object) object)))) ;;; Client: Process Filter -;; Decoding and dispatching of the server responses happens in -;; `nrepl-client-filter'. -(defvar nrepl-decode-timeout 0.025 - "Seconds to wait before decoding nREPL output.") - -(defun nrepl-client-filter (process string) - "Decode the message(s) from PROCESS contained in STRING and dispatch." - (with-current-buffer (get-buffer-create - (buffer-local-value 'nrepl-decoder-buffer - (process-buffer process))) - (goto-char (point-max)) - (insert string) - ;; at the end of the dict? +(defun nrepl-client-filter (proc string) + "Decode message(s) from PROC contained in STRING and dispatch them." + ;; (nrepl-log-message string) + (let ((string-q (process-get proc :string-q))) + (queue-enqueue string-q string) + ;; Start decoding only if the last letter is 'e' (when (eq ?e (aref string (1- (length string)))) - ;; we are good to go if no new output came within the timeout - (unless (accept-process-output process nrepl-decode-timeout) - (let ((responses (nrepl-decode-current-buffer))) - ;; callbacks are executed in the connection buffer - (with-current-buffer (process-buffer process) - (dolist (r responses) - (nrepl--dispatch-response r)))))))) + (let ((response-q (process-get proc :response-q))) + ;; (nrepl-log-message string-q) + ;; (nrepl-log-message response-q) + (nrepl-bdecode string-q response-q) + (while (queue-head response-q) + (nrepl--dispatch-response (queue-dequeue response-q))))))) (defun nrepl--dispatch-response (response) "Dispatch the RESPONSE to associated callback. -First we check the callbacks of pending requests. If no callback was found, +First we check the callbacks of pending requests. If no callback was found, we check the completed requests, since responses could be received even for older requests with \"done\" status." - (nrepl-log-message response) (nrepl-dbind-response response (id) (let ((callback (or (gethash id nrepl-pending-requests) (gethash id nrepl-completed-requests)))) @@ -382,11 +497,11 @@ process buffer and run the hook `nrepl-disconnected-hook'." ;; `nrepl-client-sentinel'. (defun nrepl-start-client-process (&optional directory host port replp server-proc) "Create new client process identified by DIRECTORY, HOST and PORT. -If DIRECTORY is nil, use `default-directory'. If eitehr HOST or PORT are -nil, pick them from the value returned by `nrepl-connection-endpoint'. If +If DIRECTORY is nil, use `default-directory'. If eitehr HOST or PORT are +nil, pick them from the value returned by `nrepl-connection-endpoint'. If REPLP is non-nil create a client connection which is associated with a repl -buffer. When non-nil, SERVER-PROC must be a running nrepl server process -within emacs. Return the newly created client connection process." +buffer. When non-nil, SERVER-PROC must be a running nrepl server process +within Emacs. Return the newly created client connection process." (let* ((endpoint (if (functionp nrepl-connection-endpoint) (funcall nrepl-connection-endpoint directory port) (nrepl--default-endpoint directory port))) @@ -406,6 +521,9 @@ within emacs. Return the newly created client connection process." (set-process-sentinel client-proc 'nrepl-client-sentinel) (set-process-coding-system client-proc 'utf-8-unix 'utf-8-unix) + (process-put client-proc :string-q (queue-create)) + (process-put client-proc :response-q (nrepl-response-queue)) + (with-current-buffer client-buf (when server-buf (setq nrepl-project-dir (buffer-local-value 'nrepl-project-dir @@ -415,26 +533,27 @@ within emacs. Return the newly created client connection process." ;; fixme: repl and connection buffers are the same thing nrepl-connection-buffer client-buf nrepl-repl-buffer (when replp client-buf) - nrepl-on-connection-buffer proc-buffer-name - nrepl-decoder-buffer (nrepl-decoder-buffer-name directory host port))) + nrepl-on-connection-buffer proc-buffer-name)) ;; Everything is set. We are ready to send requests. (nrepl-request:clone (nrepl--new-tooling-session-handler client-proc)) (nrepl-request:clone (nrepl--new-session-handler client-proc)) (when replp - (nrepl-request:describe (nrepl--init-repl-handler client-buf t))) + (nrepl-request:describe + (nrepl--connection-buffer-init-handler client-buf t))) client-proc)) -(defun nrepl--init-repl-handler (connection-buffer replp) - "Return a handler to describe into CONNECTION-BUFFER." +(defun nrepl--connection-buffer-init-handler (conn-buffer replp) + "Return a handler to setup CONN-BUFFER as a connection buffer. +If REPLP is non-nil, also initialize it as a REPL buffer." (lambda (response) (nrepl-dbind-response response (ops versions) - (with-current-buffer connection-buffer + (with-current-buffer conn-buffer (setq nrepl-ops ops) (setq nrepl-versions versions))) (when replp - (cider-repl-init connection-buffer)) - (nrepl-make-connection-default connection-buffer) + (cider-repl-init conn-buffer)) + (nrepl-make-connection-default conn-buffer) (cider--check-required-nrepl-ops) (cider--check-middleware-compatibility))) @@ -483,9 +602,8 @@ Falls back to `nrepl-port' if not found." "Destructure an nREPL RESPONSE dict. Bind the value of the provided KEYS and execute BODY." `(let ,(cl-loop for key in keys - collect `(,key (cdr (assoc ,(format "%s" key) ,response)))) + collect `(,key (lax-plist-get (cdr ,response) ,(format "%s" key)))) ,@body)) - (put 'nrepl-dbind-response 'lisp-indent-function 2) (defvar nrepl-err-handler 'cider-default-err-handler @@ -590,7 +708,7 @@ REQUEST is a pair list of the form (\"op\" \"operation\" \"par1-name\" \"par1\" ... ). See the code of `nrepl-request:clone', `nrepl-request:stdin', etc." (let* ((request-id (nrepl-next-request-id)) - (request (append (list "id" request-id) request)) + (request (append (list 'dict "id" request-id) request)) (message (nrepl-bencode request))) (nrepl-log-message request) (puthash request-id callback nrepl-pending-requests) @@ -677,7 +795,6 @@ The result is a plist with keys :value, :stderr and :stdout." If NS is non-nil, include it in the request. SESSION defaults to current session." (nrepl-send-sync-request (nrepl--make-eval-request input ns session))) - ;;; Server @@ -741,9 +858,9 @@ Return a newly created process." (t (error "Could not start nREPL server: %s" problem))))) (defun nrepl-connection-ssh-tunnel (dir port) - "Return an endpoint for SSH tunnel to project DIR path, and PORT port. + "Return an endpoint for SSH tunnel to project DIR stack, and PORT port. If DIR is remote, then attempt to open an SSH tunnel to port. If -the ssh executable is not found on the path, then fall back to +the ssh executable is not found on the stack, then fall back to specifying a direct conneciton." ;; this abuses the -v option for ssh to get output when the port ;; forwarding is set up, which is used to synchronise on, so that @@ -809,7 +926,6 @@ Return a plist with :hostname, :port and :proc keys." (with-current-buffer (process-buffer proc) (setq nrepl-wait-for-port nil)))))) - ;;; Utilities @@ -844,7 +960,21 @@ number of buffer shrinking operations.") (re-search-forward "^(" nil t) (delete-region (point-min) (- (point) 1))) (goto-char (point-max)) - (pp msg (current-buffer))))) + (nrepl--pp msg (current-buffer))))) + +(defun nrepl--pp (object &optional stream) + "Pretty print nREPL objects." + (let ((stream (or stream standard-output))) + (if (not (nrepl-dict-p object)) + (pp object stream) + (princ "(dict\n" stream) + (cl-loop for l on (cdr object) by #'cddr + do (princ (format " %s\t%s%s" + (car l) (pp-to-string (cadr l)) + (if (cddr l) "\n" "")) + stream)) + (princ ")\n" stream)) + (if (stringp object) (princ "\n" stream)))) (defun nrepl-messages-buffer () "Return or create the buffer given by `nrepl-message-buffer-name'. @@ -862,7 +992,7 @@ The default buffer name is *nrepl-messages*." (defun nrepl-op-supported-p (op) "Return t iff the given operation OP is supported by nREPL server." (with-current-buffer (nrepl-current-connection-buffer) - (and nrepl-ops (assoc op nrepl-ops)))) + (and nrepl-ops (nrepl-dict-get nrepl-ops op)))) (defun nrepl-current-dir () "Return the directory of the current buffer." @@ -934,7 +1064,7 @@ PROJECT-DIR, HOST and PORT are as in `nrepl-make-buffer-name'." (or nrepl-connection-dispatch nrepl-connection-buffer (car (nrepl-connection-buffers)) - (error "No nREPL connection"))) + (error "No nREPL connection buffer"))) (defun nrepl-connection-buffers () "Return the connection list. @@ -968,12 +1098,10 @@ Also closes associated REPL and server buffers." (when (buffer-live-p buffer) (dolist (buf-name `(,(buffer-local-value 'nrepl-server-buffer buffer) ,(buffer-local-value 'nrepl-on-connection-buffer buffer) - ,(buffer-local-value 'nrepl-decoder-buffer buffer) ,buffer)) (when buf-name (cider--close-buffer buf-name))))))) - ;;; Connection Browser @@ -1049,11 +1177,11 @@ The connections buffer is determined by (buffer-local-value 'nrepl-project-dir buffer)) ""))))) -(defun nrepl--project-name (path) - "Extracts a project name from PATH, possibly nil. -The project name is the final component of PATH if not nil." - (when path - (file-name-nondirectory (directory-file-name path)))) +(defun nrepl--project-name (stack) + "Extracts a project name from STACK, possibly nil. +The project name is the final component of STACK if not nil." + (when stack + (file-name-nondirectory (directory-file-name stack)))) (defun nrepl--update-connections-display (ewoc connections) "Update the connections EWOC to show CONNECTIONS." diff --git a/test/cider-tests.el b/test/cider-tests.el index b7fc131f..abae19f3 100644 --- a/test/cider-tests.el +++ b/test/cider-tests.el @@ -33,7 +33,9 @@ (require 'cider) (require 'noflet) + ;;;; generic + (ert-deftest test-cider-connection-buffer-name () (setq-local nrepl-endpoint '("localhost" 1)) (let ((nrepl-hide-special-buffers nil)) @@ -68,26 +70,26 @@ (noflet ((nrepl-send-sync-request (list) `(:value (dict - ("arglists" . "([] [x] [x & ys])") - ("ns" . "clojure.core") - ("name" . "str") - ("column" . 1) - ("added" . "1.0") - ("static" . "true") - ("doc" . "stub") - ("line" . 504) - ("file" . "jar:file:/clojure-1.5.1.jar!/clojure/core.clj") - ("tag" . "class java.lang.String")) + "arglists" "([] [x] [x & ys])" + "ns" "clojure.core" + "name" "str" + "column" 1 + "added" "1.0" + "static" "true" + "doc" "stub" + "line" 504 + "file" "jar:file:/clojure-1.5.1.jar!/clojure/core.clj" + "tag" "class java.lang.String") :done t)) (nrepl-current-session () nil) (cider-current-ns () "user")) - (should (equal (cadr (assoc "doc" (cider-var-info "str"))) "stub" )) + (should (equal (nrepl-dict-get (cider-var-info "str") "doc") "stub" )) (should (not (cider-var-info ""))))) -(ert-deftest test-cider-get-var-attr () - (let ((var-info '(("doc" "var doc") ("arglists" "var arglists")))) - (should (equal (cider-get-var-attr var-info "doc") "var doc")) - (should (equal (cider-get-var-attr var-info "arglists") "var arglists")))) +(ert-deftest test-nrepl-dict-get () + (let ((var-info '(dict "doc" "var doc" "arglists" "var arglists"))) + (should (equal (nrepl-dict-get var-info "doc") "var doc")) + (should (equal (nrepl-dict-get var-info "arglists") "var arglists")))) (defmacro cider-test-with-buffers (buffer-names &rest body) (let ((create (lambda (b) (list b `(generate-new-buffer " *temp*"))))) @@ -177,6 +179,20 @@ (nrepl-connection-buffers))) (should (equal (buffer-name b) (nrepl-current-connection-buffer)))))) + +;;; response handling +(ert-deftest test-cider-dbind-response () + (should (equal '("2" "39f630b9-9545-4ea0-860e-9846681d0741" ("done")) + (nrepl-dbind-response + '(dict + "id" "2" + "new-session" "531acc73-bce4-4e77-a82b-537beeb581e9" + "session" "39f630b9-9545-4ea0-860e-9846681d0741" + "status" ("done")) + (id session status) + (list id session status))))) + + ;;; connection browser (ert-deftest test-cider-connections-buffer () @@ -539,7 +555,9 @@ (should (equal "/space test" (cider--url-to-file "file:/space%20test"))) (should (equal "C:/space test" (cider--url-to-file "file:/C:/space%20test")))) + ;;; grimoire tests + (ert-deftest cider-grimoire-replace-special () (should (equal (cider-grimoire-replace-special "isa?") "isa_QMARK")) (should (equal (cider-grimoire-replace-special "really-isa?") "really-isa_QMARK")) diff --git a/test/nrepl-bencode-tests.el b/test/nrepl-bencode-tests.el index ca6b2633..d79e5b7a 100644 --- a/test/nrepl-bencode-tests.el +++ b/test/nrepl-bencode-tests.el @@ -1,5 +1,23 @@ (require 'nrepl-client) +(defun nrepl-bdecode-string (string) + "Return first complete object in STRING. +If object is incomplete, return a decoded path." + (with-temp-buffer + (insert string) + (goto-char 1) + (cdr (nrepl--bdecode-message)))) + +(defun nrepl-bdecode-strings (&rest strings) + "Decode messages which were split across STRINGS." + (let* ((sq (make-queue)) + (rq (nrepl-response-queue)) + ipath) + (dolist (s strings) + (queue-enqueue sq s) + (nrepl-bdecode sq rq)) + (queue-head rq))) + (ert-deftest test-nrepl-bdecode-string () (should (equal '("spam") (nrepl-bdecode-string "4:spam")))) @@ -14,61 +32,108 @@ (nrepl-bdecode-string "l4:spam4:eggse")))) (ert-deftest test-nrepl-bdecode-dict () - (should (equal '((dict ("cow" . "moo") ("spam" . "eggs"))) + (should (equal '((dict "cow" "moo" "spam" "eggs")) (nrepl-bdecode-string "d3:cow3:moo4:spam4:eggse")))) +(ert-deftest test-nrepl-bdecode-list-of-ints () + (should (equal '(((dict 1 2 3 4) 5 6 (7 8))) + (nrepl-bdecode-string "ldi1ei2ei3ei4eei5ei6eli7ei8eee")))) + +(ert-deftest test-nrepl-bdecode-nils () + (should (equal '(("" nil (dict "" nil))) + (nrepl-bdecode-string "l0:led0:leee"))) + (should (equal '(("" nil (dict "" 6))) + (nrepl-bdecode-string "l0:led0:i6eee")))) + (ert-deftest test-nrepl-bdecode-nrepl-response-value () (should (equal '((dict - ("ns" . "user") - ("session" . "20c51458-911e-47ec-97c2-c509aed95b12") - ("value" . "2"))) + "ns" "user" + "session" "20c51458-911e-47ec-97c2-c509aed95b12" + "value" "2")) (nrepl-bdecode-string "d2:ns4:user7:session36:20c51458-911e-47ec-97c2-c509aed95b125:value1:2e")))) (ert-deftest test-nrepl-bdecode-nrepl-response-status () (should (equal '((dict - ("session" . "f30dbd69-7095-40c1-8e98-7873ae71a07f") - ("status" "done"))) + "session" "f30dbd69-7095-40c1-8e98-7873ae71a07f" + "status" ("done"))) (nrepl-bdecode-string "d7:session36:f30dbd69-7095-40c1-8e98-7873ae71a07f6:statusl4:doneee")))) (ert-deftest test-nrepl-bdecode-nrepl-response-err () (should (equal '((dict - ("err" . "FileNotFoundException Could not locate seesaw/core__init.class or seesaw/core.clj on classpath: clojure.lang.RT.load (RT.java:432)\n") - ("session" . "f30dbd69-7095-40c1-8e98-7873ae71a07f"))) + "err" "FileNotFoundException Could not locate seesaw/core__init.class or seesaw/core.clj on classpath: clojure.lang.RT.load (RT.java:432)\n" + "session" "f30dbd69-7095-40c1-8e98-7873ae71a07f")) (nrepl-bdecode-string -"d3:err133:FileNotFoundException Could not locate seesaw/core__init.class or seesaw/core.clj on classpath: clojure.lang.RT.load (RT.java:432)\n7:session36:f30dbd69-7095-40c1-8e98-7873ae71a07fe")))) + "d3:err133:FileNotFoundException Could not locate seesaw/core__init.class or seesaw/core.clj on classpath: clojure.lang.RT.load (RT.java:432)\n7:session36:f30dbd69-7095-40c1-8e98-7873ae71a07fe")))) (ert-deftest test-nrepl-bdecode-nrepl-response-exception () (should (equal '((dict - ("ex" . "class java.io.FileNotFoundException") - ("root-ex" . "class java.io.FileNotFoundException") - ("session" . "f30dbd69-7095-40c1-8e98-7873ae71a07f") - ("status" "eval-error"))) + "ex" "class java.io.FileNotFoundException" + "root-ex" "class java.io.FileNotFoundException" + "session" "f30dbd69-7095-40c1-8e98-7873ae71a07f" + "status" ("eval-error"))) (nrepl-bdecode-string "d2:ex35:class java.io.FileNotFoundException7:root-ex35:class java.io.FileNotFoundException7:session36:f30dbd69-7095-40c1-8e98-7873ae71a07f6:statusl10:eval-erroree")))) (ert-deftest test-nrepl-bdecode-nrepl-doc-output () - (should (equal '((dict - ("id" . "18") - ("out" . "clojure.core/reduce\n") - ("session" . "6fc999d0-3795-4d51-85fc-ccca7537ee57")) - (dict - ("id" . "18") - ("out" . "([f coll] [f val coll])\n") - ("session" . "6fc999d0-3795-4d51-85fc-ccca7537ee57")) - (dict - ("id" . "18") - ("out" . " f should be a function of 2 arguments. If val is not supplied,\n returns the result of applying f to the first 2 items in coll, then\n applying f to that result and the 3rd item, etc. If coll contains no\n items, f must accept no arguments as well, and reduce returns the\n result of calling f with no arguments. If coll has only 1 item, it\n is returned and f is not called. If val is supplied, returns the\n result of applying f to val and the first item in coll, then\n applying f to that result and the 2nd item, etc. If coll contains no\n items, returns val and f is not called.\n") - ("session" . "6fc999d0-3795-4d51-85fc-ccca7537ee57")) - (dict - ("id" . "18") - ("ns" . "user") - ("session" . "6fc999d0-3795-4d51-85fc-ccca7537ee57") - ("value" . "nil")) - (dict - ("id" . "18") - ("session" . "6fc999d0-3795-4d51-85fc-ccca7537ee57") - ("status" "done"))) - (nrepl-bdecode-string "d2:id2:183:out20:clojure.core/reduce + (should (equal '(((dict + "id" "18" + "out" "clojure.core/reduce\n" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57") + (dict + "id" "18" + "out" "([f coll] [f val coll])\n" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57") + (dict + "id" "18" + "out" " f should be a function of 2 arguments. If val is not supplied,\n returns the result of applying f to the first 2 items in coll, then\n applying f to that result and the 3rd item, etc. If coll contains no\n items, f must accept no arguments as well, and reduce returns the\n result of calling f with no arguments. If coll has only 1 item, it\n is returned and f is not called. If val is supplied, returns the\n result of applying f to val and the first item in coll, then\n applying f to that result and the 2nd item, etc. If coll contains no\n items, returns val and f is not called.\n" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57") + (dict + "id" "18" + "ns" "user" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57" + "value" "nil") + (dict + "id" "18" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57" + "status" ("done")))) + (nrepl-bdecode-string "ld2:id2:183:out20:clojure.core/reduce +7:session36:6fc999d0-3795-4d51-85fc-ccca7537ee57ed2:id2:183:out24:([f coll] [f val coll]) +7:session36:6fc999d0-3795-4d51-85fc-ccca7537ee57ed2:id2:183:out588: f should be a function of 2 arguments. If val is not supplied, + returns the result of applying f to the first 2 items in coll, then + applying f to that result and the 3rd item, etc. If coll contains no + items, f must accept no arguments as well, and reduce returns the + result of calling f with no arguments. If coll has only 1 item, it + is returned and f is not called. If val is supplied, returns the + result of applying f to val and the first item in coll, then + applying f to that result and the 2nd item, etc. If coll contains no + items, returns val and f is not called. +7:session36:6fc999d0-3795-4d51-85fc-ccca7537ee57ed2:id2:182:ns4:user7:session36:6fc999d0-3795-4d51-85fc-ccca7537ee575:value3:niled2:id2:187:session36:6fc999d0-3795-4d51-85fc-ccca7537ee576:statusl4:doneeee")))) + +(ert-deftest test-nrepl-bdecode-nrepl-doc-output-2 () + (should (equal (cons + [cl-struct-queue nil nil] + [cl-struct-nrepl-response-queue + ((dict "id" "18" + "out" "clojure.core/reduce\n" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57") + (dict "id" "18" + "out" "([f coll] [f val coll])\n" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57") + (dict "id" "18" + "out" " f should be a function of 2 arguments. If val is not supplied,\n returns the result of applying f to the first 2 items in coll, then\n applying f to that result and the 3rd item, etc. If coll contains no\n items, f must accept no arguments as well, and reduce returns the\n result of calling f with no arguments. If coll has only 1 item, it\n is returned and f is not called. If val is supplied, returns the\n result of applying f to val and the first item in coll, then\n applying f to that result and the 2nd item, etc. If coll contains no\n items, returns val and f is not called.\n" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57") + (dict "id" "18" + "ns" "user" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57" + "value" "nil") + (dict "id" "18" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57" + "status" ("done"))) + ((dict "id" "18" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57" + "status" ("done"))) + nil]) + (nrepl-bdecode "d2:id2:183:out20:clojure.core/reduce 7:session36:6fc999d0-3795-4d51-85fc-ccca7537ee57ed2:id2:183:out24:([f coll] [f val coll]) 7:session36:6fc999d0-3795-4d51-85fc-ccca7537ee57ed2:id2:183:out588: f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then @@ -82,20 +147,202 @@ 7:session36:6fc999d0-3795-4d51-85fc-ccca7537ee57ed2:id2:182:ns4:user7:session36:6fc999d0-3795-4d51-85fc-ccca7537ee575:value3:niled2:id2:187:session36:6fc999d0-3795-4d51-85fc-ccca7537ee576:statusl4:doneee")))) (ert-deftest test-nrepl-bdecode-nrepl-response-multibyte () + (should (equal '(((dict + "id" "42" + "ns" "user" + "session" "3f586403-ed47-4e4d-b8db-70522054f971" + "value" "\"←\"") + (dict + "id" "42" + "session" "3f586403-ed47-4e4d-b8db-70522054f971" + "status" ("done")))) + (nrepl-bdecode-string + "ld2:id2:422:ns4:user7:session36:3f586403-ed47-4e4d-b8db-70522054f9715:value5:\"←\"ed2:id2:427:session36:3f586403-ed47-4e4d-b8db-70522054f9716:statusl4:doneeee")))) + + +;; partial parsing + +(ert-deftest test-nrepl-bdecode-dict-partial () + (should (equal '((dict "spam" "moo" "cow")) + (nrepl-bdecode-string "d3:cow3:moo4:spam4:eg")))) + +(ert-deftest test-nrepl-bdecode-dict-partial-2 () + (should (equal '((dict "spam" "moo" "cow")) + (nrepl-bdecode-string "d3:cow3:moo4:spam4:")))) + +(ert-deftest test-nrepl-bdecode-list-of-ints-partial () + (should (equal '((6 5 (dict 1 2 3 4))) + (nrepl-bdecode-string "ldi1ei2ei3ei4eei5ei6ei")))) + +(ert-deftest test-nrepl-bdecode-split-strings () (should (equal '((dict - ("id" . "42") - ("ns" . "user") - ("session" . "3f586403-ed47-4e4d-b8db-70522054f971") - ("value" . "\"←\"")) + "ns" "user" + "session" "20c51458-911e-47ec-97c2-c509aed95b12" + "value" "2")) + (nrepl-bdecode-strings + "d2:ns4:user7:sess" + "ion36:20c51458-911e-47ec" + "-97c2-c509ae" + "d95b125:value1:2e")))) + +(ert-deftest test-nrepl-bdecode-nrepl-split-doc-output () + (should (equal '((dict + "id" "18" + "out" "clojure.core/reduce\n" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57") (dict - ("id". "42") - ("session" . "3f586403-ed47-4e4d-b8db-70522054f971") - ("status" "done"))) - (nrepl-bdecode-string - "d2:id2:422:ns4:user7:session36:3f586403-ed47-4e4d-b8db-70522054f9715:value5:\"←\"ed2:id2:427:session36:3f586403-ed47-4e4d-b8db-70522054f9716:statusl4:doneee")))) + "id" "18" + "out" "([f coll] [f val coll])\n" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57") + (dict + "id" "18" + "out" " f should be a function of 2 arguments. If val is not supplied,\n returns the result of applying f to the first 2 items in coll, then\n applying f to that result and the 3rd item, etc. If coll contains no\n items, f must accept no arguments as well, and reduce returns the\n result of calling f with no arguments. If coll has only 1 item, it\n is returned and f is not called. If val is supplied, returns the\n result of applying f to val and the first item in coll, then\n applying f to that result and the 2nd item, etc. If coll contains no\n items, returns val and f is not called.\n" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57") + (dict + "id" "18" + "ns" "user" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57" + "value" "nil") + (dict + "id" "18" + "session" "6fc999d0-3795-4d51-85fc-ccca7537ee57" + "status" ("done"))) + (nrepl-bdecode-strings "d2:id2:183:out20:clojure.core/" + "reduce +7:session36:6fc999d0-3795-4d51-85fc-ccca7537ee57ed2:id2:183:out24:([f coll] [f val coll]) +7:session36:6fc999d0-3795-4d51-85fc-ccca7537ee57ed2:id2:183:out588: f should be a function of 2 arguments. If val is not supplied, + returns the result of applying f to t" + "he first 2 items in coll, then + applying f to that result and the 3rd item, etc. If coll contains no + items, f must accept no arguments as well, and reduce returns the + result of calling f with no arguments" + ". If coll has only 1 item, it + is returned and f is not called. If val is supplied, returns the + result of applying f to val and the first item in coll, then + applying f to that result and the 2nd" + " item, etc. If coll contains no + items, returns val and f is not called. +7:session36:6fc999d0-3795-4d51-85fc-ccca7537ee57ed2:id2:182:ns4:user7:session36:6fc999d0" + "-3795-4d51-85fc-ccca7537ee575:value3:niled2:id2:187:session36:6fc999d0-3795-4d51-" + "85fc-ccca7537ee576:statusl4:doneee")))) -(ert-deftest test-nrepl-bdecode-nils () - (should (equal '(("" nil (dict ("" . nil)))) - (nrepl-bdecode-string "l0:led0:leee"))) - (should (equal '(("" nil (dict ("" . 6)))) - (nrepl-bdecode-string "l0:led0:i6eee")))) +(defvar nrepl--toString-dicts + '((dict "id" "29" "session" "9bde8b1f-aefc-4883-aa7c-9c3fa4692ac2" "value" + (dict "candidates" + (dict "clojure.lang.Compiler" (dict "arglists-str" "([this])" "argtypes" nil "class" "clojure.lang.Compiler" "file" nil "javadoc" "clojure/lang/Compiler.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) + "java.lang.AbstractMethodError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.AbstractMethodError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/AbstractMethodError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) + "java.lang.ArithmeticException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.ArithmeticException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/ArithmeticException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) + "java.lang.ArrayIndexOutOfBoundsException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.ArrayIndexOutOfBoundsException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/ArrayIndexOutOfBoundsException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) + "java.lang.ArrayStoreException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.ArrayStoreException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/ArrayStoreException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) + "java.lang.AssertionError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.AssertionError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/AssertionError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) + "java.lang.Boolean" (dict "arglists-str" "([boolean] [])" "argtypes" ("boolean") "class" "java.lang.Boolean" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html#toString(boolean)" "member" "toString" "modifiers" "#{:static :public}" "returns" "java.lang.String" "throws" nil) + "java.lang.Byte" (dict "arglists-str" "([this] [this byte])" "argtypes" nil "class" "java.lang.Byte" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Byte.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.CharSequence" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.CharSequence" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/CharSequence.html#toString()" "member" "toString" "modifiers" "#{:public :abstract}" "returns" "java.lang.String" "throws" nil) "java.lang.Character" (dict "arglists-str" "([char] [])" "argtypes" ("char") "class" "java.lang.Character" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html#toString(char)" "member" "toString" "modifiers" "#{:static :public}" "returns" "java.lang.String" "throws" nil) "java.lang.Class" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.Class" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.ClassCastException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.ClassCastException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/ClassCastException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.ClassCircularityError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.ClassCircularityError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/ClassCircularityError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.ClassFormatError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.ClassFormatError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/ClassFormatError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.ClassLoader" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.ClassLoader" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.ClassNotFoundException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.ClassNotFoundException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/ClassNotFoundException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.CloneNotSupportedException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.CloneNotSupportedException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/CloneNotSupportedException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Double" (dict "arglists-str" "([this] [this double])" "argtypes" nil "class" "java.lang.Double" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Double.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Enum" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.Enum" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.EnumConstantNotPresentException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.EnumConstantNotPresentException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/EnumConstantNotPresentException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Error" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.Error" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Error.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Exception" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.Exception" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.ExceptionInInitializerError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.ExceptionInInitializerError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/ExceptionInInitializerError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Float" (dict "arglists-str" "([float] [])" "argtypes" ("float") "class" "java.lang.Float" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Float.html#toString(float)" "member" "toString" "modifiers" "#{:static :public}" "returns" "java.lang.String" "throws" nil) "java.lang.IllegalAccessError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.IllegalAccessError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalAccessError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.IllegalAccessException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.IllegalAccessException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalAccessException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.IllegalArgumentException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.IllegalArgumentException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalArgumentException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.IllegalMonitorStateException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.IllegalMonitorStateException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalMonitorStateException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.IllegalStateException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.IllegalStateException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalStateException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.IllegalThreadStateException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.IllegalThreadStateException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalThreadStateException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.IncompatibleClassChangeError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.IncompatibleClassChangeError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/IncompatibleClassChangeError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.IndexOutOfBoundsException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.IndexOutOfBoundsException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/IndexOutOfBoundsException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.InheritableThreadLocal" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.InheritableThreadLocal" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/InheritableThreadLocal.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.InstantiationError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.InstantiationError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/InstantiationError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.InstantiationException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.InstantiationException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/InstantiationException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Integer" (dict "arglists-str" "([this] [this int] [this int int])" "argtypes" nil "class" "java.lang.Integer" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.InternalError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.InternalError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/InternalError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.InterruptedException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.InterruptedException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/InterruptedException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.LinkageError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.LinkageError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/LinkageError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Long" (dict "arglists-str" "([long int] [] [long])" "argtypes" ("long" "int") "class" "java.lang.Long" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Long.html#toString(long, int)" "member" "toString" "modifiers" "#{:static :public}" "returns" "java.lang.String" "throws" nil) "java.lang.Math" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.Math" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) + "java.lang.NegativeArraySizeException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.NegativeArraySizeException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/NegativeArraySizeException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) + "java.lang.NoClassDefFoundError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.NoClassDefFoundError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/NoClassDefFoundError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.NoSuchFieldError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.NoSuchFieldError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/NoSuchFieldError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.NoSuchFieldException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.NoSuchFieldException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/NoSuchFieldException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.NoSuchMethodError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.NoSuchMethodError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/NoSuchMethodError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.NoSuchMethodException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.NoSuchMethodException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/NoSuchMethodException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.NullPointerException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.NullPointerException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/NullPointerException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Number" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.Number" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Number.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.NumberFormatException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.NumberFormatException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Object" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.Object" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.OutOfMemoryError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.OutOfMemoryError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/OutOfMemoryError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Package" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.Package" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Package.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Process" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.Process" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.ProcessBuilder" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.ProcessBuilder" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Runtime" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.Runtime" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.RuntimeException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.RuntimeException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.RuntimePermission" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.RuntimePermission" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimePermission.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.SecurityException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.SecurityException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/SecurityException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.SecurityManager" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.SecurityManager" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/SecurityManager.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Short" (dict "arglists-str" "([short] [])" "argtypes" ("short") "class" "java.lang.Short" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Short.html#toString(short)" "member" "toString" "modifiers" "#{:static :public}" "returns" "java.lang.String" "throws" nil) "java.lang.StackOverflowError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.StackOverflowError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/StackOverflowError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.StackTraceElement" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.StackTraceElement" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/StackTraceElement.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.StrictMath" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.StrictMath" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/StrictMath.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.String" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.String" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.StringBuffer" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.StringBuffer" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html#toString()" "member" "toString" "modifiers" "#{:synchronized :public}" "returns" "java.lang.String" "throws" nil) "java.lang.StringBuilder" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.StringBuilder" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.StringIndexOutOfBoundsException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.StringIndexOutOfBoundsException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/StringIndexOutOfBoundsException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.System" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.System" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Thread" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.Thread" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Thread$State" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.Thread$State" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.State.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.ThreadDeath" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.ThreadDeath" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadDeath.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.ThreadGroup" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.ThreadGroup" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadGroup.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.ThreadLocal" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.ThreadLocal" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Throwable" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.Throwable" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.TypeNotPresentException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.TypeNotPresentException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/TypeNotPresentException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.UnknownError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.UnknownError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/UnknownError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.UnsatisfiedLinkError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.UnsatisfiedLinkError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/UnsatisfiedLinkError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.UnsupportedClassVersionError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.UnsupportedClassVersionError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/UnsupportedClassVersionError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.UnsupportedOperationException" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.UnsupportedOperationException" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/UnsupportedOperationException.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.VerifyError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.VerifyError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/VerifyError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.VirtualMachineError" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.VirtualMachineError" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/VirtualMachineError.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.lang.Void" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.lang.Void" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/lang/Void.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) "java.math.BigDecimal" (dict "arglists-str" "([this])" "argtypes" nil "class" "java.math.BigDecimal" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#toString()" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil) + "java.math.BigInteger" (dict "arglists-str" "([this int] [this])" "argtypes" ("int") "class" "java.math.BigInteger" "file" nil "javadoc" "http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#toString(int)" "member" "toString" "modifiers" "#{:public}" "returns" "java.lang.String" "throws" nil)))) + (dict "id" "29" "session" "9bde8b1f-aefc-4883-aa7c-9c3fa4692ac2" "status" ("done")))) + +(defvar nrepl--toString-strings + (list "d2:id2:297:session36:9bde8b1f-aefc-4883-aa7c-9c3fa4692ac25:valued10:candidatesd21:clojure.lang.Compilerd12:arglists-str8:([this])8:argtypesle5:class21:clojure.lang.Compiler4:filele7:javadoc37:clojure/lang/Compiler.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee29:java.lang.AbstractMethodErrord12:arglists-str8:([this])8:argtypesle5:class29:java.lang.AbstractMethodError4:filele7:javadoc86:http://docs.oracle.com/javase/7/docs/api/java/lang/AbstractMethodError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee29:java.lang.ArithmeticExceptiond12:arglists-str8:([this])8:argtypesle5:class29:java.lang.ArithmeticException4:filele7:javadoc86:http://docs.oracle.com/javase/7/docs/api/java/lang/ArithmeticException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee40:java.lang.ArrayIndexOutOfBoundsExceptiond12:arglists-str8:([this])8:argtypesle5:class40:java.lang.ArrayIndexOutOfBoundsException4:filele7:javadoc97:http://docs.oracle.com/javase/7/docs/api/java/lang/ArrayIndexOutOfBoundsException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee29:java.lang.ArrayStoreExceptiond12:arglists-str8:([this])8:argtypesle5:class29:java.lang.ArrayStoreException4:filele7:javadoc86:http://docs.oracle.com/javase/7/docs/api/java/lang/ArrayStoreException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee24:java.lang.AssertionErrord12:arglists-str8:([this])8:argtypesle5:class24:java.lang.AssertionError4:filele7:javadoc81:http://docs.oracle.com/javase/7/docs/api/java/lang/AssertionError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee17:java.lang.Booleand12:arglists-str14:([boolean] [])8:argtypesl7:booleane5:class17:java.lang.Boolean4:filele7:javadoc81:http://docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html#toString(boolean)6:member8:toString9:modifiers18:#{:static :public}7:returns16:java.lang.String6:throwslee14:java.lang.Byted12:arglists-str20:([this] [this byte])8:argtypesle5:class14:java.lang.Byte4:filele7:javadoc71:http://docs.oracle.com/javase/7/docs/api/java/lang/Byte.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee22:java.lang.CharSequenced12:arglists-str8:([this])8:argtypesle5:class22:java.lang.CharSequence4:filele7:javadoc79:http://docs.oracle.com/javase/7/docs/api/java/lang/CharSequence.html#toString()6:member8:toString9:modifiers20:#{:public :abstract}7:returns16:java.lang.String6:throwslee19:java.lang.Characterd12:arglists-str11:([char] [])8:argtypesl4:chare5:class19:java.lang.Character4:filele7:javadoc80:http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html#toString(char)6:member8:toString9:modifiers18:#{:static :public}7:returns16:java.lang.String6:throwslee15:java.lang.Classd12:arglists-str8:([this])8:argtypesle5:class15:java.lang.Class4:filele7:javadoc72:http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee28:java.lang.ClassCastExceptiond12:arglists-str8:([this])8:argtypesle5:class28:java.lang.ClassCastException4:filele7:javadoc85:http://docs.oracle.com/javase/7/docs/api/java/lang/ClassCastException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee31:java.lang.ClassCircularityErrord12:arglists-str8:([this])8:argtypesle5:class31:java.lang.ClassCircularityError4:filele7:javadoc88:http://docs.oracle.com/javase/7/docs/api/java/lang/ClassCircularityError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee26:java.lang.ClassFormatErrord12:arglists-str8:([this])8:argtypesle5:class26:java.lang.ClassFormatError4:filele7:javadoc83:http://docs.oracle.com/javase/7/docs/api/java/lang/ClassFormatError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee21:java.lang.ClassLoader" + "d12:arglists-str8:([this])8:argtypesle5:class21:java.lang.ClassLoader4:filele7:javadoc78:http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee32:java.lang.ClassNotFoundExceptiond12:arglists-str8:([this])8:argtypesle5:class32:java.lang.ClassNotFoundException4:filele7:javadoc89:http://docs.oracle.com/javase/7/docs/api/java/lang/ClassNotFoundException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee36:java.lang.CloneNotSupportedExceptiond12:arglists-str8:([this])8:argtypesle5:class36:java.lang.CloneNotSupportedException4:filele7:javadoc93:http://docs.oracle.com/javase/7/docs/api/java/lang/CloneNotSupportedException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee16:java.lang.Doubled12:arglists-str22:([this] [this double])8:argtypesle5:class16:java.lang.Double4:filele7:javadoc73:http://docs.oracle.com/javase/7/docs/api/java/lang/Double.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee14:java.lang.Enumd12:arglists-str8:([this])8:argtypesle5:class14:java.lang.Enum4:filele7:javadoc71:http://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee41:java.lang.EnumConstantNotPresentExceptiond12:arglists-str8:([this])8:argtypesle5:class41:java.lang.EnumConstantNotPresentException4:filele7:javadoc98:http://docs.oracle.com/javase/7/docs/api/java/lang/EnumConstantNotPresentException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee15:java.lang.Errord12:arglists-str8:([this])8:argtypesle5:class15:java.lang.Error4:filele7:javadoc72:http://docs.oracle.com/javase/7/docs/api/java/lang/Error.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee19:java.lang.Exceptiond12:arglists-str8:([this])8:argtypesle5:class19:java.lang.Exception4:filele7:javadoc76:http://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee37:java.lang.ExceptionInInitializerErrord12:arglists-str8:([this])8:argtypesle5:class37:java.lang.ExceptionInInitializerError4:filele7:javadoc94:http://docs.oracle.com/javase/7/docs/api/java/lang/ExceptionInInitializerError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee15:java.lang.Floatd12:arglists-str12:([float] [])8:argtypesl5:floate5:class15:java.lang.Float4:filele7:javadoc77:http://docs.oracle.com/javase/7/docs/api/java/lang/Float.html#toString(float)6:member8:toString9:modifiers18:#{:static :public}7:returns16:java.lang.String6:throwslee28:java.lang.IllegalAccessErrord12:arglists-str8:([this])8:argtypesle5:class28:java.lang.IllegalAccessError4:filele7:javadoc85:http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalAccessError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee32:java.lang.IllegalAccessExceptiond12:arglists-str8:([this])8:argtypesle5:class32:java.lang.IllegalAccessException4:filele7:javadoc89:http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalAccessException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee34:java.lang.IllegalArgumentExceptiond12:arglists-str8:([this])8:argtypesle5:class34:java.lang.IllegalArgumentException4:filele7:javadoc91:http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalArgumentException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee38:java.lang.IllegalMonitorStateExceptiond12:arglists-str8:([this])8:argtypesle5:class38:java.lang.IllegalMonitorStateException4:filele7:javadoc95:http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalMonitorStateException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee31:" + "java.lang.IllegalStateExceptiond12:arglists-str8:([this])8:argtypesle5:class31:java.lang.IllegalStateException4:filele7:javadoc88:http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalStateException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee37:java.lang.IllegalThreadStateExceptiond12:arglists-str8:([this])8:argtypesle5:class37:java.lang.IllegalThreadStateException4:filele7:javadoc94:http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalThreadStateException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee38:java.lang.IncompatibleClassChangeErrord12:arglists-str8:([this])8:argtypesle5:class38:java.lang.IncompatibleClassChangeError4:filele7:javadoc95:http://docs.oracle.com/javase/7/docs/api/java/lang/IncompatibleClassChangeError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee35:java.lang.IndexOutOfBoundsExceptiond12:arglists-str8:([this])8:argtypesle5:class35:java.lang.IndexOutOfBoundsException4:filele7:javadoc92:http://docs.oracle.com/javase/7/docs/api/java/lang/IndexOutOfBoundsException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee32:java.lang.InheritableThreadLocald12:arglists-str8:([this])8:argtypesle5:class32:java.lang.InheritableThreadLocal4:filele7:javadoc89:http://docs.oracle.com/javase/7/docs/api/java/lang/InheritableThreadLocal.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee28:java.lang.InstantiationErrord12:arglists-str8:([this])8:argtypesle5:class28:java.lang.InstantiationError4:filele7:javadoc85:http://docs.oracle.com/javase/7/docs/api/java/lang/InstantiationError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee32:java.lang.InstantiationExceptiond12:arglists-str8:([this])8:argtypesle5:class32:java.lang.InstantiationException4:filele7:javadoc89:http://docs.oracle.com/javase/7/docs/api/java/lang/InstantiationException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee17:java.lang.Integerd12:arglists-str34:([this] [this int] [this int int])8:argtypesle5:class17:java.lang.Integer4:filele7:javadoc74:http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee23:java.lang.InternalErrord12:arglists-str8:([this])8:argtypesle5:class23:java.lang.InternalError4:filele7:javadoc80:http://docs.oracle.com/javase/7/docs/api/java/lang/InternalError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee30:java.lang.InterruptedExceptiond12:arglists-str8:([this])8:argtypesle5:class30:java.lang.InterruptedException4:filele7:javadoc87:http://docs.oracle.com/javase/7/docs/api/java/lang/InterruptedException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee22:java.lang.LinkageErrord12:arglists-str8:([this])8:argtypesle5:class22:java.lang.LinkageError4:filele7:javadoc79:http://docs.oracle.com/javase/7/docs/api/java/lang/LinkageError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee14:java.lang.Longd12:arglists-str22:([long int] [] [long])8:argtypesl4:long3:inte5:class14:java.lang.Long4:filele7:javadoc80:http://docs.oracle.com/javase/7/docs/api/java/lang/Long.html#toString(long, int)6:member8:toString9:modifiers18:#{:static :public}7:returns16:java.lang.String6:throwslee14:java.lang.Mathd12:arglists-str8:([this])8:argtypesle5:class14:java.lang.Math4:filele7:javadoc71:http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee36:java.lang.NegativeArraySizeExceptiond12:arglists-str8:([this])8:argtypesle5:class36:java.lang.NegativeArraySizeException4:filele7:javadoc93:http://docs.oracle.com/javase/7/docs/api/java/lang/NegativeArraySizeException.html#toString()6:member8:toStrin" + "g9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee30:java.lang.NoClassDefFoundErrord12:arglists-str8:([this])8:argtypesle5:class30:java.lang.NoClassDefFoundError4:filele7:javadoc87:http://docs.oracle.com/javase/7/docs/api/java/lang/NoClassDefFoundError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee26:java.lang.NoSuchFieldErrord12:arglists-str8:([this])8:argtypesle5:class26:java.lang.NoSuchFieldError4:filele7:javadoc83:http://docs.oracle.com/javase/7/docs/api/java/lang/NoSuchFieldError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee30:java.lang.NoSuchFieldExceptiond12:arglists-str8:([this])8:argtypesle5:class30:java.lang.NoSuchFieldException4:filele7:javadoc87:http://docs.oracle.com/javase/7/docs/api/java/lang/NoSuchFieldException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee27:java.lang.NoSuchMethodErrord12:arglists-str8:([this])8:argtypesle5:class27:java.lang.NoSuchMethodError4:filele7:javadoc84:http://docs.oracle.com/javase/7/docs/api/java/lang/NoSuchMethodError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee31:java.lang.NoSuchMethodExceptiond12:arglists-str8:([this])8:argtypesle5:class31:java.lang.NoSuchMethodException4:filele7:javadoc88:http://docs.oracle.com/javase/7/docs/api/java/lang/NoSuchMethodException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee30:java.lang.NullPointerExceptiond12:arglists-str8:([this])8:argtypesle5:class30:java.lang.NullPointerException4:filele7:javadoc87:http://docs.oracle.com/javase/7/docs/api/java/lang/NullPointerException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee16:java.lang.Numberd12:arglists-str8:([this])8:argtypesle5:class16:java.lang.Number4:filele7:javadoc73:http://docs.oracle.com/javase/7/docs/api/java/lang/Number.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee31:java.lang.NumberFormatExceptiond12:arglists-str8:([this])8:argtypesle5:class31:java.lang.NumberFormatException4:filele7:javadoc88:http://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee16:java.lang.Objectd12:arglists-str8:([this])8:argtypesle5:class16:java.lang.Object4:filele7:javadoc73:http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee26:java.lang.OutOfMemoryErrord12:arglists-str8:([this])8:argtypesle5:class26:java.lang.OutOfMemoryError4:filele7:javadoc83:http://docs.oracle.com/javase/7/docs/api/java/lang/OutOfMemoryError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee17:java.lang.Packaged12:arglists-str8:([this])8:argtypesle5:class17:java.lang.Package4:filele7:javadoc74:http://docs.oracle.com/javase/7/docs/api/java/lang/Package.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee17:java.lang.Processd12:arglists-str8:([this])8:argtypesle5:class17:java.lang.Process4:filele7:javadoc74:http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee24:java.lang.ProcessBuilderd12:arglists-str8:([this])8:argtypesle5:class24:java.lang.ProcessBuilder4:filele7:javadoc81:http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee17:java.lang.Runtimed12:arglists-str8:([this])8:argtypesle5:class17:java.lang.Runtime4:filele7:javadoc74:http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee26:java.lang.RuntimeExceptiond12:arglists-str8:([this])8:argtypesle5:class26:" + "java.lang.RuntimeException4:filele7:javadoc83:http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee27:java.lang.RuntimePermissiond12:arglists-str8:([this])8:argtypesle5:class27:java.lang.RuntimePermission4:filele7:javadoc84:http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimePermission.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee27:java.lang.SecurityExceptiond12:arglists-str8:([this])8:argtypesle5:class27:java.lang.SecurityException4:filele7:javadoc84:http://docs.oracle.com/javase/7/docs/api/java/lang/SecurityException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee25:java.lang.SecurityManagerd12:arglists-str8:([this])8:argtypesle5:class25:java.lang.SecurityManager4:filele7:javadoc82:http://docs.oracle.com/javase/7/docs/api/java/lang/SecurityManager.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee15:java.lang.Shortd12:arglists-str12:([short] [])8:argtypesl5:shorte5:class15:java.lang.Short4:filele7:javadoc77:http://docs.oracle.com/javase/7/docs/api/java/lang/Short.html#toString(short)6:member8:toString9:modifiers18:#{:static :public}7:returns16:java.lang.String6:throwslee28:java.lang.StackOverflowErrord12:arglists-str8:([this])8:argtypesle5:class28:java.lang.StackOverflowError4:filele7:javadoc85:http://docs.oracle.com/javase/7/docs/api/java/lang/StackOverflowError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee27:java.lang.StackTraceElementd12:arglists-str8:([this])8:argtypesle5:class27:java.lang.StackTraceElement4:filele7:javadoc84:http://docs.oracle.com/javase/7/docs/api/java/lang/StackTraceElement.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee20:java.lang.StrictMathd12:arglists-str8:([this])8:argtypesle5:class20:java.lang.StrictMath4:filele7:javadoc77:http://docs.oracle.com/javase/7/docs/api/java/lang/StrictMath.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee16:java.lang.Stringd12:arglists-str8:([this])8:argtypesle5:class16:java.lang.String4:filele7:javadoc73:http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee22:java.lang.StringBufferd12:arglists-str8:([this])8:argtypesle5:class22:java.lang.StringBuffer4:filele7:javadoc79:http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html#toString()6:member8:toString9:modifiers24:#{:synchronized :public}7:returns16:java.lang.String6:throwslee23:java.lang.StringBuilderd12:arglists-str8:([this])8:argtypesle5:class23:java.lang.StringBuilder4:filele7:javadoc80:http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee41:java.lang.StringIndexOutOfBoundsExceptiond12:arglists-str8:([this])8:argtypesle5:class41:java.lang.StringIndexOutOfBoundsException4:filele7:javadoc98:http://docs.oracle.com/javase/7/docs/api/java/lang/StringIndexOutOfBoundsException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee16:java.lang.Systemd12:arglists-str8:([this])8:argtypesle5:class16:java.lang.System4:filele7:javadoc73:http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee16:java.lang.Threadd12:arglists-str8:([this])8:argtypesle5:class16:java.lang.Thread4:filele7:javadoc73:http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee22:java.lang.Thread$Stated12:arglists-str8:([this])8:argtypesle5:class22:java.lang.Thread$State4:filele7:javadoc79:http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.State.html#toString()6:member8:toString9:modifie" + "rs10:#{:public}7:returns16:java.lang.String6:throwslee21:java.lang.ThreadDeathd12:arglists-str8:([this])8:argtypesle5:class21:java.lang.ThreadDeath4:filele7:javadoc78:http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadDeath.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee21:java.lang.ThreadGroupd12:arglists-str8:([this])8:argtypesle5:class21:java.lang.ThreadGroup4:filele7:javadoc78:http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadGroup.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee21:java.lang.ThreadLocald12:arglists-str8:([this])8:argtypesle5:class21:java.lang.ThreadLocal4:filele7:javadoc78:http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee19:java.lang.Throwabled12:arglists-str8:([this])8:argtypesle5:class19:java.lang.Throwable4:filele7:javadoc76:http://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee33:java.lang.TypeNotPresentExceptiond12:arglists-str8:([this])8:argtypesle5:class33:java.lang.TypeNotPresentException4:filele7:javadoc90:http://docs.oracle.com/javase/7/docs/api/java/lang/TypeNotPresentException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee22:java.lang.UnknownErrord12:arglists-str8:([this])8:argtypesle5:class22:java.lang.UnknownError4:filele7:javadoc79:http://docs.oracle.com/javase/7/docs/api/java/lang/UnknownError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee30:java.lang.UnsatisfiedLinkErrord12:arglists-str8:([this])8:argtypesle5:class30:java.lang.UnsatisfiedLinkError4:filele7:javadoc87:http://docs.oracle.com/javase/7/docs/api/java/lang/UnsatisfiedLinkError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee38:java.lang.UnsupportedClassVersionErrord12:arglists-str8:([this])8:argtypesle5:class38:java.lang.UnsupportedClassVersionError4:filele7:javadoc95:http://docs.oracle.com/javase/7/docs/api/java/lang/UnsupportedClassVersionError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee39:java.lang.UnsupportedOperationExceptiond12:arglists-str8:([this])8:argtypesle5:class39:java.lang.UnsupportedOperationException4:filele7:javadoc96:http://docs.oracle.com/javase/7/docs/api/java/lang/UnsupportedOperationException.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee21:java.lang.VerifyErrord12:arglists-str8:([this])8:argtypesle5:class21:java.lang.VerifyError4:filele7:javadoc78:http://docs.oracle.com/javase/7/docs/api/java/lang/VerifyError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee29:java.lang.VirtualMachineErrord12:arglists-str8:([this])8:argtypesle5:class29:java.lang.VirtualMachineError4:filele7:javadoc86:http://docs.oracle.com/javase/7/docs/api/java/lang/VirtualMachineError.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee14:java.lang.Voidd12:arglists-str8:([this])8:argtypesle5:class14:java.lang.Void4:filele7:javadoc71:http://docs.oracle.com/javase/7/docs/api/java/lang/Void.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee20:java.math.BigDecimald12:arglists-str8:([this])8:argtypesle5:class20:java.math.BigDecimal4:filele7:javadoc77:http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#toString()6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwslee20:java.math.BigIntegerd12:arglists-str19:([this int] [this])8:argtypesl3:inte5:class20:java.math.BigInteger4:filele7:javadoc80:http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#toString(int)6:member8:toString9:modifiers10:#{:public}7:returns16:java.lang.String6:throwsleeeeed2:id2:297:session36:9bde8b1f-aefc-4883-aa7c-9c3f" + "a4692ac26:statusl4:doneee")) + +(ert-deftest test-nrepl-bdecode-nrepl-split-toString-doc-output () + ;; If we blow this depths, we are doing something utterly wrong: + (let ((max-lisp-eval-depth 100) + (max-specpdl-size 100)) + (should (equal nrepl--toString-dicts + (apply 'nrepl-bdecode-strings nrepl--toString-strings))))) + +(ert-deftest test-nrepl-bdecode-with-queues () + (should (equal (cons + [cl-struct-queue nil nil] + [cl-struct-nrepl-response-queue (((1 2 3) (5 6))) (((1 2 3) (5 6))) nil]) + (nrepl-bdecode "lli1ei2ei3eeli5ei6eee")))) + +(ert-deftest test-nrepl-bdecode-with-queues-partial-1 () + (should (equal (cons + [cl-struct-queue ("i6") ("i6")] + [cl-struct-nrepl-response-queue (((1 2 3) (5 6))) (((1 2 3) (5 6))) + ((5) ((1 2 3)))]) + (nrepl-bdecode "lli1ei2ei3eeli5ei6eeelli1ei2ei3eeli5ei6")))) + + +;; idempotence + +(ert-deftest test-nrepl-bencode-idempotence () + (let ((obj '(dict + "int" 1 + "int-list" (1 2 3 4 5) + "string" "f30dbd69-7095-40c1-8e98-7873ae71a07f" + "dict" (dict "k1" 1 "k2" 2 "k3" "333333") + "status" ("eval-error")))) + (should (equal obj (car (nrepl-bdecode-string (nrepl-bencode obj))))))) + + +;; nREPL dict + +(ert-deftest test-nrepl-dict () + (should (equal '(dict (23 . 44) (2 . 3) (3 . 4) (4 . 5)) + (nrepl--cons '(23 . 44) '(dict (2 . 3) (3 . 4) (4 . 5 ))))) + (should (equal '((34)) + (nrepl--push 34 '(())))) + (should (equal '(((34)) (1 2 3)) + (nrepl--push '(34) '(() (1 2 3))))) + (should (equal '((34 1)) + (nrepl--push 34 '((1))))) + (should (equal '((34 1) (2)) + (nrepl--push 34 '((1) (2))))) + (should (equal '(((34) 1) (2)) + (nrepl--push '(34) '((1) (2))))) + (should (equal '((dict 34 a b) (2)) + (nrepl--push 34 '((dict a b) (2)))))) + + +;; benchmarks + +;; (let* ((N 1000) +;; (obj '(dict +;; "int" 1 +;; "int-list" (1 2 3 4 5) +;; "string" "9 ***********************************************************************************************" +;; "dict" (dict "k1" 1 "k2" 2 "k3" "333333") +;; "status" ("eval-error"))) +;; (encoded-obj (nrepl-bencode obj)) +;; (sq (make-queue))) +;; (dotimes (i N) +;; (queue-enqueue sq encoded-obj)) +;; `((:ben-dec-string . ,(benchmark N '(nrepl-bdecode-string (nrepl-bencode obj)))) +;; (:dec-string . ,(benchmark N '(nrepl-bdecode-string encoded-obj))) +;; (:dec . ,(benchmark N '(nrepl-bdecode encoded-obj))) +;; (:deq-queue . ,(benchmark 1 '(nrepl-bdecode sq))))) +;; ;; => +;; ;; ((:ben-dec-string . "Elapsed time: 0.553346s (0.215808s in 2 GCs)") +;; ;; (:dec-string . "Elapsed time: 0.218318s (0.093480s in 1 GCs)") +;; ;; (:dec . "Elapsed time: 0.441986s (0.243365s in 2 GCs)") +;; ;; (:deq-queue . "Elapsed time: 0.271402s (0.124004s in 1 GCs)")) + + +;; (let ((N 10) +;; (sq (make-queue)) +;; (encoded-obj (apply 'concat nrepl--toString-strings))) +;; (dotimes (i N) +;; (dolist (s nrepl--toString-strings) +;; (queue-enqueue sq s))) +;; `((:dec-string . ,(benchmark N '(nrepl-bdecode-string encoded-obj))) +;; (:dec . ,(benchmark N '(nrepl-bdecode encoded-obj))) +;; (:deq-queue . ,(benchmark 1 '(nrepl-bdecode sq))))) +;; ;; => +;; ;; ((:dec-string . "Elapsed time: 0.244768s (0.132353s in 1 GCs)") +;; ;; (:dec . "Elapsed time: 0.209993s (0.131057s in 1 GCs)") +;; ;; (:deq-queue . "Elapsed time: 0.177806s (0.100122s in 1 GCs)")) + + +;; (cider-interactive-eval +;; "(time (doseq [i (range 1000)] (println \"************************************************************************\")))" +;; 1) +;; ;;; => "Elapsed time: 115.973778 msecs" (with hidden REPL buffer) |