From ed215c4592417d53bc7f37a94066af02395b08d8 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Fri, 24 Mar 2023 12:17:04 -0400 Subject: [PATCH 01/31] Experimental database API --- lib/syntax_tree.rb | 1 + lib/syntax_tree/database.rb | 331 ++++++++++++++++++++++++++++++++++++ 2 files changed, 332 insertions(+) create mode 100644 lib/syntax_tree/database.rb diff --git a/lib/syntax_tree.rb b/lib/syntax_tree.rb index 24d8426f..6c595db5 100644 --- a/lib/syntax_tree.rb +++ b/lib/syntax_tree.rb @@ -21,6 +21,7 @@ module SyntaxTree # CLI. Requiring those features takes time, so we autoload as many constants # as possible in order to keep the CLI as fast as possible. + autoload :Database, "syntax_tree/database" autoload :DSL, "syntax_tree/dsl" autoload :FieldVisitor, "syntax_tree/field_visitor" autoload :Index, "syntax_tree/index" diff --git a/lib/syntax_tree/database.rb b/lib/syntax_tree/database.rb new file mode 100644 index 00000000..c9981f35 --- /dev/null +++ b/lib/syntax_tree/database.rb @@ -0,0 +1,331 @@ +# frozen_string_literal: true + +module SyntaxTree + # Provides the ability to index source files into a database, then query for + # the nodes. + module Database + class IndexingVisitor < SyntaxTree::FieldVisitor + attr_reader :database, :filepath, :node_id + + def initialize(database, filepath) + @database = database + @filepath = filepath + @node_id = nil + end + + private + + def comments(node) + end + + def field(name, value) + return unless value.is_a?(SyntaxTree::Node) + + binds = [node_id, visit(value), name] + database.execute(<<~SQL, binds) + INSERT INTO edges (from_id, to_id, name) + VALUES (?, ?, ?) + SQL + end + + def list(name, values) + values.each_with_index do |value, index| + binds = [node_id, visit(value), name, index] + database.execute(<<~SQL, binds) + INSERT INTO edges (from_id, to_id, name, list_index) + VALUES (?, ?, ?, ?) + SQL + end + end + + def node(node, _name) + previous = node_id + binds = [ + node.class.name.delete_prefix("SyntaxTree::"), + filepath, + node.location.start_line, + node.location.start_column + ] + + database.execute(<<~SQL, binds) + INSERT INTO nodes (type, path, line, column) + VALUES (?, ?, ?, ?) + SQL + + begin + @node_id = database.last_insert_row_id + yield + @node_id + ensure + @node_id = previous + end + end + + def text(name, value) + end + + def pairs(name, values) + values.each_with_index do |(key, value), index| + binds = [node_id, visit(key), "#{name}[0]", index] + database.execute(<<~SQL, binds) + INSERT INTO edges (from_id, to_id, name, list_index) + VALUES (?, ?, ?, ?) + SQL + + binds = [node_id, visit(value), "#{name}[1]", index] + database.execute(<<~SQL, binds) + INSERT INTO edges (from_id, to_id, name, list_index) + VALUES (?, ?, ?, ?) + SQL + end + end + end + + # Query for a specific type of node. + class TypeQuery + attr_reader :type + + def initialize(type) + @type = type + end + + def each(database, &block) + sql = "SELECT * FROM nodes WHERE type = ?" + database.execute(sql, type).each(&block) + end + end + + # Query for the attributes of a node, optionally also filtering by type. + class AttrQuery + attr_reader :type, :attrs + + def initialize(type, attrs) + @type = type + @attrs = attrs + end + + def each(database, &block) + joins = [] + binds = [] + + attrs.each do |name, query| + ids = query.each(database).map { |row| row[0] } + joins << <<~SQL + JOIN edges AS #{name} + ON #{name}.from_id = nodes.id + AND #{name}.name = ? + AND #{name}.to_id IN (#{(["?"] * ids.size).join(", ")}) + SQL + + binds.push(name).concat(ids) + end + + sql = +"SELECT nodes.* FROM nodes, edges #{joins.join(" ")}" + + if type + sql << " WHERE nodes.type = ?" + binds << type + end + + sql << " GROUP BY nodes.id" + database.execute(sql, binds).each(&block) + end + end + + # Query for the results of either query. + class OrQuery + attr_reader :left, :right + + def initialize(left, right) + @left = left + @right = right + end + + def each(database, &block) + left.each(database, &block) + right.each(database, &block) + end + end + + # A lazy query result. + class QueryResult + attr_reader :database, :query + + def initialize(database, query) + @database = database + @query = query + end + + def each(&block) + return enum_for(__method__) unless block_given? + query.each(database, &block) + end + end + + # A pattern matching expression that will be compiled into a query. + class Pattern + class CompilationError < StandardError + end + + attr_reader :query + + def initialize(query) + @query = query + end + + def compile + program = + begin + SyntaxTree.parse("case nil\nin #{query}\nend") + rescue Parser::ParseError + raise CompilationError, query + end + + compile_node(program.statements.body.first.consequent.pattern) + end + + private + + def compile_error(node) + raise CompilationError, PP.pp(node, +"").chomp + end + + # Shortcut for combining two queries into one that returns the results of + # if either query matches. + def combine_or(left, right) + OrQuery.new(left, right) + end + + # in foo | bar + def compile_binary(node) + compile_error(node) if node.operator != :| + + combine_or(compile_node(node.left), compile_node(node.right)) + end + + # in Ident + def compile_const(node) + value = node.value + + if SyntaxTree.const_defined?(value, false) + clazz = SyntaxTree.const_get(value) + TypeQuery.new(clazz.name.delete_prefix("SyntaxTree::")) + else + compile_error(node) + end + end + + # in SyntaxTree::Ident + def compile_const_path_ref(node) + parent = node.parent + if !parent.is_a?(SyntaxTree::VarRef) || + !parent.value.is_a?(SyntaxTree::Const) + compile_error(node) + end + + if parent.value.value == "SyntaxTree" + compile_node(node.constant) + else + compile_error(node) + end + end + + # in Ident[value: String] + def compile_hshptn(node) + compile_error(node) unless node.keyword_rest.nil? + + attrs = {} + node.keywords.each do |keyword, value| + compile_error(node) unless keyword.is_a?(SyntaxTree::Label) + attrs[keyword.value.chomp(":")] = compile_node(value) + end + + type = node.constant ? compile_node(node.constant).type : nil + AttrQuery.new(type, attrs) + end + + # in Foo + def compile_var_ref(node) + value = node.value + + if value.is_a?(SyntaxTree::Const) + compile_node(value) + else + compile_error(node) + end + end + + def compile_node(node) + case node + when SyntaxTree::Binary + compile_binary(node) + when SyntaxTree::Const + compile_const(node) + when SyntaxTree::ConstPathRef + compile_const_path_ref(node) + when SyntaxTree::HshPtn + compile_hshptn(node) + when SyntaxTree::VarRef + compile_var_ref(node) + else + compile_error(node) + end + end + end + + class Connection + attr_reader :raw_connection + + def initialize(raw_connection) + @raw_connection = raw_connection + end + + def execute(query, binds = []) + raw_connection.execute(query, binds) + end + + def index_file(filepath) + program = SyntaxTree.parse(SyntaxTree.read(filepath)) + program.accept(IndexingVisitor.new(self, filepath)) + end + + def last_insert_row_id + raw_connection.last_insert_row_id + end + + def prepare + raw_connection.execute(<<~SQL) + CREATE TABLE nodes ( + id integer primary key, + type varchar(20), + path varchar(200), + line integer, + column integer + ); + SQL + + raw_connection.execute(<<~SQL) + CREATE INDEX nodes_type ON nodes (type); + SQL + + raw_connection.execute(<<~SQL) + CREATE TABLE edges ( + id integer primary key, + from_id integer, + to_id integer, + name varchar(20), + list_index integer + ); + SQL + + raw_connection.execute(<<~SQL) + CREATE INDEX edges_name ON edges (name); + SQL + end + + def search(query) + QueryResult.new(self, Pattern.new(query).compile) + end + end + end +end From 5c379c05e9a62503276ed3b7921860ff55e76478 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Sat, 1 Apr 2023 14:08:31 -0400 Subject: [PATCH 02/31] Retrigger HEAD build From 66d70ea618994fe20b61efa0deacc0090302d710 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Mon, 3 Apr 2023 10:00:40 -0400 Subject: [PATCH 03/31] Remove obsolete blockiseq flag --- lib/syntax_tree/yarv/assembler.rb | 1 - lib/syntax_tree/yarv/calldata.rb | 34 ++++++++++++++++++------------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/lib/syntax_tree/yarv/assembler.rb b/lib/syntax_tree/yarv/assembler.rb index ac400506..b29c252a 100644 --- a/lib/syntax_tree/yarv/assembler.rb +++ b/lib/syntax_tree/yarv/assembler.rb @@ -31,7 +31,6 @@ def visit_string_literal(node) "FCALL" => CallData::CALL_FCALL, "VCALL" => CallData::CALL_VCALL, "ARGS_SIMPLE" => CallData::CALL_ARGS_SIMPLE, - "BLOCKISEQ" => CallData::CALL_BLOCKISEQ, "KWARG" => CallData::CALL_KWARG, "KW_SPLAT" => CallData::CALL_KW_SPLAT, "TAILCALL" => CallData::CALL_TAILCALL, diff --git a/lib/syntax_tree/yarv/calldata.rb b/lib/syntax_tree/yarv/calldata.rb index fadea61b..e35992f5 100644 --- a/lib/syntax_tree/yarv/calldata.rb +++ b/lib/syntax_tree/yarv/calldata.rb @@ -5,19 +5,26 @@ module YARV # This is an operand to various YARV instructions that represents the # information about a specific call site. class CallData - CALL_ARGS_SPLAT = 1 << 0 - CALL_ARGS_BLOCKARG = 1 << 1 - CALL_FCALL = 1 << 2 - CALL_VCALL = 1 << 3 - CALL_ARGS_SIMPLE = 1 << 4 - CALL_BLOCKISEQ = 1 << 5 - CALL_KWARG = 1 << 6 - CALL_KW_SPLAT = 1 << 7 - CALL_TAILCALL = 1 << 8 - CALL_SUPER = 1 << 9 - CALL_ZSUPER = 1 << 10 - CALL_OPT_SEND = 1 << 11 - CALL_KW_SPLAT_MUT = 1 << 12 + flags = %i[ + CALL_ARGS_SPLAT + CALL_ARGS_BLOCKARG + CALL_FCALL + CALL_VCALL + CALL_ARGS_SIMPLE + CALL_KWARG + CALL_KW_SPLAT + CALL_TAILCALL + CALL_SUPER + CALL_ZSUPER + CALL_OPT_SEND + CALL_KW_SPLAT_MUT + ] + + # Insert the legacy CALL_BLOCKISEQ flag for Ruby 3.2 and earlier. + flags.insert(5, :CALL_BLOCKISEQ) if RUBY_VERSION < "3.3" + + # Set the flags as constants on the class. + flags.each_with_index { |name, index| const_set(name, 1 << index) } attr_reader :method, :argc, :flags, :kw_arg @@ -50,7 +57,6 @@ def inspect names << :FCALL if flag?(CALL_FCALL) names << :VCALL if flag?(CALL_VCALL) names << :ARGS_SIMPLE if flag?(CALL_ARGS_SIMPLE) - names << :BLOCKISEQ if flag?(CALL_BLOCKISEQ) names << :KWARG if flag?(CALL_KWARG) names << :KW_SPLAT if flag?(CALL_KW_SPLAT) names << :TAILCALL if flag?(CALL_TAILCALL) From 1af7a77b56b584f27429e77dfde372620178bf11 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 18:00:17 +0000 Subject: [PATCH 04/31] Bump rubocop from 1.48.1 to 1.49.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.48.1 to 1.49.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.48.1...v1.49.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index ad2aeaa5..2f03cb6e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -12,24 +12,24 @@ GEM json (2.6.3) minitest (5.18.0) parallel (1.22.1) - parser (3.2.1.1) + parser (3.2.2.0) ast (~> 2.4.1) prettier_print (1.2.1) rainbow (3.1.1) rake (13.0.6) regexp_parser (2.7.0) rexml (3.2.5) - rubocop (1.48.1) + rubocop (1.49.0) json (~> 2.3) parallel (~> 1.10) parser (>= 3.2.0.0) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.26.0, < 2.0) + rubocop-ast (>= 1.28.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.27.0) + rubocop-ast (1.28.0) parser (>= 3.2.1.0) ruby-progressbar (1.13.0) simplecov (0.22.0) From c583a18d49bd5d60df9629d9a04869c115be9011 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Apr 2023 17:59:11 +0000 Subject: [PATCH 05/31] Bump rubocop from 1.49.0 to 1.50.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.49.0 to 1.50.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.49.0...v1.50.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 2f03cb6e..e0ce76bd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -19,7 +19,7 @@ GEM rake (13.0.6) regexp_parser (2.7.0) rexml (3.2.5) - rubocop (1.49.0) + rubocop (1.50.0) json (~> 2.3) parallel (~> 1.10) parser (>= 3.2.0.0) From f3f307de586caa5017994d4139248721d961444e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Apr 2023 17:58:56 +0000 Subject: [PATCH 06/31] Bump rubocop from 1.50.0 to 1.50.1 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.50.0 to 1.50.1. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.50.0...v1.50.1) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index e0ce76bd..f705736f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -19,7 +19,7 @@ GEM rake (13.0.6) regexp_parser (2.7.0) rexml (3.2.5) - rubocop (1.50.0) + rubocop (1.50.1) json (~> 2.3) parallel (~> 1.10) parser (>= 3.2.0.0) From ada73b3afe1269762ea75972bdf1a544f8d8c519 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 18:00:28 +0000 Subject: [PATCH 07/31] Bump rubocop from 1.50.1 to 1.50.2 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.50.1 to 1.50.2. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.50.1...v1.50.2) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index f705736f..8ee39a70 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -17,9 +17,9 @@ GEM prettier_print (1.2.1) rainbow (3.1.1) rake (13.0.6) - regexp_parser (2.7.0) + regexp_parser (2.8.0) rexml (3.2.5) - rubocop (1.50.1) + rubocop (1.50.2) json (~> 2.3) parallel (~> 1.10) parser (>= 3.2.0.0) From fefc783422e7b26a63510446faa426ac1e169b85 Mon Sep 17 00:00:00 2001 From: Felipe Vicente Date: Tue, 18 Apr 2023 23:14:34 -0300 Subject: [PATCH 08/31] Fix typo on README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a3f7d2d..113c0f29 100644 --- a/README.md +++ b/README.md @@ -297,7 +297,7 @@ Note that the output of the `match` CLI command creates a valid pattern that can ### write -This command will format the listed files and write that formatted version back to the source files. Note that this overwrites the original content, to be sure to be using a version control system. +This command will format the listed files and write that formatted version back to the source files. Note that this overwrites the original content, so be sure to be using a version control system. ```sh stree write path/to/file.rb From 5529448bd303d2fb7684c469dc20dc0031badec6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 18:02:16 +0000 Subject: [PATCH 09/31] Bump dependabot/fetch-metadata from 1.3.6 to 1.4.0 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.3.6 to 1.4.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.3.6...v1.4.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml index e54c9100..85e9fdb7 100644 --- a/.github/workflows/auto-merge.yml +++ b/.github/workflows/auto-merge.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v1.3.6 + uses: dependabot/fetch-metadata@v1.4.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" - name: Enable auto-merge for Dependabot PRs From 117c6b5f8e23070355420c57647b5b254abf7097 Mon Sep 17 00:00:00 2001 From: Andy Waite <13400+andyw8@users.noreply.github.com> Date: Wed, 19 Apr 2023 22:10:38 -0400 Subject: [PATCH 10/31] Update README.md - fix link for visitors --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a3f7d2d..3fdf0e6e 100644 --- a/README.md +++ b/README.md @@ -525,7 +525,7 @@ With visitors, you only define handlers for the nodes that you need. You can fin * call `visit(child)` with each child that you want to visit * call nothing if you're sure you don't want to descend further -There are a couple of visitors that ship with Syntax Tree that can be used as examples. They live in the [lib/syntax_tree/visitor](lib/syntax_tree/visitor) directory. +There are a couple of visitors that ship with Syntax Tree that can be used as examples. They live in the [lib/syntax_tree](lib/syntax_tree) directory. ### visit_method From c921b551f7caf51eb25c86a8b9e8a4e076ccd0a1 Mon Sep 17 00:00:00 2001 From: t-mario-y Date: Wed, 3 May 2023 19:23:15 +0900 Subject: [PATCH 11/31] rename left variables and files for plugin/disable_auto_ternary --- lib/syntax_tree/formatter.rb | 2 +- .../plugin/{disable_ternary.rb => disable_auto_ternary.rb} | 2 +- .../{disable_ternary_test.rb => disable_auto_ternary_test.rb} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename lib/syntax_tree/plugin/{disable_ternary.rb => disable_auto_ternary.rb} (70%) rename test/plugin/{disable_ternary_test.rb => disable_auto_ternary_test.rb} (100%) diff --git a/lib/syntax_tree/formatter.rb b/lib/syntax_tree/formatter.rb index 60858bf2..2b229885 100644 --- a/lib/syntax_tree/formatter.rb +++ b/lib/syntax_tree/formatter.rb @@ -60,7 +60,7 @@ def initialize( # constant. That constant is responsible for determining the default # disable ternary value. If it's defined, then we default to true. # Otherwise we default to false. - defined?(DISABLE_TERNARY) + defined?(DISABLE_AUTO_TERNARY) else disable_auto_ternary end diff --git a/lib/syntax_tree/plugin/disable_ternary.rb b/lib/syntax_tree/plugin/disable_auto_ternary.rb similarity index 70% rename from lib/syntax_tree/plugin/disable_ternary.rb rename to lib/syntax_tree/plugin/disable_auto_ternary.rb index 0cb48d84..dd38c783 100644 --- a/lib/syntax_tree/plugin/disable_ternary.rb +++ b/lib/syntax_tree/plugin/disable_auto_ternary.rb @@ -2,6 +2,6 @@ module SyntaxTree class Formatter - DISABLE_TERNARY = true + DISABLE_AUTO_TERNARY = true end end diff --git a/test/plugin/disable_ternary_test.rb b/test/plugin/disable_auto_ternary_test.rb similarity index 100% rename from test/plugin/disable_ternary_test.rb rename to test/plugin/disable_auto_ternary_test.rb From c91f495270168e9a6df1cb1029a29d6f60636c64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 18:00:15 +0000 Subject: [PATCH 12/31] Bump rubocop from 1.50.2 to 1.51.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.50.2 to 1.51.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.50.2...v1.51.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8ee39a70..0a60c87e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,15 +11,15 @@ GEM docile (1.4.0) json (2.6.3) minitest (5.18.0) - parallel (1.22.1) - parser (3.2.2.0) + parallel (1.23.0) + parser (3.2.2.1) ast (~> 2.4.1) prettier_print (1.2.1) rainbow (3.1.1) rake (13.0.6) regexp_parser (2.8.0) rexml (3.2.5) - rubocop (1.50.2) + rubocop (1.51.0) json (~> 2.3) parallel (~> 1.10) parser (>= 3.2.0.0) @@ -29,7 +29,7 @@ GEM rubocop-ast (>= 1.28.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.28.0) + rubocop-ast (1.28.1) parser (>= 3.2.1.0) ruby-progressbar (1.13.0) simplecov (0.22.0) From 692d23f169d203176e6a13f891b637f93bf1f33e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 18:07:01 +0000 Subject: [PATCH 13/31] Bump dependabot/fetch-metadata from 1.4.0 to 1.5.0 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.4.0...v1.5.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml index 85e9fdb7..d56afdfb 100644 --- a/.github/workflows/auto-merge.yml +++ b/.github/workflows/auto-merge.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v1.4.0 + uses: dependabot/fetch-metadata@v1.5.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" - name: Enable auto-merge for Dependabot PRs From ab0be75a1162cdcd525852f8d2bc0036ede40f3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 May 2023 18:01:45 +0000 Subject: [PATCH 14/31] Bump dependabot/fetch-metadata from 1.5.0 to 1.5.1 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.5.0 to 1.5.1. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.5.0...v1.5.1) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml index d56afdfb..57830be5 100644 --- a/.github/workflows/auto-merge.yml +++ b/.github/workflows/auto-merge.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v1.5.0 + uses: dependabot/fetch-metadata@v1.5.1 with: github-token: "${{ secrets.GITHUB_TOKEN }}" - name: Enable auto-merge for Dependabot PRs From b3457654ee196f752c7c936b426a99f6888b1608 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 31 May 2023 11:01:20 -0400 Subject: [PATCH 15/31] Support opt_newarray_send --- lib/syntax_tree/node.rb | 11 +- lib/syntax_tree/yarv/instruction_sequence.rb | 25 ++++- lib/syntax_tree/yarv/instructions.rb | 82 ++++----------- lib/syntax_tree/yarv/legacy.rb | 104 +++++++++++++++++++ test/compiler_test.rb | 6 ++ 5 files changed, 157 insertions(+), 71 deletions(-) diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index 54d132e6..ac6092ca 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -1299,7 +1299,7 @@ def format(q) end end - # [nil | VarRef] the optional constant wrapper + # [nil | VarRef | ConstPathRef] the optional constant wrapper attr_reader :constant # [Array[ Node ]] the regular positional arguments that this array @@ -2849,7 +2849,10 @@ def format_chain(q, children) # to print the operator trailing in order to keep it working. last_child = children.last if last_child.is_a?(CallNode) && last_child.message != :call && - last_child.message.comments.any? && last_child.operator + ( + (last_child.message.comments.any? && last_child.operator) || + (last_child.operator && last_child.operator.comments.any?) + ) q.format(CallOperatorFormatter.new(last_child.operator)) skip_operator = true else @@ -5413,7 +5416,7 @@ def ===(other) # end # class FndPtn < Node - # [nil | Node] the optional constant wrapper + # [nil | VarRef | ConstPathRef] the optional constant wrapper attr_reader :constant # [VarField] the splat on the left-hand side @@ -6035,7 +6038,7 @@ def format(q) end end - # [nil | Node] the optional constant wrapper + # [nil | VarRef | ConstPathRef] the optional constant wrapper attr_reader :constant # [Array[ [DynaSymbol | Label, nil | Node] ]] the set of tuples diff --git a/lib/syntax_tree/yarv/instruction_sequence.rb b/lib/syntax_tree/yarv/instruction_sequence.rb index 7ce7bcdd..df92799b 100644 --- a/lib/syntax_tree/yarv/instruction_sequence.rb +++ b/lib/syntax_tree/yarv/instruction_sequence.rb @@ -353,11 +353,27 @@ def specialize_instructions! next unless calldata.argc == 0 case calldata.method + when :min + node.value = + if RUBY_VERSION < "3.3" + Legacy::OptNewArrayMin.new(value.number) + else + OptNewArraySend.new(value.number, :min) + end + + node.next_node = next_node.next_node when :max - node.value = OptNewArrayMax.new(value.number) + node.value = + if RUBY_VERSION < "3.3" + Legacy::OptNewArrayMax.new(value.number) + else + OptNewArraySend.new(value.number, :max) + end + node.next_node = next_node.next_node - when :min - node.value = OptNewArrayMin.new(value.number) + when :hash + next if RUBY_VERSION < "3.3" + node.value = OptNewArraySend.new(value.number, :hash) node.next_node = next_node.next_node end when PutObject, PutString @@ -1174,6 +1190,9 @@ def self.from(source, options = Compiler::Options.new, parent_iseq = nil) when :opt_newarray_min iseq.newarray(opnds[0]) iseq.send(YARV.calldata(:min)) + when :opt_newarray_send + iseq.newarray(opnds[0]) + iseq.send(CallData.new(opnds[1])) when :opt_neq iseq.push( OptNEq.new(CallData.from(opnds[0]), CallData.from(opnds[1])) diff --git a/lib/syntax_tree/yarv/instructions.rb b/lib/syntax_tree/yarv/instructions.rb index ceb237dc..ffeebe65 100644 --- a/lib/syntax_tree/yarv/instructions.rb +++ b/lib/syntax_tree/yarv/instructions.rb @@ -3818,9 +3818,10 @@ def call(vm) # ### Summary # - # `opt_newarray_max` is a specialization that occurs when the `max` method - # is called on an array literal. It pops the values of the array off the - # stack and pushes on the result. + # `opt_newarray_send` is a specialization that occurs when a dynamic array + # literal is created and immediately sent the `min`, `max`, or `hash` + # methods. It pops the values of the array off the stack and pushes on the + # result of the method call. # # ### Usage # @@ -3828,83 +3829,36 @@ def call(vm) # [a, b, c].max # ~~~ # - class OptNewArrayMax < Instruction - attr_reader :number - - def initialize(number) - @number = number - end - - def disasm(fmt) - fmt.instruction("opt_newarray_max", [fmt.object(number)]) - end - - def to_a(_iseq) - [:opt_newarray_max, number] - end - - def deconstruct_keys(_keys) - { number: number } - end - - def ==(other) - other.is_a?(OptNewArrayMax) && other.number == number - end - - def length - 2 - end - - def pops - number - end + class OptNewArraySend < Instruction + attr_reader :number, :method - def pushes - 1 - end - - def call(vm) - vm.push(vm.pop(number).max) - end - end - - # ### Summary - # - # `opt_newarray_min` is a specialization that occurs when the `min` method - # is called on an array literal. It pops the values of the array off the - # stack and pushes on the result. - # - # ### Usage - # - # ~~~ruby - # [a, b, c].min - # ~~~ - # - class OptNewArrayMin < Instruction - attr_reader :number - - def initialize(number) + def initialize(number, method) @number = number + @method = method end def disasm(fmt) - fmt.instruction("opt_newarray_min", [fmt.object(number)]) + fmt.instruction( + "opt_newarray_send", + [fmt.object(number), fmt.object(method)] + ) end def to_a(_iseq) - [:opt_newarray_min, number] + [:opt_newarray_send, number, method] end def deconstruct_keys(_keys) - { number: number } + { number: number, method: method } end def ==(other) - other.is_a?(OptNewArrayMin) && other.number == number + other.is_a?(OptNewArraySend) && other.number == number && + other.method == method end def length - 2 + 3 end def pops @@ -3916,7 +3870,7 @@ def pushes end def call(vm) - vm.push(vm.pop(number).min) + vm.push(vm.pop(number).__send__(method)) end end diff --git a/lib/syntax_tree/yarv/legacy.rb b/lib/syntax_tree/yarv/legacy.rb index e20729d9..8715993a 100644 --- a/lib/syntax_tree/yarv/legacy.rb +++ b/lib/syntax_tree/yarv/legacy.rb @@ -124,6 +124,110 @@ def falls_through? end end + # ### Summary + # + # `opt_newarray_max` is a specialization that occurs when the `max` method + # is called on an array literal. It pops the values of the array off the + # stack and pushes on the result. + # + # ### Usage + # + # ~~~ruby + # [a, b, c].max + # ~~~ + # + class OptNewArrayMax < Instruction + attr_reader :number + + def initialize(number) + @number = number + end + + def disasm(fmt) + fmt.instruction("opt_newarray_max", [fmt.object(number)]) + end + + def to_a(_iseq) + [:opt_newarray_max, number] + end + + def deconstruct_keys(_keys) + { number: number } + end + + def ==(other) + other.is_a?(OptNewArrayMax) && other.number == number + end + + def length + 2 + end + + def pops + number + end + + def pushes + 1 + end + + def call(vm) + vm.push(vm.pop(number).max) + end + end + + # ### Summary + # + # `opt_newarray_min` is a specialization that occurs when the `min` method + # is called on an array literal. It pops the values of the array off the + # stack and pushes on the result. + # + # ### Usage + # + # ~~~ruby + # [a, b, c].min + # ~~~ + # + class OptNewArrayMin < Instruction + attr_reader :number + + def initialize(number) + @number = number + end + + def disasm(fmt) + fmt.instruction("opt_newarray_min", [fmt.object(number)]) + end + + def to_a(_iseq) + [:opt_newarray_min, number] + end + + def deconstruct_keys(_keys) + { number: number } + end + + def ==(other) + other.is_a?(OptNewArrayMin) && other.number == number + end + + def length + 2 + end + + def pops + number + end + + def pushes + 1 + end + + def call(vm) + vm.push(vm.pop(number).min) + end + end + # ### Summary # # `opt_setinlinecache` sets an inline cache for a constant lookup. It pops diff --git a/test/compiler_test.rb b/test/compiler_test.rb index 1922f8c6..ca3e8dde 100644 --- a/test/compiler_test.rb +++ b/test/compiler_test.rb @@ -311,6 +311,12 @@ class CompilerTest < Minitest::Test "[1, 2, 3].min", "[foo, bar, baz].min", "[foo, bar, baz].min(1)", + "[1, 2, 3].hash", + "[foo, bar, baz].hash", + "[foo, bar, baz].hash(1)", + "[1, 2, 3].foo", + "[foo, bar, baz].foo", + "[foo, bar, baz].foo(1)", "[**{ x: true }][0][:x]", # Core method calls "alias foo bar", From 32d6d8a62cacfdd220e47defe5a2d1a445541087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Barri=C3=A9?= Date: Thu, 1 Jun 2023 14:52:20 +0200 Subject: [PATCH 16/31] Always use do/end for multiline lambdas Previously lambda blocks inside a Command/CommandCall were always using braces, even when multiline. --- lib/syntax_tree/node.rb | 33 +++++++-------------------------- test/fixtures/lambda.rb | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index ac6092ca..a2c78677 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -7210,36 +7210,17 @@ def format(q) q.text(" ") q .if_break do - force_parens = - q.parents.any? do |node| - node.is_a?(Command) || node.is_a?(CommandCall) - end - - if force_parens - q.text("{") + q.text("do") - unless statements.empty? - q.indent do - q.breakable_space - q.format(statements) - end + unless statements.empty? + q.indent do q.breakable_space + q.format(statements) end - - q.text("}") - else - q.text("do") - - unless statements.empty? - q.indent do - q.breakable_space - q.format(statements) - end - end - - q.breakable_space - q.text("end") end + + q.breakable_space + q.text("end") end .if_flat do q.text("{") diff --git a/test/fixtures/lambda.rb b/test/fixtures/lambda.rb index 5dba3be3..8b922ef0 100644 --- a/test/fixtures/lambda.rb +++ b/test/fixtures/lambda.rb @@ -80,3 +80,31 @@ -> do # comment1 # comment2 end +% # multiline lambda in a command +command "arg" do + -> { + multi + line + } +end +- +command "arg" do + -> do + multi + line + end +end +% # multiline lambda in a command call +command.call "arg" do + -> { + multi + line + } +end +- +command.call "arg" do + -> do + multi + line + end +end From 4e94775e6d27d9407f554cb6728e71a330511004 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:00:06 +0000 Subject: [PATCH 17/31] Bump minitest from 5.18.0 to 5.18.1 Bumps [minitest](https://github.com/minitest/minitest) from 5.18.0 to 5.18.1. - [Changelog](https://github.com/minitest/minitest/blob/master/History.rdoc) - [Commits](https://github.com/minitest/minitest/compare/v5.18.0...v5.18.1) --- updated-dependencies: - dependency-name: minitest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0a60c87e..2bd42028 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -10,7 +10,7 @@ GEM ast (2.4.2) docile (1.4.0) json (2.6.3) - minitest (5.18.0) + minitest (5.18.1) parallel (1.23.0) parser (3.2.2.1) ast (~> 2.4.1) From 7fc6be2cc612f8f56416204454621ca47f2036f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Jun 2023 17:10:53 +0000 Subject: [PATCH 18/31] Bump dependabot/fetch-metadata from 1.5.1 to 1.6.0 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.5.1 to 1.6.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.5.1...v1.6.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml index 57830be5..8ca265e0 100644 --- a/.github/workflows/auto-merge.yml +++ b/.github/workflows/auto-merge.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v1.5.1 + uses: dependabot/fetch-metadata@v1.6.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" - name: Enable auto-merge for Dependabot PRs From 1d4e6a5b07110e34346eeaa5d6db51656722666f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jul 2023 17:38:22 +0000 Subject: [PATCH 19/31] Bump actions/upload-pages-artifact from 1 to 2 Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 1 to 2. - [Release notes](https://github.com/actions/upload-pages-artifact/releases) - [Commits](https://github.com/actions/upload-pages-artifact/compare/v1...v2) --- updated-dependencies: - dependency-name: actions/upload-pages-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/gh-pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 5b662631..f2419d00 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -39,7 +39,7 @@ jobs: rdoc --main README.md --op _site --exclude={Gemfile,Rakefile,"coverage/*","vendor/*","bin/*","test/*","tmp/*"} cp -r doc _site/doc - name: Upload artifact - uses: actions/upload-pages-artifact@v1 + uses: actions/upload-pages-artifact@v2 # Deployment job deploy: From 9e8a2c3db7f6bb4f862c3c87c8d77198db613589 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Fri, 14 Jul 2023 11:46:48 -0400 Subject: [PATCH 20/31] Fix rubocop build --- .rubocop.yml | 5 ++++- Gemfile.lock | 14 +++++++++----- lib/syntax_tree/reflection.rb | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index c1c17001..2142296f 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -7,7 +7,7 @@ AllCops: SuggestExtensions: false TargetRubyVersion: 2.7 Exclude: - - '{.git,.github,bin,coverage,pkg,sorbet,spec,test/fixtures,vendor,tmp}/**/*' + - '{.git,.github,.ruby-lsp,bin,coverage,doc,pkg,sorbet,spec,test/fixtures,vendor,tmp}/**/*' - test.rb Gemspec/DevelopmentDependencies: @@ -154,6 +154,9 @@ Style/ParallelAssignment: Style/PerlBackrefs: Enabled: false +Style/RedundantArrayConstructor: + Enabled: false + Style/SafeNavigation: Enabled: false diff --git a/Gemfile.lock b/Gemfile.lock index 2bd42028..a26c0e17 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -10,26 +10,30 @@ GEM ast (2.4.2) docile (1.4.0) json (2.6.3) + language_server-protocol (3.17.0.3) minitest (5.18.1) parallel (1.23.0) - parser (3.2.2.1) + parser (3.2.2.3) ast (~> 2.4.1) + racc prettier_print (1.2.1) + racc (1.7.1) rainbow (3.1.1) rake (13.0.6) - regexp_parser (2.8.0) + regexp_parser (2.8.1) rexml (3.2.5) - rubocop (1.51.0) + rubocop (1.54.2) json (~> 2.3) + language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.0.0) + parser (>= 3.2.2.3) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) rubocop-ast (>= 1.28.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.28.1) + rubocop-ast (1.29.0) parser (>= 3.2.1.0) ruby-progressbar (1.13.0) simplecov (0.22.0) diff --git a/lib/syntax_tree/reflection.rb b/lib/syntax_tree/reflection.rb index aa7b85b6..6955aa21 100644 --- a/lib/syntax_tree/reflection.rb +++ b/lib/syntax_tree/reflection.rb @@ -64,7 +64,7 @@ def inspect class << self def parse(comment) - comment = comment.gsub(/\n/, " ") + comment = comment.gsub("\n", " ") unless comment.start_with?("[") raise "Comment does not start with a bracket: #{comment.inspect}" From fcc974a2e91f183de79d1d038aba9725e327c604 Mon Sep 17 00:00:00 2001 From: Vinicius Stock Date: Wed, 12 Jul 2023 13:48:15 -0600 Subject: [PATCH 21/31] Fix WithScope for destructured post arguments --- lib/syntax_tree/node.rb | 4 ++-- lib/syntax_tree/with_scope.rb | 5 +---- test/with_scope_test.rb | 36 +++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index a2c78677..3b676552 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -8277,8 +8277,8 @@ def format(q) # parameter attr_reader :rest - # [Array[ Ident ]] any positional parameters that exist after a rest - # parameter + # [Array[ Ident | MLHSParen ]] any positional parameters that exist after a + # rest parameter attr_reader :posts # [Array[ [ Label, nil | Node ] ]] any keyword parameters and their diff --git a/lib/syntax_tree/with_scope.rb b/lib/syntax_tree/with_scope.rb index c479fd3e..8c4908f3 100644 --- a/lib/syntax_tree/with_scope.rb +++ b/lib/syntax_tree/with_scope.rb @@ -152,10 +152,7 @@ def visit_def(node) # arguments. def visit_params(node) add_argument_definitions(node.requireds) - - node.posts.each do |param| - current_scope.add_local_definition(param, :argument) - end + add_argument_definitions(node.posts) node.keywords.each do |param| current_scope.add_local_definition(param.first, :argument) diff --git a/test/with_scope_test.rb b/test/with_scope_test.rb index 5bf276be..6b48d17d 100644 --- a/test/with_scope_test.rb +++ b/test/with_scope_test.rb @@ -154,6 +154,42 @@ def foo(a) assert_argument(collector, "a", definitions: [1], usages: [2]) end + def test_collecting_methods_with_destructured_post_arguments + collector = Collector.collect(<<~RUBY) + def foo(optional = 1, (bin, bag)) + end + RUBY + + assert_equal(3, collector.arguments.length) + assert_argument(collector, "optional", definitions: [1], usages: []) + assert_argument(collector, "bin", definitions: [1], usages: []) + assert_argument(collector, "bag", definitions: [1], usages: []) + end + + def test_collecting_methods_with_desctructured_post_using_splat + collector = Collector.collect(<<~RUBY) + def foo(optional = 1, (bin, bag, *)) + end + RUBY + + assert_equal(3, collector.arguments.length) + assert_argument(collector, "optional", definitions: [1], usages: []) + assert_argument(collector, "bin", definitions: [1], usages: []) + assert_argument(collector, "bag", definitions: [1], usages: []) + end + + def test_collecting_methods_with_nested_desctructured + collector = Collector.collect(<<~RUBY) + def foo(optional = 1, (bin, (bag))) + end + RUBY + + assert_equal(3, collector.arguments.length) + assert_argument(collector, "optional", definitions: [1], usages: []) + assert_argument(collector, "bin", definitions: [1], usages: []) + assert_argument(collector, "bag", definitions: [1], usages: []) + end + def test_collecting_singleton_method_arguments collector = Collector.collect(<<~RUBY) def self.foo(a) From c8bff434e03bfb1ae24ad344e47bf712f8f83846 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jul 2023 17:06:01 +0000 Subject: [PATCH 22/31] Bump rubocop from 1.54.2 to 1.55.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.54.2 to 1.55.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.54.2...v1.55.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index a26c0e17..b99cf938 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -22,7 +22,7 @@ GEM rake (13.0.6) regexp_parser (2.8.1) rexml (3.2.5) - rubocop (1.54.2) + rubocop (1.55.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -30,7 +30,7 @@ GEM rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.28.0, < 2.0) + rubocop-ast (>= 1.28.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.29.0) From 54aced14aa95c26b3810e4b6db11ac40eb87ce1d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Jul 2023 17:14:46 +0000 Subject: [PATCH 23/31] Bump minitest from 5.18.1 to 5.19.0 Bumps [minitest](https://github.com/minitest/minitest) from 5.18.1 to 5.19.0. - [Changelog](https://github.com/minitest/minitest/blob/master/History.rdoc) - [Commits](https://github.com/minitest/minitest/compare/v5.18.1...v5.19.0) --- updated-dependencies: - dependency-name: minitest dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index b99cf938..ea447d12 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,7 @@ GEM docile (1.4.0) json (2.6.3) language_server-protocol (3.17.0.3) - minitest (5.18.1) + minitest (5.19.0) parallel (1.23.0) parser (3.2.2.3) ast (~> 2.4.1) From 4b554b38cebf1e1ac33e93e0bb0e8e2d27f168cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Jul 2023 17:22:03 +0000 Subject: [PATCH 24/31] Bump rubocop from 1.55.0 to 1.55.1 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.55.0 to 1.55.1. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.55.0...v1.55.1) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index ea447d12..5ac7c4a5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -21,8 +21,8 @@ GEM rainbow (3.1.1) rake (13.0.6) regexp_parser (2.8.1) - rexml (3.2.5) - rubocop (1.55.0) + rexml (3.2.6) + rubocop (1.55.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) From 16125ec48cc4bbac72515f283e0cb2387351aaec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Aug 2023 17:27:44 +0000 Subject: [PATCH 25/31] Bump rubocop from 1.55.1 to 1.56.0 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.55.1 to 1.56.0. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.55.1...v1.56.0) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5ac7c4a5..d8d12e74 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,6 +8,7 @@ GEM remote: https://rubygems.org/ specs: ast (2.4.2) + base64 (0.1.1) docile (1.4.0) json (2.6.3) language_server-protocol (3.17.0.3) @@ -22,7 +23,8 @@ GEM rake (13.0.6) regexp_parser (2.8.1) rexml (3.2.6) - rubocop (1.55.1) + rubocop (1.56.0) + base64 (~> 0.1.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) From b3faf1070b888aad1d53132e0121b966442893d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Aug 2023 17:43:26 +0000 Subject: [PATCH 26/31] Bump rubocop from 1.56.0 to 1.56.1 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.56.0 to 1.56.1. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.56.0...v1.56.1) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index d8d12e74..cb658916 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -23,7 +23,7 @@ GEM rake (13.0.6) regexp_parser (2.8.1) rexml (3.2.6) - rubocop (1.56.0) + rubocop (1.56.1) base64 (~> 0.1.1) json (~> 2.3) language_server-protocol (>= 3.17.0) From 385b07bf7128e280224f5633e83681f7901f1448 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 17:55:06 +0000 Subject: [PATCH 27/31] Bump rubocop from 1.56.1 to 1.56.2 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.56.1 to 1.56.2. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.56.1...v1.56.2) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index cb658916..939a6e22 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -23,7 +23,7 @@ GEM rake (13.0.6) regexp_parser (2.8.1) rexml (3.2.6) - rubocop (1.56.1) + rubocop (1.56.2) base64 (~> 0.1.1) json (~> 2.3) language_server-protocol (>= 3.17.0) From 4629899aaae5ab5114fdea2c86ae45da5bafe807 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 17:46:15 +0000 Subject: [PATCH 28/31] Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/gh-pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index f2419d00..4bbfc0a2 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Pages uses: actions/configure-pages@v3 - name: Set up Ruby From b92a2cff094cb8f360b0dea02365b7ed53878809 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 17:55:45 +0000 Subject: [PATCH 29/31] Bump minitest from 5.19.0 to 5.20.0 Bumps [minitest](https://github.com/minitest/minitest) from 5.19.0 to 5.20.0. - [Changelog](https://github.com/minitest/minitest/blob/master/History.rdoc) - [Commits](https://github.com/minitest/minitest/compare/v5.19.0...v5.20.0) --- updated-dependencies: - dependency-name: minitest dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 939a6e22..53021ebb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -12,7 +12,7 @@ GEM docile (1.4.0) json (2.6.3) language_server-protocol (3.17.0.3) - minitest (5.19.0) + minitest (5.20.0) parallel (1.23.0) parser (3.2.2.3) ast (~> 2.4.1) From 55ecb2b29ea8405f9674424238ff74b7ba1f2267 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 17:14:36 +0000 Subject: [PATCH 30/31] Bump rubocop from 1.56.2 to 1.56.3 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.56.2 to 1.56.3. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.56.2...v1.56.3) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 53021ebb..1e97c593 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -23,7 +23,7 @@ GEM rake (13.0.6) regexp_parser (2.8.1) rexml (3.2.6) - rubocop (1.56.2) + rubocop (1.56.3) base64 (~> 0.1.1) json (~> 2.3) language_server-protocol (>= 3.17.0) From 68d34667370d55953a6fb53e8f5077917357d6c6 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 20 Sep 2023 10:58:33 -0400 Subject: [PATCH 31/31] Bump to version 6.2.0 --- CHANGELOG.md | 15 ++++++++++++++- Gemfile.lock | 2 +- lib/syntax_tree/version.rb | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 273d4003..1beac42f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a ## [Unreleased] +## [6.2.0] - 2023-09-20 + +### Added + +- Fix `WithScope` for destructured post arguments. + +### Changed + +- Always use `do`/`end` for multi-line lambdas. + ## [6.1.1] - 2023-03-21 ### Changed @@ -603,7 +613,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a - 🎉 Initial release! 🎉 -[unreleased]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v6.0.2...HEAD +[unreleased]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v6.2.0...HEAD +[6.2.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v6.1.1...v6.2.0 +[6.1.1]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v6.1.0...v6.1.1 +[6.1.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v6.0.2...v6.1.0 [6.0.2]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v6.0.1...v6.0.2 [6.0.1]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v6.0.0...v6.0.1 [6.0.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v5.3.0...v6.0.0 diff --git a/Gemfile.lock b/Gemfile.lock index 1e97c593..a9fc60b1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - syntax_tree (6.1.1) + syntax_tree (6.2.0) prettier_print (>= 1.2.0) GEM diff --git a/lib/syntax_tree/version.rb b/lib/syntax_tree/version.rb index ad87d3e1..51599f77 100644 --- a/lib/syntax_tree/version.rb +++ b/lib/syntax_tree/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module SyntaxTree - VERSION = "6.1.1" + VERSION = "6.2.0" end