; Functions inspecting the nodes of the AST provided by js2-mode (defun dojo-has-node-type (node type) (and node (string= (js2-node-short-name node) type)) ) (defun dojo-get-name-from-name-node (name-node) (if (null name-node) nil (if (not (string= (js2-node-short-name name-node) "js2-name-node")) (error "Expecting a js2-name-node here. Found: %s" (js2-node-short-name name-node)) (js2-name-node-name name-node) ) ) ) (defun dojo-get-string-from-string-node (string-node) (if (not (string= (js2-node-short-name string-node) "js2-string-node")) (error "Expecting a js2-string-node here. Found: %s" (js2-node-short-name name-node)) (js2-string-node-value string-node) ) ) (defun dojo-get-value-from-number-node (number-node) (if (not (string= (js2-node-short-name number-node) "js2-number-node")) (error "Expecting a js2-number-node here. Found: %s" (js2-node-short-name number-node)) (js2-number-node-value number-node) ) ) (defun dojo-get-name-from-var-init-node (var-init-node) (let* ((target-node (js2-var-init-node-target var-init-node)) ) (cond ((dojo-has-node-type target-node "js2-name-node") (dojo-get-name-from-name-node target-node)) (t nil) ) ) ) (defun dojo-get-name-from-object-prop-left-node (left-node) (let* ((node-name (js2-node-short-name left-node)) (result (cond ((string= node-name "js2-name-node") (dojo-get-name-from-name-node left-node)) ((string= node-name "js2-string-node") (dojo-get-string-from-string-node left-node)) ((string= node-name "js2-number-node") (dojo-get-value-from-number-node left-node)) (t (log-assign 0 (format "[WARNING] Unrecognized node type for object-prop-left-node: [%s]" node-name)) nil)))) ; Get rid of some illegal characters, that make trouble in the output xml file of the corresponding class (if (string-match-p "[<>&\\-\\!\"]" result) (progn (log-assign 0 (format "[WARNING] object-prop-left-node [%s] contains illegal characters; will ignore it." result)) nil) result))) ; Note: An ancestor-path is the sequence of parents / ancestors of a given node, starting with ; the root node of the tree. Example: [js2-ast-root, js2-expr-stmt-node, js2-call-node, js2-array-node] ; for a location inside an array parameter of the outermost function call. (defun dojo-is-ancestor-of-type (ancestor-path ancestor-index type) "Returns wether the node at the given index in the given ancestor path has the given type. Returns t if this is the case, nil otherwise (or if the ancestor path isn't long enough at all)." (and (< ancestor-index (length ancestor-path)) (string= (js2-node-short-name (nth ancestor-index ancestor-path)) type))) (defun dojo-js-get-ancestor-node-name (ancestor-path ancestor-index) (if (< ancestor-index (length ancestor-path)) (js2-node-short-name (nth (nth ancestor-index ancestor-path)) type) "")) (defun dojo-is-call-expr-in-ancestor-path (ancestor-path ancestor-index &optional fct-name) "Returns wether the given ancestor-path contains a function call expression at the given ancestor-index. A function call expression consists of a js2-expr-stmt-node, followed by a js2-call-node. If the optional parameter fct-name is given, only calls to a function of this name are considered." (let* ((expr-stmt-node (nth ancestor-index ancestor-path)) (call-node (nth (1+ ancestor-index) ancestor-path)) ) (if (and (dojo-has-node-type expr-stmt-node "js2-expr-stmt-node") (dojo-has-node-type call-node "js2-call-node") ) (if fct-name ; fct-name given, check wether it matches the call node (let* ((target-node (js2-call-node-target call-node)) ) (if (dojo-has-node-type target-node "js2-name-node") ; target-node of call-node has type js2-name-node; check wether the name is equal to the given fct-name (string= (dojo-get-name-from-name-node target-node) fct-name) ; else, return nil since we don't support other node types nil ) ) ; No fct-name given, so the two checks on the node type above are sufficient t ) ; node types don't match nil ) ) ) (defun dojo-common-node-get-function-name (function-node) (dojo-get-name-from-name-node (js2-function-node-name function-node))) (defun dojo-is-nth-call-parameter-node (call-node arg-node n &optional node-type) "Returns wether the given argument node is the n-th parameter of the given call node. Passing nil as arg-node is permitted, then nil is returned. The optional node-type triggers an additional test for the additional node type." (let* ((nth-arg-node (nth n (js2-call-node-args call-node))) ) (and arg-node (or (null node-type) (string= (js2-node-short-name arg-node) node-type)) nth-arg-node (eq arg-node nth-arg-node) ) ) ) (defun dojo-js2-node-is-function-call (node name) "Returns wether the given js2 node is a js2-call-node calling a function with the given name." (if (dojo-has-node-type node "js2-call-node") (let* ((target-node (js2-call-node-target node)) ) (if (dojo-has-node-type target-node "js2-name-node") (string= (dojo-get-name-from-name-node target-node) name) nil ) ) nil ) ) (defun dojo-is-at-end-of-ancestor-path (ancestor-path ancestor-index) "Returns wether the given ancestor-index points to the very last element of the given ancestor-path." (= ancestor-index (1- (length ancestor-path))) ) (defun dojo-node-to-string (node) (with-temp-buffer (buffer-disable-undo (current-buffer)) (js2-print-tree node) (buffer-string) ) ) (provide 'dojo-common-node)