diff --git a/CHANGELOG.md b/CHANGELOG.md index 26e538c3..eeb9231f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a ## [Unreleased] +## [2.4.1] - 2022-05-10 + +- Fix nested hash patterns from accidentally adding a `then` to their output. + ## [2.4.0] - 2022-05-07 ### Added @@ -209,7 +213,8 @@ 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/v2.4.0...HEAD +[unreleased]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.4.1...HEAD +[2.4.1]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.4.0...v2.4.1 [2.4.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.3.1...v2.4.0 [2.3.1]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.3.0...v2.3.1 [2.3.0]: https://github.com/ruby-syntax-tree/syntax_tree/compare/v2.2.0...v2.3.0 diff --git a/Gemfile.lock b/Gemfile.lock index 8357fd92..b4eebdd4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - syntax_tree (2.4.0) + syntax_tree (2.4.1) GEM remote: https://rubygems.org/ diff --git a/lib/syntax_tree/node.rb b/lib/syntax_tree/node.rb index d153ef78..fdb40631 100644 --- a/lib/syntax_tree/node.rb +++ b/lib/syntax_tree/node.rb @@ -5064,13 +5064,16 @@ def format(q) parts = keywords.map { |(key, value)| KeywordFormatter.new(key, value) } parts << KeywordRestFormatter.new(keyword_rest) if keyword_rest + nested = PATTERNS.include?(q.parent.class) contents = -> do q.group { q.seplist(parts) { |part| q.format(part, stackable: false) } } # If there isn't a constant, and there's a blank keyword_rest, then we # have an plain ** that needs to have a `then` after it in order to # parse correctly on the next parse. - q.text(" then") if !constant && keyword_rest && keyword_rest.value.nil? + if !constant && keyword_rest && keyword_rest.value.nil? && !nested + q.text(" then") + end end # If there is a constant, we're going to format to have the constant name @@ -5097,7 +5100,7 @@ def format(q) # If there's only one pair, then we'll just print the contents provided # we're not inside another pattern. - if !PATTERNS.include?(q.parent.class) && parts.size == 1 + if !nested && parts.size == 1 contents.call return end diff --git a/lib/syntax_tree/parser.rb b/lib/syntax_tree/parser.rb index 75d3c322..f5ffe47d 100644 --- a/lib/syntax_tree/parser.rb +++ b/lib/syntax_tree/parser.rb @@ -1671,9 +1671,15 @@ def on_heredoc_end(value) # (nil | VarField) keyword_rest # ) -> HshPtn def on_hshptn(constant, keywords, keyword_rest) - # Create an artificial VarField if we find an extra ** on the end - if !keyword_rest && (token = find_token(Op, "**", consume: false)) + if keyword_rest + # We're doing this to delete the token from the list so that it doesn't + # confuse future patterns by thinking they have an extra ** on the end. + find_token(Op, "**") + elsif (token = find_token(Op, "**", consume: false)) tokens.delete(token) + + # Create an artificial VarField if we find an extra ** on the end. This + # means the formatting will be a little more consistent. keyword_rest = VarField.new(value: nil, location: token.location) end diff --git a/lib/syntax_tree/version.rb b/lib/syntax_tree/version.rb index 894ff1b7..fbecb604 100644 --- a/lib/syntax_tree/version.rb +++ b/lib/syntax_tree/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module SyntaxTree - VERSION = "2.4.0" + VERSION = "2.4.1" end diff --git a/test/fixtures/hshptn.rb b/test/fixtures/hshptn.rb index 2935f9c1..7a35b4d0 100644 --- a/test/fixtures/hshptn.rb +++ b/test/fixtures/hshptn.rb @@ -66,3 +66,8 @@ case foo in **nil end +% +case foo +in bar, { baz:, **nil } +in qux: +end