{"id":13798014,"url":"https://github.com/yujinakayama/astrolabe","last_synced_at":"2025-04-06T07:11:39.743Z","repository":{"id":18297905,"uuid":"21472393","full_name":"yujinakayama/astrolabe","owner":"yujinakayama","description":"An object-oriented Ruby AST extension for Parser","archived":false,"fork":false,"pushed_at":"2020-08-11T04:02:09.000Z","size":68,"stargazers_count":68,"open_issues_count":2,"forks_count":7,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-30T05:09:36.320Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yujinakayama.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-07-03T18:15:27.000Z","updated_at":"2024-02-07T14:09:13.000Z","dependencies_parsed_at":"2022-08-24T03:20:53.039Z","dependency_job_id":null,"html_url":"https://github.com/yujinakayama/astrolabe","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yujinakayama%2Fastrolabe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yujinakayama%2Fastrolabe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yujinakayama%2Fastrolabe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yujinakayama%2Fastrolabe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yujinakayama","download_url":"https://codeload.github.com/yujinakayama/astrolabe/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247445670,"owners_count":20939958,"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-08-04T00:00:37.863Z","updated_at":"2025-04-06T07:11:39.724Z","avatar_url":"https://github.com/yujinakayama.png","language":"Ruby","funding_links":[],"categories":["Tools"],"sub_categories":[],"readme":"[![Gem Version](https://badge.fury.io/rb/astrolabe.svg)](http://badge.fury.io/rb/astrolabe)\n[![Dependency Status](https://gemnasium.com/yujinakayama/astrolabe.svg)](https://gemnasium.com/yujinakayama/astrolabe)\n[![Build Status](https://travis-ci.org/yujinakayama/astrolabe.svg?branch=master\u0026style=flat)](https://travis-ci.org/yujinakayama/astrolabe)\n[![Coverage Status](https://coveralls.io/repos/yujinakayama/astrolabe/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/yujinakayama/astrolabe?branch=master)\n[![Code Climate](https://codeclimate.com/github/yujinakayama/astrolabe/badges/gpa.svg)](https://codeclimate.com/github/yujinakayama/astrolabe)\n\n# Astrolabe\n\n**Astrolabe** is an AST node library that provides an object-oriented way to handle AST by extending [Parser](https://github.com/whitequark/parser)'s node class.\n\n## Installation\n\nAdd this line to your `Gemfile`:\n\n```ruby\ngem 'astrolabe'\n```\n\nAnd then execute:\n\n```bash\n$ bundle install\n```\n\n## Usage\n\nYou can generate an AST that consists of `Astrolabe::Node` by using `Astrolabe::Builder` along with `Parser`:\n\n```ruby\nrequire 'astrolabe/builder'\nrequire 'parser/current'\n\nsource_buffer = Parser::Source::Buffer.new('(string)')\nsource_buffer.source = 'puts :foo'\n\nast_builder = Astrolabe::Builder.new\nparser = Parser::CurrentRuby.new(ast_builder)\n\nroot_node = parser.parse(source_buffer)\nroot_node.class # =\u003e Astrolabe::Node\n```\n\n`Astrolabe::Node` is a subclass of [`Parser::AST::Node`](http://rubydoc.info/gems/parser/Parser/AST/Node).\n\n## APIs\n\nSee these references for all the public APIs:\n\n* [`Astrolabe::Node`](http://rubydoc.info/gems/astrolabe/Astrolabe/Node)\n* [`Astrolabe::Builder`](http://rubydoc.info/gems/astrolabe/Astrolabe/Builder)\n\n### Node Type Predicate Methods\n\nThese would be useful especially when combined with `Enumerable` methods (described below).\n\n```ruby\nnode.send_type?    # Equivalent to: `node.type == :send`\nnode.op_asgn_type? # Equivalent to: `node.type == :op_asgn`\n\n# Non-word characters (other than a-zA-Z0-9_) in type names are omitted.\nnode.defined_type? # Equivalent to: `node.type == :defined?`\n```\n\n### Access to Parent Node\n\n```ruby\ndef method_taking_block?(node)\n  return unless node.parent.block_type?\n  node.parent.children.first.equal?(node)\nend\n\nblock_node = parser.parse(buffer)\n# (block\n#   (send\n#     (int 3) :times)\n#   (args\n#     (arg :i))\n#   (send nil :do_something))\n\nsend_node, args_node, body_node = *block_node\nmethod_taking_block?(send_node) # =\u003e true\n```\n\n### AST Traversal\n\nThese methods bring the power of `Enumerable` to AST.\n\nNote that you may want to use [`Parser::AST::Processor`](http://rubydoc.info/gems/parser/Parser/AST/Processor)\nif you don't need to track context of AST.\n\n```ruby\n# Iterate ancestor nodes in the order from parent to root.\nnode.each_ancestor { |ancestor_node| ... }\n\n# This is different from `node.children.each { |child| ... }`\n# which yields all children including non-node element.\nnode.each_child_node { |child_node| ... }\n\n# These iteration methods can be chained by Enumerable methods.\n# Find the first lvar node under the receiver node.\nlvar_node = node.each_descendant.find(\u0026:lvar_type?)\n\n# Iterate the receiver node itself and the descendant nodes.\n# This would be useful when you treat the receiver node as a root of tree\n# and want to iterate all nodes in the tree.\nast.each_node { |node| ... }\n\n# Yield only specific type nodes.\nast.each_node(:send) { |send_node| ... }\n# This is equivalent to:\nast.each_node.select(\u0026:send_type?).each { |send_node| ... }\n\n# Yield only nodes matching any of the types.\nast.each_node(:send, :block) { |send_or_block_node| ... }\nast.each_node([:send, :block]) { |send_or_block_node| ... }\n# These are equivalent to:\nast.each_node\n  .select { |node| [:send, :block].include?(node.type) }\n  .each { |send_or_block_node| ... }\n```\n\n## Projects using Astrolabe\n\n* [RuboCop](https://github.com/bbatsov/rubocop)\n* [Transpec](https://github.com/yujinakayama/transpec)\n\n## Compatibility\n\nTested on MRI 2.2, 2.3, 2.4, 2.5, and JRuby 9000.\n\n## License\n\nCopyright (c) 2014 Yuji Nakayama\n\nSee the [LICENSE.txt](LICENSE.txt) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyujinakayama%2Fastrolabe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyujinakayama%2Fastrolabe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyujinakayama%2Fastrolabe/lists"}