{"id":19917191,"url":"https://github.com/athos/symbol-analyzer","last_synced_at":"2025-06-23T05:07:05.059Z","repository":{"id":19099412,"uuid":"22327669","full_name":"athos/symbol-analyzer","owner":"athos","description":"Clojure code analyzer that tells us how each symbol is being used in the code","archived":false,"fork":false,"pushed_at":"2015-08-12T08:23:35.000Z","size":332,"stargazers_count":12,"open_issues_count":7,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-23T05:06:13.021Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/athos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-07-28T01:57:04.000Z","updated_at":"2025-01-22T11:48:02.000Z","dependencies_parsed_at":"2022-09-25T04:35:26.129Z","dependency_job_id":null,"html_url":"https://github.com/athos/symbol-analyzer","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/athos/symbol-analyzer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/athos%2Fsymbol-analyzer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/athos%2Fsymbol-analyzer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/athos%2Fsymbol-analyzer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/athos%2Fsymbol-analyzer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/athos","download_url":"https://codeload.github.com/athos/symbol-analyzer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/athos%2Fsymbol-analyzer/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261417578,"owners_count":23155073,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T21:49:06.233Z","updated_at":"2025-06-23T05:06:59.537Z","avatar_url":"https://github.com/athos.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# symbol-analyzer　[![Build Status](https://travis-ci.org/athos/symbol-analyzer.png)](https://travis-ci.org/athos/symbol-analyzer)\n\n`symbol-analyzer` is a code analyzer that analyzes for you how each symbol is being used in the code. It can be used in various ways such as static analysis for Clojure code or defining complicated macros that require code walk.\n\n## Installation\n\nLatest stable release is 0.1.1.\n\nAdd the following dependency to your `project.clj` file:\n\n[![Clojars Project](http://clojars.org/symbol-analyzer/latest-version.svg)](http://clojars.org/symbol-analyzer)\n\n## Basic Usage\n\nThe basic usages of `symbol-analyzer` are *extract* and *analyze*.\n\n**Note** `symbol-analyzer` is still of alpha quality, and **its APIs (the format of their return values described below, especially) are highly subject to change.**\n\n### Extract\n\n*Extract* analyzes how the specified symbols in the code are being used and will return the result, which we call *symbol information*. The target symbols to be analyzed are specified by assigning unique IDs as metadata with a specific key. The default key is `:id`.\n\nFor example, we can analyze the usage of the second `x` in `(let [x 0] x)` as follows:\n\n```clojure\nuser=\u003e (require '[symbol-analyzer.extraction :refer [extract]])\nnil\nuser=\u003e (extract '(let [x 0] ^{:id 0} x))\n{0 {:type :local, :usage :ref, :binding :none}}\nuser=\u003e\n```\n\nIn this example, we assign ID `0` to the second `x` we are targeting. From the result, we can find the symbol assigned ID `0` (i.e. the one we are targeting) to be a reference to a local binding. Similarly, we'll get the following result if we assign IDs to other symbols as well:\n\n```clojure\nuser=\u003e (extract '(^{:id 0} let [^{:id 1} x 0] ^{:id 2} x))\n{2 {:type :local, :usage :ref, :binding 1}, 1 {:type :local, :usage :def}, 0 {:type :macro, :macro #'clojure.core/let}}\nuser=\u003e\n```\n\n`symbol-analyzer` can even analyze code containing user-defined macros; the analyzer expands the macro by itself if it encounters a macro in the course of analysis, and it will identify the usage of symbols from the expanded form that doesn't contain macros.\n\n```clojure\nuser=\u003e (defmacro let1 [name expr \u0026 body] `(let [~name ~expr] ~@body))\n#'user/let1\nuser=\u003e (let1 x 2 (* x x))\n4\nuser=\u003e (extract '(let1 ^{:id 0} x 2 (* ^{:id 1} x x)))\n{1 {:type :local, :usage :ref, :binding 0}, 0 {:type :local, :usage :def}}\nuser=\u003e\n```\n\n\n\n### Analyze\n\n*Analyze* applies *extract* to all the symbols in the code. Symbol information resulted from the extraction will be added to symbols in the input code as metadata.\n\n```clojure\nuser=\u003e (require '[symbol-analyzer.core :refer [analyze-sexp]])\nnil\nuser=\u003e (set! *print-meta* true)    ; to visualize metadata\nnil\nuser=\u003e (analyze-sexp '(let [x 0] x))\n(^{:symbol-info {:type :macro, :macro #'clojure.core/let}, :id 7} let\n [^{:symbol-info {:type :local, :usage :def}, :id 8} x 0]\n ^{:symbol-info {:type :local, :usage :ref, :binding 8}, :id 9} x)\nuser=\u003e\n```\n\nUsing the analysis results, we can also write certain types of code walkers rather easily. For example, suppose we want to do something to all (and only) the symbols representing local bindings. In such a case, it is often the case we have to expend a great amount of effort to write up the code handling local environments and traversing the input code by ourselves. With `symbol-analyzer`, on the other hand, we can realize code walkers like that in combination with simple sequence functions such as `reduce` and `filter` or functions in `clojure.walk`. In the example below, we are defining with `analyze-sexp` a function renaming the symbols representing local bindings:\n\n```clojure\nuser=\u003e (defn rename-locals [sexp]\n  #_=\u003e   (postwalk (fn [x]\n  #_=\u003e               (if (and (symbol? x)\n  #_=\u003e                        (= (-\u003e x meta :symbol-info :type) :local))\n  #_=\u003e                 (symbol (str \\? x))\n  #_=\u003e                 x))\n  #_=\u003e             (analyze-sexp sexp)))\n#'user/rename-locals\nuser=\u003e (rename-locals '(let [x x] [x 'x]))\n(let [?x x] [?x (quote x)])\nuser=\u003e\n```\n\nNote that the symbols representing the local `x` bound by `let` get renamed to `?x`, and not the symbols representing `x` as a free variable nor a quoted literal symbol.\n\nIn addition to `analyze-sexp`, taking an S-expression as input, `symbol-analyzer` also provides another API named `analyze`, which takes as input Clojure code represented as [Sjacket](https://github.com/cgrand/sjacket) nodes. This interface is intended to use for implementing tools analyzing the code and writing it back as text, such as syntax highlighters, etc. (See [genuine-highlighter](https://github.com/athos/genuine-highlighter) for an example of `symbol-analyzer`-backed syntax highlighter).\n\n\n## License\n\nCopyright © 2014-2015 OHTA Shogo\n\nDistributed under the Eclipse Public License version 1.0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fathos%2Fsymbol-analyzer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fathos%2Fsymbol-analyzer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fathos%2Fsymbol-analyzer/lists"}