(require 'dojo-common-containers) (require 'dojo-core-api) (require 'dojo-core-util) (defun dojo-read-current-workspace () ; Note: This code requires the dom.el library, available at https://github.com/emacs-mirror/emacs/blob/master/lisp/dom.el ; Load it e.g. using (load-file "/home/wpausch/.emacs.d/lisp/dom/dom.el") (dojo-core-save-get-or-create-save-dir) (let* ((base-dir (concat (file-name-as-directory dojo-workspace-path) (file-name-as-directory dojo-workspace-dir))) (check-lock-result (dojo-core-load-check-lock-file base-dir)) (workspace (dojo-core-load-parse-workspace-file base-dir)) (scans (if workspace (dojo-core-load-parse-scans-file base-dir) nil)) (resource-id-to-project (if workspace (dojo-core-load-parse-resource-index base-dir) nil))) (if workspace (progn (setf (dojo-workspace-resource-id-to-project workspace) resource-id-to-project) (dojo-core-load-parse-resources-files base-dir workspace) (dolist (scan scans) (puthash (dojo-scan-id scan) scan (dojo-workspace-id-to-scan workspace))) ; Ensure consistenty regarding ids (dojo-core-util-check-resource-ids workspace) (setq dojo-current-workspace workspace)) (setq dojo-current-workspace (construct-dojo-workspace))))) (defun dojo-core-load-check-lock-file (base-dir) (let ((lock-file-name (concat base-dir "lock"))) (if (and (file-exists-p base-dir) (file-exists-p lock-file-name)) (let ((msg (concat "Workspace is already locked, either because another instance is running, or because an instance wasn't exitted properly. " "In the latter case, use dojo-core-load-repair-workspace (not yet implemented)."))) (error msg)) (write-region "" nil lock-file-name) t))) (defun dojo-core-load-parse-workspace-file (base-dir) (let ((file-name (concat base-dir "workspace.xml"))) (if (not (file-exists-p file-name)) nil (with-temp-buffer (buffer-disable-undo (current-buffer)) (insert-file-contents file-name) (let* ((workspace-node (libxml-parse-xml-region (point-min) (point-max))) (work-state (gethash (dom-attr workspace-node 'work-state) DOJO-WORKSTATE-STRING-MAP)) (last-scanned-project (dom-attr workspace-node 'last-scanned-project)) (workspace-scan-pending (dojo-core-load-convert-bool-attribute (dom-attr workspace-node 'workspace-scan-pending))) (workspace-scan-interrupted (dojo-core-load-convert-bool-attribute (dom-attr workspace-node 'workspace-scan-interrupted))) (last-scan-utcseconds (dojo-core-load-convert-number-attribute (dom-attr workspace-node 'last-scan-utcseconds))) (last-extract-own-utcseconds (dojo-core-load-convert-number-attribute (dom-attr workspace-node 'last-extract-own-utcseconds))) (last-extract-imports-utcseconds (dojo-core-load-convert-number-attribute (dom-attr workspace-node 'last-extract-imports-utcseconds))) (last-extract-referenced-utcseconds (dojo-core-load-convert-number-attribute (dom-attr workspace-node 'last-extract-referenced-utcseconds))) (last-plan-extract-utcseconds (dojo-core-load-convert-number-attribute (dom-attr workspace-node 'last-plan-extract-utcseconds))) (own-class-extraction-pending (dojo-core-load-convert-bool-attribute (dom-attr workspace-node 'own-class-extraction-pending))) (extract-imports-pending (dojo-core-load-convert-bool-attribute (dom-attr workspace-node 'extract-imports-pending))) (referenced-extraction-pending (dojo-core-load-convert-bool-attribute (dom-attr workspace-node 'referenced-extraction-pending))) (plan-extract-pending (dojo-core-load-convert-bool-attribute (dom-attr workspace-node 'plan-extract-pending))) (next-free-scan-id (dojo-core-load-convert-number-attribute (dom-attr workspace-node 'next-free-scan-id))) (next-free-project-id (dojo-core-load-convert-number-attribute (dom-attr workspace-node 'next-free-project-id))) (next-free-resource-id (dojo-core-load-convert-number-attribute (dom-attr workspace-node 'next-free-resource-id))) (next-free-class-id (dojo-core-load-convert-number-attribute (dom-attr workspace-node 'next-free-class-id))) (children (dom-children workspace-node)) (workspace (construct-dojo-workspace))) (log-workloop (format "[%s] Current workstate loaded from workspace.xml" work-state)) (setf (dojo-workspace-work-state workspace) work-state) (setf (dojo-workspace-last-scanned-project workspace) last-scanned-project) (setf (dojo-workspace-workspace-scan-pending workspace) workspace-scan-pending) (setf (dojo-workspace-workspace-scan-interrupted workspace) workspace-scan-interrupted) (setf (dojo-workspace-last-scan-utcseconds workspace) last-scan-utcseconds) (setf (dojo-workspace-last-extract-own-utcseconds workspace) last-extract-own-utcseconds) (setf (dojo-workspace-last-extract-imports-utcseconds workspace) last-extract-imports-utcseconds) (setf (dojo-workspace-last-extract-referenced-utcseconds workspace) last-extract-referenced-utcseconds) (setf (dojo-workspace-last-plan-extract-utcseconds workspace) last-plan-extract-utcseconds) (setf (dojo-workspace-own-class-extraction-pending workspace) own-class-extraction-pending) (setf (dojo-workspace-extract-imports-pending workspace) extract-imports-pending) (setf (dojo-workspace-referenced-extraction-pending workspace) referenced-extraction-pending) (setf (dojo-workspace-plan-extract-pending workspace) plan-extract-pending) (setf (dojo-workspace-next-free-scan-id workspace) (if next-free-scan-id next-free-scan-id 0)) (setf (dojo-workspace-next-free-project-id workspace) (if next-free-project-id next-free-project-id 0)) (setf (dojo-workspace-next-free-resource-id workspace) (if next-free-resource-id next-free-resource-id 0)) (setf (dojo-workspace-next-free-class-id workspace) (if next-free-class-id next-free-class-id 0)) (dolist (child children) (cond ((dojo-core-load-is-node child 'executions) (dojo-core-load-parse-executions workspace child)) ((dojo-core-load-is-node child 'projects) (dojo-core-load-parse-projects workspace child)) ; (log-load (format "After loading projects: name-to-project is %s" (dojo-workspace-name-to-project workspace))) ; (log-load (format "After loading projects: id-to-project is %s" (dojo-workspace-id-to-project workspace)))) ((dojo-core-load-is-node child 'last-scanned-tokens) (setf (dojo-workspace-last-scanned-tokens workspace) (dojo-core-load-parse-string-list child 'token))) ((dojo-core-load-is-node child 'pending-extractions) (let ((pending-extractions (dojo-core-load-parse-string-list child 'extraction))) (dolist (pending-extraction pending-extractions) ; Just puthash, as the hashtable was newly created when constructing the workspace above (puthash pending-extraction t (dojo-workspace-pending-extractions workspace))))) ((dojo-core-load-is-node child 'dirty-symbols) (let ((dirty-symbol-ids (dojo-core-load-get-attribute-list child 'dirty-symbol 'id))) (dolist (dirty-symbol-id dirty-symbol-ids) (puthash (string-to-number dirty-symbol-id) t (dojo-workspace-dirty-symbol-ids workspace))))) (t (log-load (format "[WARNING] Found unknown child node [%s] of workspace node, will ignore it." child))))) workspace))))) (defun dojo-core-load-parse-executions (workspace executions-node) (let* ((children (dom-children executions-node)) (exec-map (dojo-workspace-exec-map workspace))) (dolist (child children) (cond ((dojo-core-load-is-node child 'execution) (let* ((workstate-symbol (gethash (dom-attr child 'work-state) DOJO-WORKSTATE-STRING-MAP)) (last-exec-utcseconds (dojo-core-load-convert-number-attribute (dom-attr child 'last-exec-utcseconds))) (next-exec-utcseconds (dojo-core-load-convert-number-attribute (dom-attr child 'next-exec-utcseconds))) (workstate (gethash workstate-symbol exec-map))) (if (null workstate) (log-load (format "[WARNING] Found unsupported workstate-symbol [%s], please inspect." workstate-symbol)) (setf (dojo-workstate-last-exec-utcseconds workstate) last-exec-utcseconds) (setf (dojo-workstate-next-exec-utcseconds workstate) next-exec-utcseconds)))) (t (log-load (format "[WARNING] executions element is not of expected type 'execution, found [%s], will ignore it." child))))))) (defun dojo-core-load-parse-projects (workspace projects-node) (let* ((children (dom-children projects-node)) (id-to-project (dojo-workspace-id-to-project workspace)) (name-to-project (dojo-workspace-name-to-project workspace))) (dolist (child children) (cond ((dojo-core-load-is-node child 'project) (let* ((id (dojo-core-load-convert-number-attribute (dom-attr child 'id))) (name (dom-attr child 'name)) (is-js-dojo-project (dojo-core-load-convert-bool-attribute (dom-attr child 'is-js-dojo-project))) (pom-resource-id (dojo-core-load-convert-number-attribute (dom-attr child 'pom-resource))) (blueprint-resource-id (dojo-core-load-convert-number-attribute (dom-attr child 'blueprint-resource))) (datamodel-resource-id (dojo-core-load-convert-number-attribute (dom-attr child 'datamodel-resource))) (last-save-api-time (dojo-core-load-convert-number-attribute (dom-attr child 'last-save-api-time))) (last-save-dep-time (dojo-core-load-convert-number-attribute (dom-attr child 'last-save-dep-time))) (last-save-resources-time (dojo-core-load-convert-number-attribute (dom-attr child 'last-save-resources-time))) (project-children (dom-children child)) (project (dojo-project--create)) (locale-to-i18n-resource (dojo-project-locale-to-i18n-resource project)) (css-resources (dojo-project-css-resources project))) (setf (dojo-project-id project) id) (setf (dojo-project-name project) name) (setf (dojo-project-is-js-dojo-project project) is-js-dojo-project) (setf (dojo-project-pom-resource-id project) pom-resource-id) (setf (dojo-project-blueprint-resource-id project) blueprint-resource-id) (setf (dojo-project-datamodel-resource-id project) datamodel-resource-id) (setf (dojo-project-last-save-api-time project) last-save-api-time) (setf (dojo-project-last-save-dep-time project) last-save-dep-time) (setf (dojo-project-last-save-resources-time project) last-save-resources-time) (dolist (project-child project-children) (cond ((dojo-core-load-is-node project-child 'i18n-resources) (let* ((i18n-resources-children (dom-children project-child))) (dolist (i18n-resources-child i18n-resources-children) (cond ((dojo-core-load-is-node i18n-resources-child 'i18n-resource) (let* ((locale (dom-attr i18n-resources-child 'locale)) (resource-id (dojo-core-load-convert-number-attribute (dom-attr i18n-resources-child 'resource)))) (puthash locale resource-id locale-to-i18n-resource))))))) ; Produces a lot of misleading warnings, for empty parent nodes ; (t ; (log-load (format "[WARNING] i18n-resources-child is not of expected type 'i18n-resource, will ignore [%s]" i18n-resources-child))))))) ((dojo-core-load-is-node project-child 'css-resources) (let* ((css-resources-children (dom-children project-child))) (dolist (css-resources-child css-resources-children) (cond ((dojo-core-load-is-node css-resources-child 'css-resource) (let* ((resource-id (dojo-core-load-convert-number-attribute (dom-attr css-resources-child 'id))) (main (dojo-core-load-convert-bool-attribute (dom-attr css-resources-child 'main)))) (if main (puthash "main" resource-id css-resources) (puthash resource-id resource-id css-resources)))))))) ; Produces a lot of misleading warnings, for empty parent nodes ; (t ; (log-load (format "[WARNING] css-resources-child is not of expected type 'css-resource, will ignore [%s]" css-resources-child))))))) (t (log-load (format "[WARNING] project child is not of any expected type, expecting 'i18n-resources or 'css-resources, will ignore [%s]" project-child))))) (setf (dojo-project-locale-to-i18n-resource project) locale-to-i18n-resource) (setf (dojo-project-css-resources project) css-resources) (puthash id project id-to-project) (puthash name project name-to-project))) (t (log-load (format "[WARNING] projects element is not of expected type 'project, found [%s], will ignore it." child))))))) (defun dojo-core-load-parse-resource-index (base-dir) (let ((file-name (concat base-dir "resource-index.xml"))) (if (not (file-exists-p file-name)) (make-hash-table :test 'equal) (with-temp-buffer (buffer-disable-undo (current-buffer)) (insert-file-contents file-name) (let* ((resource-index-node (libxml-parse-xml-region (point-min) (point-max))) (children (dom-children resource-index-node)) (resource-id-to-project (make-hash-table :test 'equal))) (dolist (child children) (cond ((dojo-core-load-is-node child 'resource) (let* ((resource-id (dojo-core-load-convert-number-attribute (dom-attr child 'id))) (project (dom-attr child 'project))) (puthash resource-id project resource-id-to-project))) ((not (listp child)) ()) (t (log-load (format "[WARNING] List element is not of expected type 'resource, found [%s], will ignore it." child))))) resource-id-to-project))))) (defun dojo-core-load-parse-scans-file (base-dir) (let ((file-name (concat base-dir "scans.xml"))) (if (not (file-exists-p file-name)) nil (with-temp-buffer (buffer-disable-undo (current-buffer)) (insert-file-contents file-name) (let* ((scans-node (libxml-parse-xml-region (point-min) (point-max))) (children (dom-children scans-node)) (scans ())) (dolist (child children) (cond ((dojo-core-load-is-node child 'scan) (let* ((id (dojo-core-load-convert-number-attribute (dom-attr child 'id))) (class-id (dojo-core-load-convert-number-attribute (dom-attr child 'class))) (start-utcseconds (dojo-core-load-convert-number-attribute (dom-attr child 'start-utcseconds))) (end-utcseconds (dojo-core-load-convert-number-attribute (dom-attr child 'end-utcseconds))) (length (dojo-core-load-convert-number-attribute (dom-attr child 'length))) (discarded (dojo-core-load-convert-bool-attribute (dom-attr child 'discarded))) (scan (dojo-scan--create))) (setf (dojo-scan-id scan) id) (setf (dojo-scan-class-id scan) class-id) (setf (dojo-scan-start-utcseconds scan) start-utcseconds) (setf (dojo-scan-end-utcseconds scan) end-utcseconds) (setf (dojo-scan-length scan) length) (setf (dojo-scan-discarded scan) discarded) (push scan scans))) ((not (listp child)) ()) (t (log-load (format "[WARNING] List element is not of expected type 'scan, found [%s], will ignore it." child))))) (nreverse scans)))))) (defun dojo-core-load-parse-resources-files (base-dir workspace) (let* ((resources-dir (concat base-dir (file-name-as-directory "resources"))) (resources-project-dirs (if (file-exists-p resources-dir) (directory-files resources-dir) ())) (path-to-resources (make-hash-table :test 'equal)) (id-to-resource (make-hash-table :test 'equal))) (progn (setf (dojo-workspace-project-to-services-resource workspace) (make-hash-table :test 'equal)) (dolist (resources-project-dir resources-project-dirs) (if (not (or (string= resources-project-dir ".") (string= resources-project-dir ".."))) (let ((resources-file (concat resources-dir (file-name-as-directory resources-project-dir) "resources.xml"))) (if (file-exists-p resources-file) (progn (log-load (format "Loading resources.xml for project [%s]..." resources-project-dir)) (dojo-core-load-register-resources resources-file id-to-resource path-to-resources nil workspace resources-project-dir) (log-load "... done."))) ; Detect, and process the special case, that workspace scan was interrupted ; by exiting dojo-minor-mode inside a project. Then, we have a curr_scan_resources.xml ; file we additionally need to process here. (let* ((workspace-scan-pending (dojo-workspace-workspace-scan-pending workspace)) (last-scanned-project (dojo-workspace-last-scanned-project workspace)) (last-scanned-tokens (dojo-workspace-last-scanned-tokens workspace))) (if (and workspace-scan-pending (string= last-scanned-project resources-project-dir) last-scanned-tokens) (let ((curr-scan-resources-file (concat resources-dir (file-name-as-directory resources-project-dir) "curr_scan_resources.xml"))) (if (file-exists-p curr-scan-resources-file) (progn (log-load (format "Loading curr_scan_resources.xml for project [%s]..." last-scanned-project)) (dojo-core-load-register-resources curr-scan-resources-file id-to-resource path-to-resources t workspace resources-project-dir) (delete-file curr-scan-resources-file) (log-load "... done."))))))))) (setf (dojo-workspace-path-to-resources workspace) path-to-resources) (setf (dojo-workspace-id-to-resource workspace) id-to-resource)))) ; (dojo-core-workspace-derive-css-files workspace)))) (defun dojo-core-load-register-resources (resources-file id-to-resource path-to-resources &optional process-curr-scan-project-resources workspace project) ; TODO: Check resource-index.xml, in order to remove all entries that do not longer exist; add similar code to workspace scan (if (file-exists-p resources-file) (with-temp-buffer (buffer-disable-undo (current-buffer)) (insert-file-contents resources-file) (let* ((resources-node (libxml-parse-xml-region (point-min) (point-max))) (children (dom-children resources-node)) (curr-scan-project-resources nil) (resource-id-to-project (dojo-workspace-resource-id-to-project workspace)) (total-js-extract-time (dojo-workspace-total-js-extract-time workspace)) (total-js-extract-size (dojo-workspace-total-js-extract-size workspace)) (total-js-extract-count (dojo-workspace-total-js-extract-count workspace))) (dolist (child children) (cond ((dojo-core-load-is-node child 'resource) (let* ((id (dojo-core-load-convert-number-attribute (dom-attr child 'id))) (state (dom-attr child 'state)) (last-located-utc-seconds (dojo-core-load-convert-number-attribute (dom-attr child 'last-located-utc-seconds))) (last-parsed-utc-seconds (dojo-core-load-convert-number-attribute (dom-attr child 'last-parsed-utc-seconds))) (last-parsed-size (dojo-core-load-convert-number-attribute (dom-attr child 'last-parsed-size))) (last-ast-time (dojo-core-load-convert-number-attribute (dom-attr child 'last-ast-time))) (last-parse-time (dojo-core-load-convert-number-attribute (dom-attr child 'last-parse-time))) (file-hash (dom-attr child 'file-hash)) (last-scan-id (dojo-core-load-convert-number-attribute (dom-attr child 'last-scan-id))) (type (dom-attr child 'type)) (class-id (dojo-core-load-convert-number-attribute (dom-attr child 'class-id))) (project (dom-attr child 'project)) (path (dom-attr child 'path)) (file-path (dom-attr child 'file-path)) (priority (dojo-core-load-convert-number-attribute (dom-attr child 'prio))) (priority-count (dojo-core-load-convert-number-attribute (dom-attr child 'prio-count))) (resource (dojo-resource--create)) (resources (gethash path path-to-resources))) (if (not (null (gethash id id-to-resource))) (progn (log-load (format "[WARNING] Registering resource [%s] for the second time, resource ids seem to be inconsistent, case needs to be handled.")))) (setf (dojo-resource-id resource) id) (setf (dojo-resource-state resource) state) (setf (dojo-resource-last-located-utc-seconds resource) last-located-utc-seconds) (setf (dojo-resource-last-parsed-utc-seconds resource) last-parsed-utc-seconds) (setf (dojo-resource-last-parsed-size resource) last-parsed-size) (setf (dojo-resource-last-ast-time resource) last-ast-time) (setf (dojo-resource-last-parse-time resource) last-parse-time) (setf (dojo-resource-file-hash resource) file-hash) (setf (dojo-resource-last-scan-id resource) last-scan-id) (setf (dojo-resource-type resource) type) (setf (dojo-resource-parsed-id resource) class-id) (setf (dojo-resource-project resource) project) (setf (dojo-resource-path resource) path) (setf (dojo-resource-file-path resource) file-path) (if (and (not (null last-ast-time)) (not (null last-parse-time)) (not (null last-parsed-size))) (progn (setq total-js-extract-time (+ total-js-extract-time last-ast-time last-parse-time)) (setq total-js-extract-size (+ total-js-extract-size last-parsed-size)) (incf total-js-extract-count))) (puthash id project resource-id-to-project) ; Register loaded resource for extraction if needed. (if (not (null priority)) (dojo-core-util-request-extraction workspace id priority (if (null priority-count) 1 priority-count))) ; Usually, during loading we start with an empty path-to-resources map, ; so there cannot be any duplicates. Only in the special case that a ; project scan was interrupted by application exit, we additionally have ; a curr_scan_resources.xml, which can contain resources that are present ; in the resources.xml as well. ; Thus, only in that special case, perform a duplicate check. (if process-curr-scan-project-resources (let ((found-existing-resource nil)) (dolist (existing-resource resources) (if (string= (dojo-resource-file-path existing-resource) (dojo-resource-file-path resource)) (setq found-existing-resource existing-resource))) (if found-existing-resource (progn (copy-dojo-resource resource found-existing-resource) (push found-existing-resource curr-scan-project-resources)) (push resource resources) (push resource curr-scan-project-resources))) (push resource resources)) (if (string= type "blueprint") (let* ((project-to-services-resource (dojo-workspace-project-to-services-resource workspace))) (log-load (format "Registering blueprint file [%s] for project [%s]" file-path project)) (puthash project id project-to-services-resource))) (puthash path resources path-to-resources) (puthash id resource id-to-resource))) (t (log-load (format "[WARNING] List element is not of expected type 'resource, found [%s], will ignore it." child))))) (setf (dojo-workspace-total-js-extract-time workspace) total-js-extract-time) (setf (dojo-workspace-total-js-extract-size workspace) total-js-extract-size) (setf (dojo-workspace-total-js-extract-count workspace) total-js-extract-count) (log-load (format "Loading resources for project [%s], total-extract-time now [%s], -size now [%s], -count now [%s]" project total-js-extract-time total-js-extract-size total-js-extract-count)) (if process-curr-scan-project-resources (progn (setf (dojo-workspace-curr-scan-project-resources workspace) curr-scan-project-resources) (log-load (format "Loaded [%s] curr-scan-project-resources" (length curr-scan-project-resources))))))))) (defun dojo-core-load-parse-class-files (base-dir) (let* ((classes-dir (concat base-dir (file-name-as-directory "classes"))) (classes-contents (if (file-exists-p classes-dir) (directory-files classes-dir) ())) (id-to-class (make-hash-table :test 'equal))) (dolist (classes-content classes-contents) (if (not (or (string= classes-content ".") (string= classes-content ".."))) (let ((project-dir (concat classes-dir (file-name-as-directory classes-content)))) (if (file-directory-p project-dir) (dojo-core-load-register-classes workspace project-dir classes-content nil id-to-class))))) id-to-class)) (defun dojo-core-load-register-classes (base-dir workspace project path id-to-class) (log-load (format "Called for base-dir [%s], project [%s] and path [%s]" base-dir project path)) (let* ((dir-files (directory-files base-dir))) (dolist (dir-file dir-files) (if (not (or (string= dir-file ".") (string= dir-file ".."))) (let ((file-path (concat base-dir dir-file))) (if (file-directory-p file-path) (dojo-core-load-register-classes (concat base-dir (file-name-as-directory dir-file)) workspace project (if path (concat path "/" dir-file) dir-file) id-to-class) (dojo-core-load-register-class (concat base-dir dir-file) project path id-to-class))))))) (defun dojo-core-load-load-class (workspace resource) (let* ((id-to-class (dojo-workspace-id-to-class workspace)) (project (dojo-resource-project resource)) (path (dojo-resource-path resource)) (path-without-name (dojo-common-strings-get-without-last-token path "/")) ; At this point, we expect path to be something like 'clazzes/util/ErrorHelper' (save-dir (dojo-core-save-get-or-create-save-dir)) (class-dir (concat save-dir (file-name-as-directory "classes") (file-name-as-directory project) (file-name-as-directory path-without-name))) (class-file-name (concat class-dir (get-last-token path "/") ".xml")) (loaded-class (dojo-core-load-register-class class-file-name project path id-to-class))) ; (setf (dojo-resource-parsed-id resource) loaded-class) loaded-class)) (defun dojo-core-load-parse-class-node (class-node &optional is-api) (let* ((id (dojo-core-load-convert-number-attribute (dom-attr class-node 'id))) (resource-id (dojo-core-load-convert-number-attribute (dom-attr class-node 'resource))) (project (dom-attr class-node 'project)) (path (dom-attr class-node 'path)) (scan-id (dojo-core-load-convert-number-attribute (dom-attr class-node 'scan-id))) (next-free-symbol-id (dojo-core-load-convert-number-attribute (dom-attr class-node 'next-free-symbol-id))) (define-symbol-id (dojo-core-load-convert-number-attribute (dom-attr class-node 'define-symbol))) (static-symbol-id (dojo-core-load-convert-number-attribute (dom-attr class-node 'static-symbol))) (this-symbol-id (dojo-core-load-convert-number-attribute (dom-attr class-node 'this-symbol))) (superclass-paths nil) (annotations nil) (import-to-symbol nil) (id-to-symbol nil) (id-to-scope nil) (in-assignment-map nil) (out-assignment-map nil) (class (dojo-class--create))) (setf (dojo-class-is-api-class class) is-api) (dolist (class-node-child (dom-children class-node)) (cond ((dojo-core-load-is-node class-node-child 'superclass-paths) (setq superclass-paths (dojo-core-load-parse-string-list class-node-child 'superclass-path))) ((dojo-core-load-is-node class-node-child 'annotations) (setq annotations (dojo-core-load-parse-annotations class-node-child))) ((dojo-core-load-is-node class-node-child 'imports) (setq import-to-symbol (dojo-core-load-parse-imports-node class-node-child))) ((dojo-core-load-is-node class-node-child 'symbols) (setq id-to-symbol (dojo-core-load-parse-symbols-node class-node-child is-api))) ((dojo-core-load-is-node class-node-child 'scopes) (setq id-to-scope (dojo-core-load-parse-scopes-node class-node-child))) ((dojo-core-load-is-node class-node-child 'in-assignments) ()) ; (log-load (format "... Will process in-assignments node."))) ; (setq in-assignment-map (dojo-core-load-parse-assignments-node class-node-child t))) ((dojo-core-load-is-node class-node-child 'out-assignments) ()) ; (log-load (format "... Will process out-assignments node."))) ; (setq out-assignment-map (dojo-core-load-parse-assignments-node class-node-child nil))) (t (log-load (format "[WARNING] Found unsupported node [%s]" class-node-child))))) ; Resolve scopes (the code loading the symbols just stored the scope-id in field ; dojo-symbol-scope, replace it against the dojo-scope struct ; fetched from the id-to-scope map) ; ... and the same for the arguments. (if (null id-to-symbol) (log-load (format "[WARNING] No id-to-symbol map available in load-register-class; possibly the xml file is invalid.")) (maphash (lambda (id symbol) (cond ((dojo-core-util-is-function-symbol symbol) (let* ((argument-ids (dojo-symbol-get-function-arguments symbol)) (new-arguments ()) (return-id (dojo-symbol-get-function-return-type symbol)) (return-type (progn ; (log-load (format "Processing return-id [%s], match [%s]" ; return-id (if (null return-id) "---" (string-match-p "^[0-9]+$" return-id)))) (if (and (stringp return-id) (not (null (string-match-p "^[0-9]+$" return-id)))) (gethash (string-to-number return-id) id-to-symbol) return-id))) (scope-id (dojo-symbol-get-function-scope symbol)) (scope (if id-to-scope (gethash scope-id id-to-scope) nil))) (dolist (argument-id argument-ids) (let ((argument (gethash argument-id id-to-symbol))) (if (null argument) (log-load (format "[WARNING] Could not resolve function-argument [%s] of function-symbol [%s]" argument-id id)) (push argument new-arguments)))) ; (log-load (format "Processing symbol %s, resolved return-type %s" symbol return-type)) (dojo-symbol-set-function-arguments symbol new-arguments) (dojo-symbol-set-function-return-type symbol return-type) (dojo-symbol-set-function-scope symbol scope))) ((dojo-core-util-is-ref-symbol symbol) (let* ((symbol-ids (dojo-symbol-get-ref-symbols symbol)) (new-symbols ())) (dolist (symbol-id symbol-ids) (cond ((stringp symbol-id) ; Case some textual reference, like '*' (push symbol-id new-symbols)) ((numberp symbol-id) (let ((symbol (gethash symbol-id id-to-symbol))) (if (null symbol) (log-load (format "[WARNING] Could not resolve symbol [%s] of reference symbol [%s]" symbol-id id)) (push symbol new-symbols)))) (t (log-load (format "[WARNING] Unknown case of ref-symbol: [%s]" symbol-id))))) ; (log-load (format "Loaded new-symbols (case ref): %s" new-symbols)) (dojo-symbol-set-ref-symbols symbol (nreverse new-symbols)))) ((or (dojo-core-util-is-object-symbol symbol) (dojo-core-util-is-array-or-object-symbol symbol)) (let* ((key-symbol-id (dojo-symbol-get-object-key-type symbol)) (value-symbol-id (dojo-symbol-get-object-value-type symbol)) (name-to-symbol (dojo-symbol-get-object-members symbol)) (function-symbol-id (dojo-symbol-get-object-function-symbol symbol))) (if (numberp key-symbol-id) (dojo-symbol-set-object-key-type symbol (gethash key-symbol-id id-to-symbol))) (if (numberp value-symbol-id) (dojo-symbol-set-object-value-type symbol (gethash value-symbol-id id-to-symbol))) (if (numberp function-symbol-id) (dojo-symbol-set-object-function-symbol symbol (gethash function-symbol-id id-to-symbol))) (let ((member-names (hash-table-get-all-keys name-to-symbol))) (dolist (member-name member-names) (let ((member (gethash member-name name-to-symbol))) (if (numberp member) (puthash member-name (gethash member id-to-symbol) name-to-symbol))))))) ((dojo-core-util-is-array-symbol symbol) (let* ((value-symbol-id (dojo-symbol-get-array-value-type symbol))) (if (numberp value-symbol-id) (dojo-symbol-set-array-value-type symbol (gethash value-symbol-id id-to-symbol))))))) id-to-symbol)) (if (null id-to-scope) () ; (log-load (format "[WARNING] No id-to-scope map available in load-register-class; possibly the xml file is invalid.")) (maphash (lambda (id scope) (let* ((name-to-symbol (dojo-scope-name-to-symbol scope)) (names (hash-table-get-all-keys name-to-symbol))) (dolist (name names) (let ((symbol (gethash name name-to-symbol))) (if (numberp symbol) (puthash name (gethash symbol id-to-symbol) name-to-symbol)))))) id-to-scope)) (if (not (null import-to-symbol)) (let* ((new-import-to-symbol (make-hash-table :test 'equal))) (maphash (lambda (import symbol-id) (if (numberp symbol-id) (puthash import (gethash symbol-id id-to-symbol) new-import-to-symbol))) import-to-symbol) (setq import-to-symbol new-import-to-symbol))) (setf annotations (sort annotations (lambda (annotation-one annotation-two) (- (dojo-annotation-min-pos annotation-two) (dojo-annotation-min-pos annotation-one))))) (setf (dojo-class-id class) id) (setf (dojo-class-resource-id class) resource-id) (setf (dojo-class-project class) project) (setf (dojo-class-path class) path) (setf (dojo-class-scan-id class) scan-id) (setf (dojo-class-superclass-paths class) superclass-paths) (setf (dojo-class-annotations class) annotations) (setf (dojo-class-import-to-symbol class) import-to-symbol) (setf (dojo-class-next-free-symbol-id class) next-free-symbol-id) (setf (dojo-class-id-to-symbol class) id-to-symbol) (setf (dojo-class-id-to-scope class) id-to-scope) (setf (dojo-class-define-symbol class) (gethash define-symbol-id id-to-symbol)) (let* ((this-symbol (gethash this-symbol-id id-to-symbol)) (static-symbol (gethash static-symbol-id id-to-symbol))) (if this-symbol (dojo-class-set-this-symbol class this-symbol)) (if static-symbol (dojo-class-set-static-symbol class static-symbol))) ; (setf (dojo-class-in-assignment-map class) in-assignment-map) ; (setf (dojo-class-out-assignment-map class) out-assignment-map) class)) (defun dojo-core-load-register-class (class-file project path id-to-class) (log-load (format "Will parse class-file [%s] in project [%s] with path [%s]" class-file project path)) (if (file-exists-p class-file) (with-temp-buffer (buffer-disable-undo (current-buffer)) (insert-file-contents class-file) (let* ((class-node (libxml-parse-xml-region (point-min) (point-max))) (class (if class-node (dojo-core-load-parse-class-node class-node) nil))) (if class (puthash (dojo-class-id class) class id-to-class)) class)))) (defun dojo-core-load-parse-annotations (node) (log-load (format "Called dojo-core-load-parse-map.")) (let* ((annotations ()) (node-children (dom-children node))) (dolist (node-child node-children) (cond ((dojo-core-load-is-node node-child 'annotation) (let* ((key (dom-attr node-child 'key)) (value (dom-attr node-child 'value)) (min-pos (dojo-core-load-convert-number-attribute (dom-attr node-child 'min-pos))) (max-pos (dojo-core-load-convert-number-attribute (dom-attr node-child 'max-pos))) (annotation (construct-dojo-annotation (if (and key (> (length key) 0)) key nil) (if (and value (> (length value) 0)) value nil) min-pos max-pos))) (push annotation annotations))) (t (log-load (format "[WARNING] While loading annotation-map: Found unrecognized entry [%s]" node-child))))) annotations)) (defun dojo-core-load-parse-imports-node (imports-node) (let* ((import-to-symbol (make-hash-table :test 'equal)) (imports-children (dom-children imports-node))) (dolist (import-child imports-children) (cond ((dojo-core-load-is-node import-child 'import) (let* ((name (dom-attr import-child 'symbol)) (id (dojo-core-load-convert-number-attribute (dom-attr import-child 'id)))) (puthash name id import-to-symbol))))) import-to-symbol)) (defun dojo-core-load-parse-symbols-node (symbols-node &optional is-api) (let* ((local-id-to-symbol (make-hash-table :test 'equal)) (symbols-children (dom-children symbols-node))) (dolist (symbols-child symbols-children) (cond ((dojo-core-load-is-node symbols-child 'symbol) (let ((symbol (dojo-core-load-parse-symbol-node symbols-child is-api))) (puthash (dojo-symbol-id symbol) symbol local-id-to-symbol))) (t (log-load (format "[WARNING] Node is no symbol: %s" symbols-child))))) local-id-to-symbol)) (defun dojo-core-load-parse-symbol-node (symbol-node &optional is-api) (let* ((id (dojo-core-load-convert-number-attribute (dom-attr symbol-node 'id))) (name (dom-attr symbol-node 'name)) (value (dojo-common-string-unquote-xml (dom-attr symbol-node 'value))) (type (gethash (dom-attr symbol-node 'type) DOJO-JSTYPE-STRING-MAP)) (parent-id (dojo-core-load-convert-number-attribute (dom-attr symbol-node 'parent-id))) (scan-id (dojo-core-load-convert-number-attribute (dom-attr symbol-node 'scan-id))) (class-id (dojo-core-load-convert-number-attribute (dom-attr symbol-node 'class-id))) (min-pos (dojo-core-load-convert-number-attribute (dom-attr symbol-node 'min-pos))) (max-pos (dojo-core-load-convert-number-attribute (dom-attr symbol-node 'max-pos))) (symbol (make-dojo-symbol))) (setf (dojo-symbol-is-api-symbol symbol) is-api) (setf (dojo-symbol-id symbol) id) (setf (dojo-symbol-name symbol) (if (and (stringp name) (> (length name) 0)) name nil)) (setf (dojo-symbol-value symbol) (if (and (stringp value) (> (length value) 0)) value nil)) (setf (dojo-symbol-parent-id symbol) parent-id) (setf (dojo-symbol-scan-id symbol) scan-id) (setf (dojo-symbol-class-id symbol) class-id) (setf (dojo-symbol-min-pos symbol) min-pos) (setf (dojo-symbol-max-pos symbol) max-pos) (dojo-symbol-set-type symbol type) (cond ((eq type 'DOJO-JSTYPE-ARRAY) (let* ((value-type-arg (dom-attr symbol-node 'value-type)) (value-symbol-id-or-type (if (dojo-core-load-is-string-number value-type-arg) (string-to-number value-type-arg) value-type-arg))) (dojo-symbol-set-array-value-type symbol value-symbol-id-or-type))) ((or (eq type 'DOJO-JSTYPE-ARRAY-OR-OBJECT) (eq type 'DOJO-JSTYPE-OBJECT)) (let* ((key-type-arg (dom-attr symbol-node 'key-type)) (key-symbol-id-or-type (if (dojo-core-load-is-string-number key-type-arg) (string-to-number key-type-arg) key-type-arg)) (value-type-arg (dom-attr symbol-node 'value-type)) (value-symbol-id-or-type (if (dojo-core-load-is-string-number value-type-arg) (string-to-number value-type-arg) value-type-arg)) (fct-symbol-id (dojo-core-load-convert-number-attribute (dom-attr symbol-node 'fct-symbol))) (object-type-string (dom-attr symbol-node 'object-type)) (object-type (if object-type-string (gethash object-type-string DOJO-OBJECTTYPE-STRING-MAP) nil)) (object-info-string (dom-attr symbol-node 'object-info)) (object-info (if (dojo-core-load-is-string-number object-info-string) (string-to-number object-info-string) object-info-string)) (name-to-symbol (dojo-core-load-parse-name-to-symbol-map symbol-node 'property))) (dojo-symbol-set-array-or-object-key-type symbol key-symbol-id-or-type) (dojo-symbol-set-array-or-object-value-type symbol value-symbol-id-or-type) (dojo-symbol-set-object-function-symbol symbol fct-symbol-id) (dojo-symbol-set-object-object-type symbol object-type) (dojo-symbol-set-object-object-info symbol object-info) (dojo-symbol-set-object-members symbol name-to-symbol))) ((eq type 'DOJO-JSTYPE-FUNCTION) (let ((argument-ids (dojo-core-load-parse-arguments symbol-node)) (return-symbol-id-or-type (dom-attr symbol-node 'return-type)) (scope-id (dojo-core-load-parse-scope symbol-node))) (dojo-symbol-set-function-arguments symbol argument-ids) (dojo-symbol-set-function-return-type symbol return-symbol-id-or-type) (dojo-symbol-set-function-scope symbol scope-id))) ((or (eq type 'DOJO-JSTYPE-IMPORT) (eq type 'DOJO-JSTYPE-INSTANCE)) (let ((resource-id (dojo-core-load-convert-number-attribute (dom-attr symbol-node 'resource))) (import-type (gethash (dom-attr symbol-node 'import-type) DOJO-IMPORT-STRING-MAP)) (path (dom-attr symbol-node 'path))) (dojo-symbol-set-import-resource-id symbol resource-id) (dojo-symbol-set-import-type symbol import-type) (dojo-symbol-set-import-path symbol path))) ((eq type 'DOJO-JSTYPE-REF) (let ((ref-type (gethash (dom-attr symbol-node 'ref-type) DOJO-REFTYPE-STRING-MAP)) (ref-symbols (dojo-core-load-parse-ref-symbols symbol-node))) ; (log-load (format "Case REF: ref-symbols are %s" ref-symbols)) (dojo-symbol-set-ref-type symbol ref-type) (dojo-symbol-set-ref-symbols symbol (nreverse ref-symbols))))) symbol)) (defun dojo-core-load-is-string-number (s) (and (stringp s) (not (null (string-match-p "^[0-9]+$" s))))) (defun dojo-core-load-parse-scopes-node (scopes-node) ; (log-load (format "Called dojo-core-load-parse-scopes-node")) (let* ((id-to-scope (make-hash-table :test 'equal)) (scopes-children (dom-children scopes-node))) (dolist (scopes-child scopes-children) (cond ((dojo-core-load-is-node scopes-child 'scope) (let* ((id (dojo-core-load-convert-number-attribute (dom-attr scopes-child 'id))) (scan-id (dojo-core-load-convert-number-attribute (dom-attr scopes-child 'scan-id))) (level (dojo-core-load-convert-number-attribute (dom-attr scopes-child 'level))) (description (dom-attr scopes-child 'description)) (name-to-symbol (dojo-core-load-parse-name-to-symbol-map scopes-child 'property)) (key-to-symbol (dojo-core-load-parse-name-to-symbol-map scopes-child 'key)) (scope (dojo-scope--create))) (setf (dojo-scope-id scope) id) (setf (dojo-scope-scan-id scope) scan-id) (setf (dojo-scope-level scope) level) (setf (dojo-scope-description scope) description) (setf (dojo-scope-name-to-symbol scope) name-to-symbol) (setf (dojo-scope-key-to-symbol scope) key-to-symbol) ; (log-load (format "Setting key-to-symbol [%s]" key-to-symbol)) (puthash id scope id-to-scope))) (t (log-load (format "[WARNING] Found unknown child node of : [%s]" scopes-child))))) id-to-scope)) (defun dojo-core-load-parse-assignments-node (assignments-node dest-symbol-is-key) (let* ((assignment-map (make-hash-table :test 'equal)) (assignments-children (dom-children assignments-node))) (dolist (assignments-child assignments-children) (cond ((dojo-core-load-is-node assignments-child 'assignment) (let* ((source-id (dojo-core-load-convert-number-attribute (dom-attr assignments-child 'source))) (dest-id (dojo-core-load-convert-number-attribute (dom-attr assignments-child 'dest))) (scan-id (dojo-core-load-convert-number-attribute (dom-attr assignments-child 'scan-id))) (key (if dest-symbol-is-key dest-id source-id)) (assignment (construct-dojo-assignment source-id dest-id scan-id)) (assignments (gethash key assignment-map))) (push assignment assignments) (puthash key assignments assignment-map))) (t (log-load (format "[WARNING] Found unknown child of node: [%s]" assignments-child))))) assignment-map)) (defun dojo-core-load-convert-bool-attribute (attribute-value) (if (string= attribute-value "true") t nil)) (defun dojo-core-load-convert-number-attribute (attribute-value) (if (or (null attribute-value) (= (length attribute-value) 0)) nil (string-to-number attribute-value))) (defun dojo-core-load-is-node (node searched-tag) (and (listp node) (eq (nth 0 node) searched-tag))) (defun dojo-core-load-parse-string-list (list-node child-tag) "Given an xml node foobar, this function returns the list of strings corresponding to the children, i.e. [foo, bar] in the example. child-tag is the expected name of the child tag (in the example 'child), all other tags are ignored / subject to a warning." (let ((string-list ())) (dolist (child (dom-children list-node)) (cond ((dojo-core-load-is-node child child-tag) (push (dom-text child) string-list)) ((not (listp child)) ()) (t (log-load (format "[WARNING] List element is not of expected type [%s], found [%s], will ignore it." child-tag child))))) (nreverse string-list))) (defun dojo-core-load-get-attribute-list (list-node child-tag attribute-name) "Given an xml node , this function returns a list of the given attribute inside the given child. In this example, called with 'child and 'attr, the list ['foo', 'bar'] is returned." (let ((string-list ())) (dolist (child (dom-children list-node)) (cond ((dojo-core-load-is-node child child-tag) (push (dom-attr child attribute-name) string-list)) ((not (listp child)) ()) (t (log-load (format "[WARNING] List element is not of expected type [%s], found [%s], will ignore it." child-tag child))))) (nreverse string-list))) (defun dojo-core-load-parse-name-to-symbol-map (parent-node child-tag) (let* ((name-to-symbol (make-hash-table :test 'equal)) (children (dom-children parent-node))) (dolist (child children) (cond ((dojo-core-load-is-node child child-tag) (let ((id (dojo-core-load-convert-number-attribute (dom-attr child 'id))) (name (dom-attr child 'name))) (puthash name id name-to-symbol))) (t (log-load (format "[WARNING] Element for name-to-symbol-map is not of expected type [%s], found [%s]" child-tag child))))) name-to-symbol)) (defun dojo-core-load-parse-arguments (function-symbol-node) (let ((arguments nil) (children (dom-children function-symbol-node))) (dolist (child children) (cond ((dojo-core-load-is-node child 'argument) (push (dojo-core-load-convert-number-attribute (dom-attr child 'id)) arguments)))) arguments)) (defun dojo-core-load-parse-ref-symbols (ref-symbol-node) (let ((ref-symbols nil) (children (dom-children ref-symbol-node))) (dolist (child children) (cond ((dojo-core-load-is-node child 'ref-symbol) (let* ((ref-symbol-id (dojo-core-load-convert-number-attribute (dom-attr child 'id))) (ref-symbol-ref (dom-attr child 'ref))) (cond ((not (null ref-symbol-id)) (push ref-symbol-id ref-symbols)) ((not (null ref-symbol-ref)) (push ref-symbol-ref ref-symbols))))))) ref-symbols)) (defun dojo-core-load-parse-scope (function-symbol-node) (let ((scope-id nil) (children (dom-children function-symbol-node))) (dolist (child children) (cond ((dojo-core-load-is-node child 'scope) (setq scope-id (dojo-core-load-convert-number-attribute (dom-attr child 'id)))))) scope-id)) (defun dojo-core-load-load-api-by-resource (resource-id) (let* (;(resource-id-to-project (dojo-workspace-resource-id-to-project dojo-current-workspace)) (id-to-resource (dojo-workspace-id-to-resource dojo-current-workspace)) (resource (gethash resource-id id-to-resource)) (path-key (if resource (dojo-core-workspace-get-path-key resource) nil)) (path-key-to-id-to-api-class (dojo-workspace-path-key-to-id-to-api-class dojo-current-workspace)) (id-to-api-class-for-path-key (if path-key (gethash path-key path-key-to-id-to-api-class) nil))) (cond ((null resource) (log-js-api (format "[WARNING] Found no resource for resource-id [%s]" resource-id))) ((null path-key) (log-js-api (format "[WARNING] Found no import-path-key for resource-id [%s]" resource-id))) ((null id-to-api-class-for-path-key) (dojo-core-load-parse-api-file path-key))))) (defun dojo-core-load-parse-api-file (path-key) (let* ((save-dir (dojo-core-save-get-or-create-save-dir)) (project (dojo-core-workspace-get-project-by-path-key path-key)) (path (dojo-core-workspace-get-path-by-path-key path-key)) (path-dir (concat save-dir (file-name-as-directory "api") (file-name-as-directory project) (file-name-as-directory path))) (api-file-name (concat path-dir "api.xml"))) (if (not (file-exists-p api-file-name)) (progn (log-load (format "[WARNING] Did not find api.xml for path key [%s]" path-key)) nil) (with-temp-buffer (log-load (format "Loading api.xml for path-key [%s]: [%s]" path-key api-file-name)) (buffer-disable-undo (current-buffer)) (insert-file-contents api-file-name) (let* ((classes-node (libxml-parse-xml-region (point-min) (point-max))) (class-nodes (dom-children classes-node))) (dolist (class-node class-nodes) (cond ((dojo-core-load-is-node class-node 'class) (let* ((api-class (dojo-core-load-parse-class-node class-node t)) (id (dojo-class-id api-class)) (path-key-to-id-to-api-class (dojo-workspace-path-key-to-id-to-api-class dojo-current-workspace)) (id-to-api-class-for-path-key (gethash path-key path-key-to-id-to-api-class)) (id-to-api-class (dojo-workspace-id-to-api-class dojo-current-workspace))) (if (null id-to-api-class-for-path-key) (progn (setq id-to-api-class-for-path-key (make-hash-table :test 'equal)) (puthash path-key id-to-api-class-for-path-key path-key-to-id-to-api-class))) (puthash id api-class id-to-api-class-for-path-key) (puthash id api-class id-to-api-class))) (t (log-load (format "[WARNING] Found unrecognized child node of classes node: [%s]" class-node)))))))))) (defun dojo-core-load-parse-dependency-file-if-exists (project) (let* ((save-dir (dojo-core-save-get-or-create-save-dir)) (project-dir (concat save-dir (file-name-as-directory "dependencies") (file-name-as-directory project))) (dependencies-file-name (concat project-dir "dependencies.xml")) (project-to-dep-maps (dojo-workspace-project-to-dep-maps dojo-current-workspace)) ; Map>> (project-to-inverse-dep-maps (dojo-workspace-project-to-inverse-dep-maps dojo-current-workspace)) (dep-map (gethash project project-to-dep-maps)) ; Map> (inverse-dep-map (gethash project project-to-inverse-dep-maps))) (if (not (file-exists-p dependencies-file-name)) (log-load (format "[WARNING] Did not find dependencies.xml for project [%s]; will do nothing." project)) (with-temp-buffer (if (not (null dep-map)) (log-load (format "[WARNING] dep-map for project [%s] already exists; parse-dependency-file-if-exists will overwrite it and start with an empty dep-map." project))) (if (not (null inverse-dep-map)) (log-load (format "[WARNING] inverse-dep-map for project [%s] already exists; parse-dependency-file-if-exists will overwrite it and start with an empty inverse-dep-map." project))) (setq dep-map (make-hash-table :test 'equal)) (puthash project dep-map project-to-dep-maps) (setq inverse-dep-map (make-hash-table :test 'equal)) (puthash project inverse-dep-map project-to-inverse-dep-maps) (log-load (format "...... Loading dependencies.xml for project [%s]: [%s]" project dependencies-file-name)) (log-dep (format "...... Loading dependencies.xml for project [%s]: [%s]" project dependencies-file-name)) (buffer-disable-undo (current-buffer)) (insert-file-contents dependencies-file-name) (let* ((dependencies-node (libxml-parse-xml-region (point-min) (point-max))) (dep-children (dom-children dependencies-node))) (dolist (dep-child dep-children) (cond ((or (dojo-core-load-is-node dep-child 'dependency) (dojo-core-load-is-node dep-child 'inverse-dependency)) (let* ((resource-id (dojo-core-load-convert-number-attribute (dom-attr dep-child 'resource))) (dep-resource-id (dojo-core-load-convert-number-attribute (dom-attr dep-child 'dep-resource))) (dep-type (gethash (dom-attr dep-child 'type) DOJO-DEPTYPE-STRING-MAP)) (origin-resource-id (dojo-core-load-convert-number-attribute (dom-attr dep-child 'origin))) (inverse (dojo-core-load-is-node dep-child 'inverse-dependency))) (if inverse (dojo-core-dep-insert-into-dep-map inverse-dep-map resource-id dep-resource-id dep-type origin-resource-id) (dojo-core-dep-insert-into-dep-map dep-map resource-id dep-resource-id dep-type origin-resource-id)))) (t (log-load (format "[WARNING] Found unrecognized child node of dependencies node: [%s]" dep-child)))))) (log-dep (format "... Finished for project [%s]" project)))))) ; (dojo-core-dep-log-deps))))) (provide 'dojo-core-load)