Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ruby-syntax-tree/syntax_tree
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v6.0.2
Choose a base ref
...
head repository: ruby-syntax-tree/syntax_tree
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v6.1.0
Choose a head ref
Loading
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
/coverage/
/pkg/
/rdocs/
/sorbet/
/spec/reports/
/tmp/
/vendor/
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ AllCops:
SuggestExtensions: false
TargetRubyVersion: 2.7
Exclude:
- '{.git,.github,bin,coverage,pkg,spec,test/fixtures,vendor,tmp}/**/*'
- '{.git,.github,bin,coverage,pkg,sorbet,spec,test/fixtures,vendor,tmp}/**/*'
- test.rb

Gemspec/DevelopmentDependencies:
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.2.0
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -6,6 +6,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a

## [Unreleased]

## [6.1.0] - 2023-03-20

### Added

- The `stree ctags` command for generating ctags like `universal-ctags` or `ripper-tags` would.
- The `definedivar` YARV instruction has been added to match CRuby's implementation.
- We now generate better Sorbet RBI files for the nodes in the tree and the visitors.
- `SyntaxTree::Reflection.nodes` now includes the visitor method.

### Changed

- We now explicitly require `pp` in environments that need it.

## [6.0.2] - 2023-03-03

### Added
12 changes: 6 additions & 6 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
syntax_tree (6.0.2)
syntax_tree (6.1.0)
prettier_print (>= 1.2.0)

GEM
@@ -10,16 +10,16 @@ GEM
ast (2.4.2)
docile (1.4.0)
json (2.6.3)
minitest (5.17.0)
minitest (5.18.0)
parallel (1.22.1)
parser (3.2.1.0)
parser (3.2.1.1)
ast (~> 2.4.1)
prettier_print (1.2.0)
prettier_print (1.2.1)
rainbow (3.1.1)
rake (13.0.6)
regexp_parser (2.7.0)
rexml (3.2.5)
rubocop (1.47.0)
rubocop (1.48.1)
json (~> 2.3)
parallel (~> 1.10)
parser (>= 3.2.0.0)
@@ -31,7 +31,7 @@ GEM
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.27.0)
parser (>= 3.2.1.0)
ruby-progressbar (1.12.0)
ruby-progressbar (1.13.0)
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@ It is built with only standard library dependencies. It additionally ships with
- [CLI](#cli)
- [ast](#ast)
- [check](#check)
- [ctags](#ctags)
- [expr](#expr)
- [format](#format)
- [json](#json)
@@ -139,6 +140,33 @@ To change the print width that you are checking against, specify the `--print-wi
stree check --print-width=100 path/to/file.rb
```

### ctags

This command will output to stdout a set of tags suitable for usage with [ctags](https://github.com/universal-ctags/ctags).

```sh
stree ctags path/to/file.rb
```

For a file containing the following Ruby code:

```ruby
class Foo
end

class Bar < Foo
end
```

you will receive:

```
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
Bar test.rb /^class Bar < Foo$/;" c inherits:Foo
Foo test.rb /^class Foo$/;" c
```

### expr

This command will output a Ruby case-match expression that would match correctly against the first expression of the input.
@@ -788,6 +816,7 @@ inherit_gem:
* [Neovim](https://neovim.io/) - [neovim/nvim-lspconfig](https://github.com/neovim/nvim-lspconfig).
* [Vim](https://www.vim.org/) - [dense-analysis/ale](https://github.com/dense-analysis/ale).
* [VSCode](https://code.visualstudio.com/) - [ruby-syntax-tree/vscode-syntax-tree](https://github.com/ruby-syntax-tree/vscode-syntax-tree).
* [Emacs](https://www.gnu.org/software/emacs/) - [emacs-format-all-the-code](https://github.com/lassik/emacs-format-all-the-code).
## Contributing
1 change: 1 addition & 0 deletions lib/syntax_tree.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require "prettier_print"
require "pp"
require "ripper"

require_relative "syntax_tree/node"
91 changes: 91 additions & 0 deletions lib/syntax_tree/cli.rb
Original file line number Diff line number Diff line change
@@ -154,6 +154,92 @@ def failure
end
end

# An action of the CLI that generates ctags for the given source.
class CTags < Action
attr_reader :entries

def initialize(options)
super(options)
@entries = []
end

def run(item)
lines = item.source.lines(chomp: true)

SyntaxTree
.index(item.source)
.each do |entry|
line = lines[entry.location.line - 1]
pattern = "/^#{line.gsub("\\", "\\\\\\\\").gsub("/", "\\/")}$/;\""

entries << case entry
when SyntaxTree::Index::ModuleDefinition
parts = [entry.name, item.filepath, pattern, "m"]

if entry.nesting != [[entry.name]]
parts << "class:#{entry.nesting.flatten.tap(&:pop).join(".")}"
end

parts.join("\t")
when SyntaxTree::Index::ClassDefinition
parts = [entry.name, item.filepath, pattern, "c"]

if entry.nesting != [[entry.name]]
parts << "class:#{entry.nesting.flatten.tap(&:pop).join(".")}"
end

unless entry.superclass.empty?
inherits = entry.superclass.join(".").delete_prefix(".")
parts << "inherits:#{inherits}"
end

parts.join("\t")
when SyntaxTree::Index::MethodDefinition
parts = [entry.name, item.filepath, pattern, "f"]

unless entry.nesting.empty?
parts << "class:#{entry.nesting.flatten.join(".")}"
end

parts.join("\t")
when SyntaxTree::Index::SingletonMethodDefinition
parts = [entry.name, item.filepath, pattern, "F"]

unless entry.nesting.empty?
parts << "class:#{entry.nesting.flatten.join(".")}"
end

parts.join("\t")
when SyntaxTree::Index::AliasMethodDefinition
parts = [entry.name, item.filepath, pattern, "a"]

unless entry.nesting.empty?
parts << "class:#{entry.nesting.flatten.join(".")}"
end

parts.join("\t")
when SyntaxTree::Index::ConstantDefinition
parts = [entry.name, item.filepath, pattern, "C"]

unless entry.nesting.empty?
parts << "class:#{entry.nesting.flatten.join(".")}"
end

parts.join("\t")
end
end
end

def success
puts(<<~HEADER)
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
HEADER

entries.sort.each { |entry| puts(entry) }
end
end

# An action of the CLI that formats the source twice to check if the first
# format is not idempotent.
class Debug < Action
@@ -327,6 +413,9 @@ def run(item)
#{Color.bold("stree check [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE")}
Check that the given files are formatted as syntax tree would format them
#{Color.bold("stree ctags [-e SCRIPT] FILE")}
Print out a ctags-compatible index of the given files
#{Color.bold("stree debug [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE")}
Check that the given files can be formatted idempotently
@@ -488,6 +577,8 @@ def run(argv)
AST.new(options)
when "c", "check"
Check.new(options)
when "ctags"
CTags.new(options)
when "debug"
Debug.new(options)
when "doc"
Loading