1 | (in-package :jss) |
---|
2 | |
---|
3 | (defvar *class-to-last-component* (make-hash-table :test 'equalp)) |
---|
4 | |
---|
5 | (defclass javaparser () ((parser :accessor parser))) |
---|
6 | |
---|
7 | (defmethod initialize-instance ((p javaparser)&key) |
---|
8 | (call-next-method) |
---|
9 | (setf (parser p) (new 'javaparser))) |
---|
10 | |
---|
11 | (defmacro def-java-read (ast-class class fields &body body) |
---|
12 | (let ((jclass (find-java-class (concatenate 'string "com.github.javaparser.ast.expr." (string ast-class))))) |
---|
13 | `(progn |
---|
14 | (setf (gethash ,jclass *class-to-last-component*) ',ast-class) |
---|
15 | (defmethod ,ast-class ((obj ,class) node &optional |
---|
16 | ,@(loop for field in fields |
---|
17 | collect `(,(intern (string-upcase field)) (get-java-field node ,field t)))) |
---|
18 | ,@body)))) |
---|
19 | |
---|
20 | (defvar *object-for-this* (new 'lang.object)) |
---|
21 | |
---|
22 | (defmethod get-optional ((r javaparser) node) |
---|
23 | (if (equal node (load-time-value (#"empty" 'java.util.Optional ))) nil (#"get" node))) |
---|
24 | |
---|
25 | (defmethod process-node ((r javaparser) node) |
---|
26 | (when (jinstance-of-p node "java.util.Optional") |
---|
27 | (setq node (get-optional r node))) |
---|
28 | (when (null node) |
---|
29 | (return-from process-node nil)) |
---|
30 | (if (java-object-p node) |
---|
31 | (funcall (gethash (jobject-class node) *class-to-last-component*) r node) |
---|
32 | node)) |
---|
33 | |
---|
34 | (defmethod read-java-expression ((r javaparser) expression) |
---|
35 | `(let ((this *object-for-this*)) |
---|
36 | (declare (ignorable this)) |
---|
37 | ,(process-node r (#"getResult" (#"parseExpression" (parser r) expression))))) |
---|
38 | |
---|
39 | (def-java-read LongLiteralExpr javaparser () |
---|
40 | (read-from-string (#"replaceFirst" (#"getValue" node) "L" ""))) |
---|
41 | |
---|
42 | (def-java-read BooleanLiteralExpr javaparser () |
---|
43 | (if (equal (#"getValue" node) "true") t nil)) |
---|
44 | |
---|
45 | (def-java-read IntegerLiteralExpr javaparser nil |
---|
46 | (parse-integer (#"getValue" node))) |
---|
47 | |
---|
48 | (def-java-read DoubleLiteralExpr javaparser nil |
---|
49 | (let ((raw (#"getValue" node))) |
---|
50 | (setq raw (#"replaceAll" raw "_" "")) |
---|
51 | (if (#"matches" raw ".*[dD]$") |
---|
52 | (read-from-string (#"replaceFirst" (subseq raw 0 (1- (length raw))) "e" "d")) |
---|
53 | (if (#"matches" raw ".*[fF]$") |
---|
54 | (read-from-string (subseq raw 0 (1- (length raw)))) |
---|
55 | (read-from-string raw))))) |
---|
56 | |
---|
57 | (def-java-read CharLiteralExpr javaparser nil |
---|
58 | (#"getValue" node)) |
---|
59 | |
---|
60 | (def-java-read StringLiteralExpr javaparser nil |
---|
61 | (#"getValue" node)) |
---|
62 | |
---|
63 | (def-java-read NullLiteralExpr javaparser nil |
---|
64 | +null+) |
---|
65 | |
---|
66 | (def-java-read SimpleName javaparser () |
---|
67 | (let ((symbol (intern (#"getIdentifier" node)))) |
---|
68 | symbol)) |
---|
69 | |
---|
70 | (def-java-read NameExpr javaparser () |
---|
71 | (let ((symbol (intern (#"getIdentifier" (#"getName" node))))) |
---|
72 | symbol)) |
---|
73 | |
---|
74 | (eval-when (:compile-toplevel :load-toplevel :execute) |
---|
75 | (defun read-invoke/javaparser (stream char arg) |
---|
76 | (if (eql arg 1) |
---|
77 | (if (ignore-errors |
---|
78 | (jclass "com.github.javaparser.ParseStart")) ;; chosen randomly, TODO memoize |
---|
79 | (read-sharp-java-expression stream) |
---|
80 | ;; Deal with possiblity of not loading jar |
---|
81 | (error "Cannot load javaparser code needed for the #1 macro")) |
---|
82 | (read-invoke stream char arg))) |
---|
83 | (set-dispatch-macro-character #\# #\" 'read-invoke/javaparser)) |
---|
84 | |
---|
85 | |
---|