Hello community,

here is the log from the commit of package rubygem-rubocop-ast for 
openSUSE:Factory checked in at 2020-08-18 14:00:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-rubocop-ast (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-rubocop-ast.new.3399 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-rubocop-ast"

Tue Aug 18 14:00:50 2020 rev:2 rq:827558 version:0.1.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/rubygem-rubocop-ast/rubygem-rubocop-ast.changes  
2020-06-22 17:46:56.202041019 +0200
+++ 
/work/SRC/openSUSE:Factory/.rubygem-rubocop-ast.new.3399/rubygem-rubocop-ast.changes
        2020-08-18 14:03:31.018326238 +0200
@@ -1,0 +2,19 @@
+Mon Aug 17 14:35:55 UTC 2020 - Dan Čermák <[email protected]>
+
+- New upstream release 0.1.0
+
+  New features
+
+  * #36: Add post_condition_loop? and loop_keyword? for Node. (@fatkodima)
+  * #38: Add helpers allowing to check whether the method is a nonmutating 
operator method or a nonmutating method of several core classes. (@fatkodima)
+  * #37: Add enumerable_method? for MethodIdentifierPredicates. (@fatkodima)
+  * #4: Add interpolation? for RegexpNode. (@tejasbubane)
+  * #20: Add option predicates for RegexpNode. (@owst)
+  * #11: Add argument_type? method to make it easy to recognize argument 
nodes. (@tejasbubane)
+  * #31: NodePattern now uses param === node to match params, which allows 
Regexp, Proc, Set in addition to Nodes and literals. (@marcandre)
+  * #41: Add delimiters and related predicates for RegexpNode. (@owst)
+  * #46: Basic support for non-legacy AST output from parser. Note that there 
is no support (yet) in main RuboCop gem. Expect emit_forward_arg to be set to 
true in v1.0 (@marcandre)
+  * #48: Support Parser::Ruby28 for Ruby 2.8 (3.0) parser (experimental). 
(@koic)
+  * #35: NodePattern now accepts %named_param and %CONST. The macros 
def_node_pattern and def_node_search accept default named parameters. 
(@marcandre)
+
+-------------------------------------------------------------------

Old:
----
  rubocop-ast-0.0.3.gem

New:
----
  rubocop-ast-0.1.0.gem

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rubygem-rubocop-ast.spec ++++++
--- /var/tmp/diff_new_pack.INAe3W/_old  2020-08-18 14:03:31.866326618 +0200
+++ /var/tmp/diff_new_pack.INAe3W/_new  2020-08-18 14:03:31.870326620 +0200
@@ -25,7 +25,7 @@
 # of those fields
 #
 Name:           rubygem-rubocop-ast
-Version:        0.0.3
+Version:        0.1.0
 Release:        0
 Summary:        RuboCop tools to deal with Ruby code AST
 License:        MIT

++++++ rubocop-ast-0.0.3.gem -> rubocop-ast-0.1.0.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/README.md new/README.md
--- old/README.md       2020-05-15 09:39:32.000000000 +0200
+++ new/README.md       2020-06-26 06:40:59.000000000 +0200
@@ -2,12 +2,15 @@
 
 [![Gem 
Version](https://badge.fury.io/rb/rubocop-ast.svg)](https://badge.fury.io/rb/rubocop-ast)
 
[![CI](https://github.com/rubocop-hq/rubocop-ast/workflows/CI/badge.svg)](https://github.com/rubocop-hq/rubocop-ast/actions?query=workflow%3ACI)
+[![Test 
Coverage](https://api.codeclimate.com/v1/badges/a29666e6373bc41bc0a9/test_coverage)](https://codeclimate.com/github/rubocop-hq/rubocop-ast/test_coverage)
+[![Maintainability](https://api.codeclimate.com/v1/badges/a29666e6373bc41bc0a9/maintainability)](https://codeclimate.com/github/rubocop-hq/rubocop-ast/maintainability)
 
 Contains the classes needed by 
[RuboCop](https://github.com/rubocop-hq/rubocop) to deal with Ruby's AST, in 
particular:
 * `RuboCop::AST::Node`
-* `RuboCop::AST::NodePattern` ([doc](manual/node_pattern.md))
+* `RuboCop::AST::NodePattern` 
([doc](docs/modules/ROOT/pages/node_pattern.adoc))
 
-This gem may be used independently from the main RuboCop gem.
+This gem may be used independently from the main RuboCop gem. It was extracted 
from RuboCop in version 0.84 and its only
+dependency is the `parser` gem, which `rubocop-ast` extends.
 
 ## Installation
 
@@ -25,7 +28,17 @@
 
 ## Usage
 
-Refer to the documentation of `RuboCop::AST::Node` and 
[`RuboCop::AST::NodePattern`](manual/node_pattern.md)
+Refer to the documentation of `RuboCop::AST::Node` and 
[`RuboCop::AST::NodePattern`](docs/modules/ROOT/pages/node_pattern.adoc)
+
+### Parser compatibility switches
+
+The main `RuboCop` gem uses [legacy AST output from 
parser](https://github.com/whitequark/parser/#usage).
+This gem is meant to be compatible with all settings. For example, to have `-> 
{ ... }` emitted
+as `LambdaNode` instead of `SendNode`:
+
+```ruby
+RuboCop::AST::Builder.emit_lambda = true
+```
 
 ## Contributing
 
Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast/builder.rb 
new/lib/rubocop/ast/builder.rb
--- old/lib/rubocop/ast/builder.rb      2020-05-15 09:39:32.000000000 +0200
+++ new/lib/rubocop/ast/builder.rb      2020-06-26 06:40:59.000000000 +0200
@@ -35,9 +35,12 @@
         hash:         HashNode,
         if:           IfNode,
         int:          IntNode,
+        index:        IndexNode,
+        indexasgn:    IndexasgnNode,
         irange:       RangeNode,
         erange:       RangeNode,
         kwsplat:      KeywordSplatNode,
+        lambda:       LambdaNode,
         module:       ModuleNode,
         or:           OrNode,
         pair:         PairNode,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast/node/def_node.rb 
new/lib/rubocop/ast/node/def_node.rb
--- old/lib/rubocop/ast/node/def_node.rb        2020-05-15 09:39:32.000000000 
+0200
+++ new/lib/rubocop/ast/node/def_node.rb        2020-06-26 06:40:59.000000000 
+0200
@@ -24,7 +24,7 @@
       #
       # @return [Boolean] whether the `def` node uses argument forwarding
       def argument_forwarding?
-        arguments.any?(&:forward_args_type?)
+        arguments.any?(&:forward_args_type?) || 
arguments.any?(&:forward_arg_type?)
       end
 
       # The name of the defined method as a symbol.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast/node/forward_args_node.rb 
new/lib/rubocop/ast/node/forward_args_node.rb
--- old/lib/rubocop/ast/node/forward_args_node.rb       2020-05-15 
09:39:32.000000000 +0200
+++ new/lib/rubocop/ast/node/forward_args_node.rb       2020-06-26 
06:40:59.000000000 +0200
@@ -5,6 +5,21 @@
     # A node extension for `forward-args` nodes. This will be used in place
     # of a plain node when the builder constructs the AST, making its methods
     # available to all `forward-args` nodes within RuboCop.
+    #
+    # Not used with modern emitters:
+    #
+    #   $ ruby-parse -e "def foo(...); end"
+    #   (def :foo
+    #     (args
+    #       (forward-arg)) nil)
+    #   $ ruby-parse --legacy -e "->(foo) { bar }"
+    #   (def :foo
+    #     (forward-args) nil)
+    #
+    # Note the extra 's' with legacy form.
+    #
+    # The main RuboCop runs in legacy mode; this node is only used
+    # if user `AST::Builder.modernize` or `AST::Builder.emit_lambda=true`
     class ForwardArgsNode < Node
       include CollectionNode
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast/node/index_node.rb 
new/lib/rubocop/ast/node/index_node.rb
--- old/lib/rubocop/ast/node/index_node.rb      1970-01-01 01:00:00.000000000 
+0100
+++ new/lib/rubocop/ast/node/index_node.rb      2020-06-26 06:40:59.000000000 
+0200
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module RuboCop
+  module AST
+    # Used for modern support only!
+    # Not as thoroughly tested as legacy equivalent
+    #
+    #   $ ruby-parse -e "foo[:bar]"
+    #   (index
+    #     (send nil :foo)
+    #     (sym :bar))
+    #   $ ruby-parse --legacy -e "foo[:bar]"
+    #   (send
+    #     (send nil :foo) :[]
+    #     (sym :bar))
+    #
+    # The main RuboCop runs in legacy mode; this node is only used
+    # if user `AST::Builder.modernize` or `AST::Builder.emit_index=true`
+    class IndexNode < Node
+      include ParameterizedNode
+      include MethodDispatchNode
+
+      # For similarity with legacy mode
+      def attribute_accessor?
+        false
+      end
+
+      # For similarity with legacy mode
+      def assignment_method?
+        false
+      end
+
+      # For similarity with legacy mode
+      def method_name
+        :[]
+      end
+
+      # An array containing the arguments of the dispatched method.
+      #
+      # @return [Array<Node>] the arguments of the dispatched method
+      def arguments
+        node_parts[1..-1]
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast/node/indexasgn_node.rb 
new/lib/rubocop/ast/node/indexasgn_node.rb
--- old/lib/rubocop/ast/node/indexasgn_node.rb  1970-01-01 01:00:00.000000000 
+0100
+++ new/lib/rubocop/ast/node/indexasgn_node.rb  2020-06-26 06:40:59.000000000 
+0200
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+module RuboCop
+  module AST
+    # Used for modern support only!
+    # Not as thoroughly tested as legacy equivalent
+    #
+    #   $ ruby-parse -e "foo[:bar] = :baz"
+    #   (indexasgn
+    #     (send nil :foo)
+    #     (sym :bar)
+    #     (sym :baz))
+    #   $ ruby-parse --legacy -e "foo[:bar] = :baz"
+    #   (send
+    #     (send nil :foo) :[]=
+    #     (sym :bar)
+    #     (sym :baz))
+    #
+    # The main RuboCop runs in legacy mode; this node is only used
+    # if user `AST::Builder.modernize` or `AST::Builder.emit_index=true`
+    class IndexasgnNode < Node
+      include ParameterizedNode
+      include MethodDispatchNode
+
+      # For similarity with legacy mode
+      def attribute_accessor?
+        false
+      end
+
+      # For similarity with legacy mode
+      def assignment_method?
+        true
+      end
+
+      # For similarity with legacy mode
+      def method_name
+        :[]=
+      end
+
+      # An array containing the arguments of the dispatched method.
+      #
+      # @return [Array<Node>] the arguments of the dispatched method
+      def arguments
+        node_parts[1..-1]
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast/node/lambda_node.rb 
new/lib/rubocop/ast/node/lambda_node.rb
--- old/lib/rubocop/ast/node/lambda_node.rb     1970-01-01 01:00:00.000000000 
+0100
+++ new/lib/rubocop/ast/node/lambda_node.rb     2020-06-26 06:40:59.000000000 
+0200
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module RuboCop
+  module AST
+    # Used for modern support only:
+    # Not as thoroughly tested as legacy equivalent
+    #
+    #   $ ruby-parse -e "->(foo) { bar }"
+    #   (block
+    #     (lambda)
+    #     (args
+    #       (arg :foo))
+    #     (send nil :bar))
+    #   $ ruby-parse --legacy -e "->(foo) { bar }"
+    #   (block
+    #     (send nil :lambda)
+    #     (args
+    #       (arg :foo))
+    #     (send nil :bar))
+    #
+    # The main RuboCop runs in legacy mode; this node is only used
+    # if user `AST::Builder.modernize` or `AST::Builder.emit_lambda=true`
+    class LambdaNode < Node
+      include ParameterizedNode
+      include MethodDispatchNode
+
+      # For similarity with legacy mode
+      def lambda?
+        true
+      end
+
+      # For similarity with legacy mode
+      def lambda_literal?
+        true
+      end
+
+      # For similarity with legacy mode
+      def attribute_accessor?
+        false
+      end
+
+      # For similarity with legacy mode
+      def assignment_method?
+        false
+      end
+
+      # For similarity with legacy mode
+      def method_name
+        :lambda
+      end
+
+      # For similarity with legacy mode
+      def arguments
+        []
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast/node/mixin/method_dispatch_node.rb 
new/lib/rubocop/ast/node/mixin/method_dispatch_node.rb
--- old/lib/rubocop/ast/node/mixin/method_dispatch_node.rb      2020-05-15 
09:39:32.000000000 +0200
+++ new/lib/rubocop/ast/node/mixin/method_dispatch_node.rb      2020-06-26 
06:40:59.000000000 +0200
@@ -3,7 +3,8 @@
 module RuboCop
   module AST
     # Common functionality for nodes that are a kind of method dispatch:
-    # `send`, `csend`, `super`, `zsuper`, `yield`, `defined?`
+    # `send`, `csend`, `super`, `zsuper`, `yield`, `defined?`,
+    # and (modern only): `index`, `indexasgn`, `lambda`
     module MethodDispatchNode
       extend NodePattern::Macros
       include MethodIdentifierPredicates
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb 
new/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb
--- old/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb      
2020-05-15 09:39:32.000000000 +0200
+++ new/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb      
2020-06-26 06:40:59.000000000 +0200
@@ -6,15 +6,62 @@
     # `send`, `csend`, `def`, `defs`, `super`, `zsuper`
     #
     # @note this mixin expects `#method_name` and `#receiver` to be implemented
-    module MethodIdentifierPredicates
+    module MethodIdentifierPredicates # rubocop:disable Metrics/ModuleLength
       ENUMERATOR_METHODS = %i[collect collect_concat detect downto each
                               find find_all find_index inject loop map!
                               map reduce reject reject! reverse_each select
-                              select! times upto].freeze
+                              select! times upto].to_set.freeze
+
+      ENUMERABLE_METHODS = (Enumerable.instance_methods + 
[:each]).to_set.freeze
 
       # http://phrogz.net/programmingruby/language.html#table_18.4
       OPERATOR_METHODS = %i[| ^ & <=> == === =~ > >= < <= << >> + - * /
-                            % ** ~ +@ -@ !@ ~@ [] []= ! != !~ `].freeze
+                            % ** ~ +@ -@ !@ ~@ [] []= ! != !~ `].to_set.freeze
+
+      NONMUTATING_BINARY_OPERATOR_METHODS = %i[* / % + - == === != < > <= >= 
<=>].to_set.freeze
+      NONMUTATING_UNARY_OPERATOR_METHODS = %i[+@ -@ ~ !].to_set.freeze
+      NONMUTATING_OPERATOR_METHODS = (NONMUTATING_BINARY_OPERATOR_METHODS +
+        NONMUTATING_UNARY_OPERATOR_METHODS).freeze
+
+      NONMUTATING_ARRAY_METHODS = %i[
+        all? any? assoc at bsearch bsearch_index collect
+        combination compact count cycle deconstruct difference
+        dig drop drop_while each each_index empty? eql?
+        fetch filter find_index first flatten hash
+        include? index inspect intersection join
+        last length map max min minmax none? one? pack
+        permutation product rassoc reject
+        repeated_combination repeated_permutation reverse
+        reverse_each rindex rotate sample select shuffle
+        size slice sort sum take take_while
+        to_a to_ary to_h to_s transpose union uniq
+        values_at zip |
+      ].to_set.freeze
+
+      NONMUTATING_HASH_METHODS = %i[
+        any? assoc compact dig each each_key each_pair
+        each_value empty? eql? fetch fetch_values filter
+        flatten has_key? has_value? hash include? inspect
+        invert key key? keys? length member? merge rassoc
+        rehash reject select size slice to_a to_h to_hash
+        to_proc to_s transform_keys transform_values value?
+        values values_at
+      ].to_set.freeze
+
+      NONMUTATING_STRING_METHODS = %i[
+        ascii_only? b bytes bytesize byteslice capitalize
+        casecmp casecmp? center chars chomp chop chr codepoints
+        count crypt delete delete_prefix delete_suffix
+        downcase dump each_byte each_char each_codepoint
+        each_grapheme_cluster each_line empty? encode encoding
+        end_with? eql? getbyte grapheme_clusters gsub hash
+        hex include index inspect intern length lines ljust lstrip
+        match match? next oct ord partition reverse rindex rjust
+        rpartition rstrip scan scrub size slice squeeze start_with?
+        strip sub succ sum swapcase to_a to_c to_f to_i to_r to_s
+        to_str to_sym tr tr_s unicode_normalize unicode_normalized?
+        unpack unpack1 upcase upto valid_encoding?
+      ].to_set.freeze
 
       # Checks whether the method name matches the argument.
       #
@@ -31,6 +78,48 @@
         OPERATOR_METHODS.include?(method_name)
       end
 
+      # Checks whether the method is a nonmutating binary operator method.
+      #
+      # @return [Boolean] whether the method is a nonmutating binary operator 
method
+      def nonmutating_binary_operator_method?
+        NONMUTATING_BINARY_OPERATOR_METHODS.include?(method_name)
+      end
+
+      # Checks whether the method is a nonmutating unary operator method.
+      #
+      # @return [Boolean] whether the method is a nonmutating unary operator 
method
+      def nonmutating_unary_operator_method?
+        NONMUTATING_UNARY_OPERATOR_METHODS.include?(method_name)
+      end
+
+      # Checks whether the method is a nonmutating operator method.
+      #
+      # @return [Boolean] whether the method is a nonmutating operator method
+      def nonmutating_operator_method?
+        NONMUTATING_OPERATOR_METHODS.include?(method_name)
+      end
+
+      # Checks whether the method is a nonmutating Array method.
+      #
+      # @return [Boolean] whether the method is a nonmutating Array method
+      def nonmutating_array_method?
+        NONMUTATING_ARRAY_METHODS.include?(method_name)
+      end
+
+      # Checks whether the method is a nonmutating Hash method.
+      #
+      # @return [Boolean] whether the method is a nonmutating Hash method
+      def nonmutating_hash_method?
+        NONMUTATING_HASH_METHODS.include?(method_name)
+      end
+
+      # Checks whether the method is a nonmutating String method.
+      #
+      # @return [Boolean] whether the method is a nonmutating String method
+      def nonmutating_string_method?
+        NONMUTATING_STRING_METHODS.include?(method_name)
+      end
+
       # Checks whether the method is a comparison method.
       #
       # @return [Boolean] whether the method is a comparison
@@ -53,6 +142,13 @@
           method_name.to_s.start_with?('each_')
       end
 
+      # Checks whether the method is an Enumerable method.
+      #
+      # @return [Boolean] whether the method is an Enumerable method
+      def enumerable_method?
+        ENUMERABLE_METHODS.include?(method_name)
+      end
+
       # Checks whether the method is a predicate method.
       #
       # @return [Boolean] whether the method is a predicate method
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast/node/mixin/parameterized_node.rb 
new/lib/rubocop/ast/node/mixin/parameterized_node.rb
--- old/lib/rubocop/ast/node/mixin/parameterized_node.rb        2020-05-15 
09:39:32.000000000 +0200
+++ new/lib/rubocop/ast/node/mixin/parameterized_node.rb        2020-06-26 
06:40:59.000000000 +0200
@@ -4,6 +4,7 @@
   module AST
     # Common functionality for nodes that are parameterized:
     # `send`, `super`, `zsuper`, `def`, `defs`
+    # and (modern only): `index`, `indexasgn`, `lambda`
     module ParameterizedNode
       # Checks whether this node's arguments are wrapped in parentheses.
       #
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast/node/regexp_node.rb 
new/lib/rubocop/ast/node/regexp_node.rb
--- old/lib/rubocop/ast/node/regexp_node.rb     2020-05-15 09:39:32.000000000 
+0200
+++ new/lib/rubocop/ast/node/regexp_node.rb     2020-06-26 06:40:59.000000000 
+0200
@@ -31,6 +31,62 @@
       def content
         children.select(&:str_type?).map(&:str_content).join
       end
+
+      # @return [Bool] if the regexp is a /.../ literal
+      def slash_literal?
+        loc.begin.source == '/'
+      end
+
+      # @return [Bool] if the regexp is a %r{...} literal (using any 
delimiters)
+      def percent_r_literal?
+        !slash_literal?
+      end
+
+      # @return [String] the regexp delimiters (without %r)
+      def delimiters
+        [loc.begin.source[-1], loc.end.source[0]]
+      end
+
+      # @return [Bool] if char is one of the delimiters
+      def delimiter?(char)
+        delimiters.include?(char)
+      end
+
+      # @return [Bool] if regexp contains interpolation
+      def interpolation?
+        children.any?(&:begin_type?)
+      end
+
+      # @return [Bool] if regexp uses the multiline regopt
+      def multiline_mode?
+        regopt_include?(:m)
+      end
+
+      # @return [Bool] if regexp uses the extended regopt
+      def extended?
+        regopt_include?(:x)
+      end
+
+      # @return [Bool] if regexp uses the ignore-case regopt
+      def ignore_case?
+        regopt_include?(:i)
+      end
+
+      # @return [Bool] if regexp uses the single-interpolation regopt
+      def single_interpolation?
+        regopt_include?(:o)
+      end
+
+      # @return [Bool] if regexp uses the no-encoding regopt
+      def no_encoding?
+        regopt_include?(:n)
+      end
+
+      private
+
+      def regopt_include?(option)
+        regopt.children.include?(option)
+      end
     end
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast/node/send_node.rb 
new/lib/rubocop/ast/node/send_node.rb
--- old/lib/rubocop/ast/node/send_node.rb       2020-05-15 09:39:32.000000000 
+0200
+++ new/lib/rubocop/ast/node/send_node.rb       2020-06-26 06:40:59.000000000 
+0200
@@ -10,7 +10,8 @@
       include MethodDispatchNode
 
       def_node_matcher :attribute_accessor?, <<~PATTERN
-        (send nil? ${:attr_reader :attr_writer :attr_accessor :attr} $...)
+        [(send nil? ${:attr_reader :attr_writer :attr_accessor :attr} $...)
+         (_    _    _                                                 _ ...)]
       PATTERN
     end
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast/node.rb new/lib/rubocop/ast/node.rb
--- old/lib/rubocop/ast/node.rb 2020-05-15 09:39:32.000000000 +0200
+++ new/lib/rubocop/ast/node.rb 2020-06-26 06:40:59.000000000 +0200
@@ -44,6 +44,8 @@
 
       BASIC_CONDITIONALS = %i[if while until].freeze
       CONDITIONALS = [*BASIC_CONDITIONALS, :case].freeze
+      POST_CONDITION_LOOP_TYPES = %i[while_post until_post].freeze
+      LOOP_TYPES = (POST_CONDITION_LOOP_TYPES + %i[while until for]).freeze
       VARIABLES = %i[ivar gvar cvar lvar].freeze
       REFERENCES = %i[nth_ref back_ref].freeze
       KEYWORDS = %i[alias and break case class def defs defined?
@@ -53,6 +55,7 @@
                     yield].freeze
       OPERATOR_KEYWORDS = %i[and or].freeze
       SPECIAL_KEYWORDS = %w[__FILE__ __LINE__ __ENCODING__].freeze
+      ARGUMENT_TYPES = %i[arg optarg restarg kwarg kwoptarg kwrestarg 
blockarg].freeze
 
       # @see https://www.rubydoc.info/gems/ast/AST/Node:initialize
       def initialize(type, children = [], properties = {})
@@ -425,6 +428,15 @@
         CONDITIONALS.include?(type)
       end
 
+      def post_condition_loop?
+        POST_CONDITION_LOOP_TYPES.include?(type)
+      end
+
+      # Note: `loop { }` is a normal method call and thus not a loop keyword.
+      def loop_keyword?
+        LOOP_TYPES.include?(type)
+      end
+
       def keyword?
         return true if special_keyword? || send_type? && prefix_not?
         return false unless KEYWORDS.include?(type)
@@ -456,6 +468,10 @@
         parent&.send_type? && parent.arguments.include?(self)
       end
 
+      def argument_type?
+        ARGUMENT_TYPES.include?(type)
+      end
+
       def boolean_type?
         true_type? || false_type?
       end
@@ -500,7 +516,7 @@
       # So, does the return value of this node matter? If we changed it to
       # `(...; nil)`, might that affect anything?
       #
-      # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
+      # rubocop:disable Metrics/MethodLength
       def value_used?
         # Be conservative and return true if we're not sure.
         return false if parent.nil?
@@ -522,7 +538,7 @@
           true
         end
       end
-      # rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity
+      # rubocop:enable Metrics/MethodLength
 
       # Some expressions are evaluated for their value, some for their side
       # effects, and some for both.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast/node_pattern.rb 
new/lib/rubocop/ast/node_pattern.rb
--- old/lib/rubocop/ast/node_pattern.rb 2020-05-15 09:39:32.000000000 +0200
+++ new/lib/rubocop/ast/node_pattern.rb 2020-06-26 06:40:59.000000000 +0200
@@ -70,13 +70,23 @@
     #     '(send %1 _)'       # % stands for a parameter which must be 
supplied to
     #                         # #match at matching time
     #                         # it will be compared to the corresponding value 
in
-    #                         # the AST using #==
+    #                         # the AST using #=== so you can pass Procs, 
Regexp,
+    #                         # etc. in addition to Nodes or literals.
+    #                         # `Array#===` will never match a node element, 
but
+    #                         # `Set#===` is an alias to `Set#include?` (Ruby 
2.5+
+    #                         # only), and so can be very useful to match 
within
+    #                         # many possible literals / Nodes.
     #                         # a bare '%' is the same as '%1'
     #                         # the number of extra parameters passed to #match
     #                         # must equal the highest % value in the pattern
     #                         # for consistency, %0 is the 'root node' which is
     #                         # passed as the 1st argument to #match, where the
     #                         # matching process starts
+    #     '(send _ %named)'   # arguments can also be passed as named
+    #                         # parameters (see `%1`)
+    #                         # Note that the macros `def_node_pattern` and
+    #                         # `def_node_search` accept default values for 
these.
+    #     '(send _ %CONST)'   # the named constant will act like `%1` and 
`%named`.
     #     '^^send'            # each ^ ascends one level in the AST
     #                         # so this matches against the grandparent node
     #     '`send'             # descends any number of level in the AST
@@ -119,11 +129,13 @@
         ).freeze
         NUMBER       = /-?\d+(?:\.\d+)?/.freeze
         STRING       = /".+?"/.freeze
-        METHOD_NAME  = /\#?#{IDENTIFIER}[\!\?]?\(?/.freeze
+        METHOD_NAME  = /\#?#{IDENTIFIER}[!?]?\(?/.freeze
+        PARAM_CONST  = /%[A-Z:][a-zA-Z_:]+/.freeze
+        KEYWORD_NAME = /%[a-z_]+/.freeze
         PARAM_NUMBER = /%\d*/.freeze
 
-        SEPARATORS = /[\s]+/.freeze
-        TOKENS     = Regexp.union(META, PARAM_NUMBER, NUMBER,
+        SEPARATORS = /\s+/.freeze
+        TOKENS     = Regexp.union(META, PARAM_CONST, KEYWORD_NAME, 
PARAM_NUMBER, NUMBER,
                                   METHOD_NAME, SYMBOL, STRING)
 
         TOKEN = /\G(?:#{SEPARATORS}|#{TOKENS}|.)/.freeze
@@ -135,6 +147,8 @@
         FUNCALL   = /\A\##{METHOD_NAME}/.freeze
         LITERAL   = /\A(?:#{SYMBOL}|#{NUMBER}|#{STRING})\Z/.freeze
         PARAM     = /\A#{PARAM_NUMBER}\Z/.freeze
+        CONST     = /\A#{PARAM_CONST}\Z/.freeze
+        KEYWORD   = /\A#{KEYWORD_NAME}\Z/.freeze
         CLOSING   = /\A(?:\)|\}|\])\Z/.freeze
 
         REST      = '...'
@@ -193,6 +207,7 @@
           @captures = 0  # number of captures seen
           @unify    = {} # named wildcard -> temp variable
           @params   = 0  # highest % (param) number seen
+          @keywords = Set[] # keyword parameters seen
           run(node_var)
         end
 
@@ -232,6 +247,8 @@
           when LITERAL   then compile_literal(token)
           when PREDICATE then compile_predicate(token)
           when NODE      then compile_nodetype(token)
+          when KEYWORD   then compile_keyword(token[1..-1])
+          when CONST     then compile_const(token[1..-1])
           when PARAM     then compile_param(token[1..-1])
           when CLOSING   then fail_due_to("#{token} in invalid position")
           when nil       then fail_due_to('pattern ended prematurely')
@@ -612,7 +629,15 @@
         end
 
         def compile_param(number)
-          "#{CUR_ELEMENT} == #{get_param(number)}"
+          "#{get_param(number)} === #{CUR_ELEMENT}"
+        end
+
+        def compile_const(const)
+          "#{get_const(const)} === #{CUR_ELEMENT}"
+        end
+
+        def compile_keyword(keyword)
+          "#{get_keyword(keyword)} === #{CUR_ELEMENT}"
         end
 
         def compile_args(tokens)
@@ -626,12 +651,14 @@
         end
 
         def compile_arg(token)
+          name = token[1..-1]
           case token
-          when WILDCARD  then
-            name = token[1..-1]
+          when WILDCARD
             access_unify(name) || fail_due_to('invalid in arglist: ' + token)
           when LITERAL   then token
-          when PARAM     then get_param(token[1..-1])
+          when KEYWORD   then get_keyword(name)
+          when CONST     then get_const(name)
+          when PARAM     then get_param(name)
           when CLOSING   then fail_due_to("#{token} in invalid position")
           when nil       then fail_due_to('pattern ended prematurely')
           else fail_due_to("invalid token in arglist: #{token.inspect}")
@@ -650,6 +677,15 @@
           number.zero? ? @root : "param#{number}"
         end
 
+        def get_keyword(name)
+          @keywords << name
+          name
+        end
+
+        def get_const(const)
+          const # Output the constant exactly as given
+        end
+
         def emit_yield_capture(when_no_capture = '')
           yield_val = if @captures.zero?
                         when_no_capture
@@ -675,9 +711,15 @@
           (1..@params).map { |n| "param#{n}" }.join(',')
         end
 
-        def emit_trailing_params
+        def emit_keyword_list(forwarding: false)
+          pattern = "%<keyword>s: #{'%<keyword>s' if forwarding}"
+          @keywords.map { |k| format(pattern, keyword: k) }.join(',')
+        end
+
+        def emit_trailing_params(forwarding: false)
           params = emit_param_list
-          params.empty? ? '' : ",#{params}"
+          keywords = emit_keyword_list(forwarding: forwarding)
+          [params, keywords].reject(&:empty?).map { |p| ", #{p}" }.join
         end
 
         def emit_method_code
@@ -753,68 +795,51 @@
         def self.tokens(pattern)
           pattern.scan(TOKEN).reject { |token| token =~ /\A#{SEPARATORS}\Z/ }
         end
-      end
-      private_constant :Compiler
-
-      # Helpers for defining methods based on a pattern string
-      module Macros
-        # Define a method which applies a pattern to an AST node
-        #
-        # The new method will return nil if the node does not match
-        # If the node matches, and a block is provided, the new method will
-        # yield to the block (passing any captures as block arguments).
-        # If the node matches, and no block is provided, the new method will
-        # return the captures, or `true` if there were none.
-        def def_node_matcher(method_name, pattern_str)
-          compiler = Compiler.new(pattern_str, 'node')
-          src = "def #{method_name}(node = self" \
-                "#{compiler.emit_trailing_params});" \
-                "#{compiler.emit_method_code};end"
-
-          location = caller_locations(1, 1).first
-          class_eval(src, location.path, location.lineno)
-        end
 
-        # Define a method which recurses over the descendants of an AST node,
-        # checking whether any of them match the provided pattern
-        #
-        # If the method name ends with '?', the new method will return `true`
-        # as soon as it finds a descendant which matches. Otherwise, it will
-        # yield all descendants which match.
-        def def_node_search(method_name, pattern_str)
-          compiler = Compiler.new(pattern_str, 'node')
-          called_from = caller(1..1).first.split(':')
-
-          if method_name.to_s.end_with?('?')
-            node_search_first(method_name, compiler, called_from)
-          else
-            node_search_all(method_name, compiler, called_from)
+        def def_helper(base, method_name, **defaults)
+          location = caller_locations(3, 1).first
+          unless defaults.empty?
+            base.send :define_method, method_name do |*args, **values|
+              send method_name, *args, **defaults, **values
+            end
+            method_name = :"without_defaults_#{method_name}"
           end
+          src = yield method_name
+          base.class_eval(src, location.path, location.lineno)
         end
 
-        def node_search_first(method_name, compiler, called_from)
-          node_search(method_name, compiler, 'return true', '', called_from)
+        def def_node_matcher(base, method_name, **defaults)
+          def_helper(base, method_name, **defaults) do |name|
+            <<~RUBY
+              def #{name}(node = self#{emit_trailing_params})
+                #{emit_method_code}
+              end
+            RUBY
+          end
         end
 
-        def node_search_all(method_name, compiler, called_from)
-          yield_code = compiler.emit_yield_capture('node')
-          prelude = "return enum_for(:#{method_name}, node0" \
-                    "#{compiler.emit_trailing_params}) unless block_given?"
-
-          node_search(method_name, compiler, yield_code, prelude, called_from)
+        def def_node_search(base, method_name, **defaults)
+          def_helper(base, method_name, **defaults) do |name|
+            emit_node_search(name)
+          end
         end
 
-        def node_search(method_name, compiler, on_match, prelude, called_from)
-          src = node_search_body(method_name, compiler.emit_trailing_params,
-                                 prelude, compiler.match_code, on_match)
-          filename, lineno = *called_from
-          class_eval(src, filename, lineno.to_i)
+        def emit_node_search(method_name)
+          if method_name.to_s.end_with?('?')
+            on_match = 'return true'
+          else
+            prelude = <<~RUBY
+              return enum_for(:#{method_name},
+                node0#{emit_trailing_params(forwarding: true)}) unless 
block_given?
+            RUBY
+            on_match = emit_yield_capture('node')
+          end
+          emit_node_search_body(method_name, prelude: prelude, on_match: 
on_match)
         end
 
-        def node_search_body(method_name, trailing_params, prelude, match_code,
-                             on_match)
+        def emit_node_search_body(method_name, prelude:, on_match:)
           <<~RUBY
-            def #{method_name}(node0#{trailing_params})
+            def #{method_name}(node0#{emit_trailing_params})
               #{prelude}
               node0.each_node do |node|
                 if #{match_code}
@@ -826,6 +851,33 @@
           RUBY
         end
       end
+      private_constant :Compiler
+
+      # Helpers for defining methods based on a pattern string
+      module Macros
+        # Define a method which applies a pattern to an AST node
+        #
+        # The new method will return nil if the node does not match
+        # If the node matches, and a block is provided, the new method will
+        # yield to the block (passing any captures as block arguments).
+        # If the node matches, and no block is provided, the new method will
+        # return the captures, or `true` if there were none.
+        def def_node_matcher(method_name, pattern_str, **keyword_defaults)
+          Compiler.new(pattern_str, 'node')
+                  .def_node_matcher(self, method_name, **keyword_defaults)
+        end
+
+        # Define a method which recurses over the descendants of an AST node,
+        # checking whether any of them match the provided pattern
+        #
+        # If the method name ends with '?', the new method will return `true`
+        # as soon as it finds a descendant which matches. Otherwise, it will
+        # yield all descendants which match.
+        def def_node_search(method_name, pattern_str, **keyword_defaults)
+          Compiler.new(pattern_str, 'node')
+                  .def_node_search(self, method_name, **keyword_defaults)
+        end
+      end
 
       attr_reader :pattern
 
@@ -837,11 +889,15 @@
         instance_eval(src, __FILE__, __LINE__ + 1)
       end
 
-      def match(*args)
+      def match(*args, **rest)
         # If we're here, it's because the singleton method has not been 
defined,
         # either because we've been dup'ed or serialized through YAML
         initialize(pattern)
-        match(*args)
+        if rest.empty?
+          match(*args)
+        else
+          match(*args, **rest)
+        end
       end
 
       def marshal_load(pattern)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast/processed_source.rb 
new/lib/rubocop/ast/processed_source.rb
--- old/lib/rubocop/ast/processed_source.rb     2020-05-15 09:39:32.000000000 
+0200
+++ new/lib/rubocop/ast/processed_source.rb     2020-06-26 06:40:59.000000000 
+0200
@@ -2,6 +2,7 @@
 
 require 'digest/sha1'
 
+# rubocop:disable Metrics/ClassLength
 module RuboCop
   module AST
     # ProcessedSource contains objects which are generated by Parser
@@ -176,6 +177,9 @@
         when 2.7
           require 'parser/ruby27'
           Parser::Ruby27
+        when 2.8
+          require 'parser/ruby28'
+          Parser::Ruby28
         else
           raise ArgumentError,
                 "RuboCop found unknown Ruby version: #{ruby_version.inspect}"
@@ -201,3 +205,4 @@
     end
   end
 end
+# rubocop:enable Metrics/ClassLength
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast/traversal.rb 
new/lib/rubocop/ast/traversal.rb
--- old/lib/rubocop/ast/traversal.rb    2020-05-15 09:39:32.000000000 +0200
+++ new/lib/rubocop/ast/traversal.rb    2020-06-26 06:40:59.000000000 +0200
@@ -19,9 +19,10 @@
                              rational str sym regopt self lvar
                              ivar cvar gvar nth_ref back_ref cbase
                              arg restarg blockarg shadowarg
-                             kwrestarg zsuper lambda redo retry
+                             kwrestarg zsuper redo retry
                              forward_args forwarded_args
-                             match_var match_nil_pattern empty_else].freeze
+                             match_var match_nil_pattern empty_else
+                             forward_arg lambda procarg0 __ENCODING__].freeze
       ONE_CHILD_NODE    = %i[splat kwsplat block_pass not break next
                              preexe postexe match_current_line defined?
                              arg_expr pin match_rest if_guard unless_guard
@@ -33,7 +34,8 @@
                              match_with_lvasgn begin kwbegin return
                              in_match match_alt
                              match_as array_pattern array_pattern_with_tail
-                             hash_pattern const_pattern].freeze
+                             hash_pattern const_pattern
+                             index indexasgn].freeze
       SECOND_CHILD_ONLY = %i[lvasgn ivasgn cvasgn gvasgn optarg kwarg
                              kwoptarg].freeze
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast/version.rb 
new/lib/rubocop/ast/version.rb
--- old/lib/rubocop/ast/version.rb      2020-05-15 09:39:32.000000000 +0200
+++ new/lib/rubocop/ast/version.rb      2020-06-26 06:40:59.000000000 +0200
@@ -3,7 +3,7 @@
 module RuboCop
   module AST
     module Version
-      STRING = '0.0.3'
+      STRING = '0.1.0'
     end
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/rubocop/ast.rb new/lib/rubocop/ast.rb
--- old/lib/rubocop/ast.rb      2020-05-15 09:39:32.000000000 +0200
+++ new/lib/rubocop/ast.rb      2020-06-26 06:40:59.000000000 +0200
@@ -2,6 +2,7 @@
 
 require 'parser'
 require 'forwardable'
+require 'set'
 
 require_relative 'ast/node_pattern'
 require_relative 'ast/sexp'
@@ -34,8 +35,11 @@
 require_relative 'ast/node/float_node'
 require_relative 'ast/node/hash_node'
 require_relative 'ast/node/if_node'
+require_relative 'ast/node/index_node'
+require_relative 'ast/node/indexasgn_node'
 require_relative 'ast/node/int_node'
 require_relative 'ast/node/keyword_splat_node'
+require_relative 'ast/node/lambda_node'
 require_relative 'ast/node/module_node'
 require_relative 'ast/node/or_node'
 require_relative 'ast/node/pair_node'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2020-05-15 09:39:32.000000000 +0200
+++ new/metadata        2020-06-26 06:40:59.000000000 +0200
@@ -1,7 +1,7 @@
 --- !ruby/object:Gem::Specification
 name: rubocop-ast
 version: !ruby/object:Gem::Version
-  version: 0.0.3
+  version: 0.1.0
 platform: ruby
 authors:
 - Bozhidar Batsov
@@ -10,7 +10,7 @@
 autorequire: 
 bindir: bin
 cert_chain: []
-date: 2020-05-15 00:00:00.000000000 Z
+date: 2020-06-26 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: parser
@@ -77,8 +77,11 @@
 - lib/rubocop/ast/node/forward_args_node.rb
 - lib/rubocop/ast/node/hash_node.rb
 - lib/rubocop/ast/node/if_node.rb
+- lib/rubocop/ast/node/index_node.rb
+- lib/rubocop/ast/node/indexasgn_node.rb
 - lib/rubocop/ast/node/int_node.rb
 - lib/rubocop/ast/node/keyword_splat_node.rb
+- lib/rubocop/ast/node/lambda_node.rb
 - lib/rubocop/ast/node/mixin/basic_literal_node.rb
 - lib/rubocop/ast/node/mixin/binary_operator_node.rb
 - lib/rubocop/ast/node/mixin/collection_node.rb
@@ -120,7 +123,7 @@
   homepage_uri: https://www.rubocop.org/
   changelog_uri: 
https://github.com/rubocop-hq/rubocop-ast/blob/master/CHANGELOG.md
   source_code_uri: https://github.com/rubocop-hq/rubocop-ast/
-  documentation_uri: https://docs.rubocop.org/
+  documentation_uri: https://docs.rubocop.org/rubocop-ast/
   bug_tracker_uri: https://github.com/rubocop-hq/rubocop-ast/issues
 post_install_message: 
 rdoc_options: []


Reply via email to