ruby-next-core 0.14.0 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/.rbnext/2.3/ruby-next/language/rewriters/2.7/pattern_matching.rb +78 -37
- data/lib/.rbnext/2.7/ruby-next/language/rewriters/2.7/pattern_matching.rb +1061 -0
- data/lib/ruby-next/language/rewriters/2.7/pattern_matching.rb +78 -37
- data/lib/ruby-next/version.rb +1 -1
- metadata +3 -2
| @@ -243,6 +243,7 @@ module RubyNext | |
| 243 243 |  | 
| 244 244 | 
             
                      @deconstructed_keys = {}
         | 
| 245 245 | 
             
                      @predicates = Predicates::CaseIn.new
         | 
| 246 | 
            +
                      @lvars = []
         | 
| 246 247 |  | 
| 247 248 | 
             
                      matchee_ast =
         | 
| 248 249 | 
             
                        s(:begin, s(:lvasgn, MATCHEE, node.children[0]))
         | 
| @@ -272,6 +273,7 @@ module RubyNext | |
| 272 273 |  | 
| 273 274 | 
             
                      @deconstructed_keys = {}
         | 
| 274 275 | 
             
                      @predicates = Predicates::Noop.new
         | 
| 276 | 
            +
                      @lvars = []
         | 
| 275 277 |  | 
| 276 278 | 
             
                      matchee =
         | 
| 277 279 | 
             
                        s(:begin, s(:lvasgn, MATCHEE, node.children[0]))
         | 
| @@ -282,10 +284,12 @@ module RubyNext | |
| 282 284 | 
             
                          arr: MATCHEE_ARR,
         | 
| 283 285 | 
             
                          hash: MATCHEE_HASH
         | 
| 284 286 | 
             
                        ) do
         | 
| 285 | 
            -
                           | 
| 286 | 
            -
                             | 
| 287 | 
            -
             | 
| 288 | 
            -
             | 
| 287 | 
            +
                          with_declared_locals do
         | 
| 288 | 
            +
                            send(
         | 
| 289 | 
            +
                              :"#{node.children[1].type}_clause",
         | 
| 290 | 
            +
                              node.children[1]
         | 
| 291 | 
            +
                            )
         | 
| 292 | 
            +
                          end.then do |node|
         | 
| 289 293 | 
             
                            s(:begin,
         | 
| 290 294 | 
             
                              s(:or,
         | 
| 291 295 | 
             
                                node,
         | 
| @@ -311,6 +315,7 @@ module RubyNext | |
| 311 315 |  | 
| 312 316 | 
             
                      @deconstructed_keys = {}
         | 
| 313 317 | 
             
                      @predicates = Predicates::Noop.new
         | 
| 318 | 
            +
                      @lvars = []
         | 
| 314 319 |  | 
| 315 320 | 
             
                      matchee =
         | 
| 316 321 | 
             
                        s(:begin, s(:lvasgn, MATCHEE, node.children[0]))
         | 
| @@ -321,10 +326,12 @@ module RubyNext | |
| 321 326 | 
             
                          arr: MATCHEE_ARR,
         | 
| 322 327 | 
             
                          hash: MATCHEE_HASH
         | 
| 323 328 | 
             
                        ) do
         | 
| 324 | 
            -
                           | 
| 325 | 
            -
                             | 
| 326 | 
            -
             | 
| 327 | 
            -
             | 
| 329 | 
            +
                          with_declared_locals do
         | 
| 330 | 
            +
                            send(
         | 
| 331 | 
            +
                              :"#{node.children[1].type}_clause",
         | 
| 332 | 
            +
                              node.children[1]
         | 
| 333 | 
            +
                            )
         | 
| 334 | 
            +
                          end
         | 
| 328 335 | 
             
                        end
         | 
| 329 336 |  | 
| 330 337 | 
             
                      node.updated(
         | 
| @@ -395,13 +402,15 @@ module RubyNext | |
| 395 402 | 
             
                    def build_when_clause(clause)
         | 
| 396 403 | 
             
                      predicates.reset!
         | 
| 397 404 | 
             
                      [
         | 
| 398 | 
            -
                         | 
| 399 | 
            -
                           | 
| 400 | 
            -
                             | 
| 401 | 
            -
             | 
| 402 | 
            -
             | 
| 403 | 
            -
             | 
| 404 | 
            -
             | 
| 405 | 
            +
                        with_declared_locals do
         | 
| 406 | 
            +
                          with_guard(
         | 
| 407 | 
            +
                            send(
         | 
| 408 | 
            +
                              :"#{clause.children[0].type}_clause",
         | 
| 409 | 
            +
                              clause.children[0]
         | 
| 410 | 
            +
                            ),
         | 
| 411 | 
            +
                            clause.children[1] # guard
         | 
| 412 | 
            +
                          )
         | 
| 413 | 
            +
                        end,
         | 
| 405 414 | 
             
                        process(clause.children[2] || s(:nil)) # expression
         | 
| 406 415 | 
             
                      ].then do |children|
         | 
| 407 416 | 
             
                        s(:when, *children)
         | 
| @@ -442,7 +451,7 @@ module RubyNext | |
| 442 451 | 
             
                      var = node.children[0]
         | 
| 443 452 | 
             
                      return s(:true) if var == :_
         | 
| 444 453 |  | 
| 445 | 
            -
                      check_match_var_alternation!(var) | 
| 454 | 
            +
                      check_match_var_alternation!(var)
         | 
| 446 455 |  | 
| 447 456 | 
             
                      s(:begin,
         | 
| 448 457 | 
             
                        s(:or,
         | 
| @@ -541,11 +550,10 @@ module RubyNext | |
| 541 550 | 
             
                    def array_find(head, *nodes, tail)
         | 
| 542 551 | 
             
                      index = s(:lvar, :__i__)
         | 
| 543 552 |  | 
| 544 | 
            -
                      match_vars = []
         | 
| 545 | 
            -
             | 
| 546 553 | 
             
                      head_match =
         | 
| 547 554 | 
             
                        unless head.children.empty?
         | 
| 548 | 
            -
                           | 
| 555 | 
            +
                          # we only need to call this to track the lvar usage
         | 
| 556 | 
            +
                          build_var_assignment(head.children[0].children[0])
         | 
| 549 557 |  | 
| 550 558 | 
             
                          arr_take = s(:send,
         | 
| 551 559 | 
             
                            s(:lvar, locals[:arr]),
         | 
| @@ -557,16 +565,19 @@ module RubyNext | |
| 557 565 |  | 
| 558 566 | 
             
                      tail_match =
         | 
| 559 567 | 
             
                        unless tail.children.empty?
         | 
| 560 | 
            -
                           | 
| 568 | 
            +
                          # we only need to call this to track the lvar usage
         | 
| 569 | 
            +
                          build_var_assignment(tail.children[0].children[0])
         | 
| 561 570 |  | 
| 562 571 | 
             
                          match_var_clause(tail.children[0], arr_slice(index + nodes.size, -1))
         | 
| 563 572 | 
             
                        end
         | 
| 564 573 |  | 
| 565 574 | 
             
                      nodes.each do |node|
         | 
| 566 575 | 
             
                        if node.type == :match_var
         | 
| 567 | 
            -
                           | 
| 576 | 
            +
                          # we only need to call this to track the lvar usage
         | 
| 577 | 
            +
                          build_var_assignment(node.children[0])
         | 
| 568 578 | 
             
                        elsif node.type == :match_as
         | 
| 569 | 
            -
                           | 
| 579 | 
            +
                          # we only need to call this to track the lvar usage
         | 
| 580 | 
            +
                          build_var_assignment(node.children[1].children[0])
         | 
| 570 581 | 
             
                        end
         | 
| 571 582 | 
             
                      end
         | 
| 572 583 |  | 
| @@ -594,19 +605,7 @@ module RubyNext | |
| 594 605 | 
             
                        s(:args,
         | 
| 595 606 | 
             
                          s(:arg, :_),
         | 
| 596 607 | 
             
                          s(:arg, :__i__)),
         | 
| 597 | 
            -
                        pattern) | 
| 598 | 
            -
                        next block if match_vars.empty?
         | 
| 599 | 
            -
             | 
| 600 | 
            -
                        # We need to declare match vars outside of `find` block
         | 
| 601 | 
            -
                        locals_declare = s(:begin, s(:masgn,
         | 
| 602 | 
            -
                          s(:mlhs, *match_vars),
         | 
| 603 | 
            -
                          s(:nil)))
         | 
| 604 | 
            -
             | 
| 605 | 
            -
                        s(:begin,
         | 
| 606 | 
            -
                          s(:or,
         | 
| 607 | 
            -
                            locals_declare,
         | 
| 608 | 
            -
                            block))
         | 
| 609 | 
            -
                      end
         | 
| 608 | 
            +
                        pattern)
         | 
| 610 609 | 
             
                    end
         | 
| 611 610 |  | 
| 612 611 | 
             
                    def array_match_rest(index, node, *tail)
         | 
| @@ -649,6 +648,14 @@ module RubyNext | |
| 649 648 | 
             
                      end
         | 
| 650 649 | 
             
                    end
         | 
| 651 650 |  | 
| 651 | 
            +
                    def find_pattern_array_element(node, index)
         | 
| 652 | 
            +
                      element = arr_item_at(index)
         | 
| 653 | 
            +
                      locals.with(arr: locals[:arr, index]) do
         | 
| 654 | 
            +
                        predicates.push :"i#{index}"
         | 
| 655 | 
            +
                        find_pattern_clause(node, element).tap { predicates.pop }
         | 
| 656 | 
            +
                      end
         | 
| 657 | 
            +
                    end
         | 
| 658 | 
            +
             | 
| 652 659 | 
             
                    def hash_pattern_array_element(node, index)
         | 
| 653 660 | 
             
                      element = arr_item_at(index)
         | 
| 654 661 | 
             
                      locals.with(hash: locals[:arr, index]) do
         | 
| @@ -829,6 +836,15 @@ module RubyNext | |
| 829 836 | 
             
                      end
         | 
| 830 837 | 
             
                    end
         | 
| 831 838 |  | 
| 839 | 
            +
                    def find_pattern_hash_element(node, key)
         | 
| 840 | 
            +
                      element = hash_value_at(key)
         | 
| 841 | 
            +
                      key_index = deconstructed_key(key)
         | 
| 842 | 
            +
                      locals.with(arr: locals[:hash, key_index]) do
         | 
| 843 | 
            +
                        predicates.push :"k#{key_index}"
         | 
| 844 | 
            +
                        find_pattern_clause(node, element).tap { predicates.pop }
         | 
| 845 | 
            +
                      end
         | 
| 846 | 
            +
                    end
         | 
| 847 | 
            +
             | 
| 832 848 | 
             
                    def hash_element(head, *tail)
         | 
| 833 849 | 
             
                      send("#{head.type}_hash_element", head).then do |node|
         | 
| 834 850 | 
             
                        next node if tail.empty?
         | 
| @@ -948,6 +964,24 @@ module RubyNext | |
| 948 964 | 
             
                      end
         | 
| 949 965 | 
             
                    end
         | 
| 950 966 |  | 
| 967 | 
            +
                    def with_declared_locals
         | 
| 968 | 
            +
                      lvars.clear
         | 
| 969 | 
            +
                      node = yield
         | 
| 970 | 
            +
             | 
| 971 | 
            +
                      return node if lvars.empty?
         | 
| 972 | 
            +
             | 
| 973 | 
            +
                      # We need to declare match lvars outside of the outer `find` block,
         | 
| 974 | 
            +
                      # so we do that for that whole pattern
         | 
| 975 | 
            +
                      locals_declare = s(:begin, s(:masgn,
         | 
| 976 | 
            +
                        s(:mlhs, *lvars.uniq.map { s(:lvasgn, _1) }),
         | 
| 977 | 
            +
                        s(:nil)))
         | 
| 978 | 
            +
             | 
| 979 | 
            +
                      s(:begin,
         | 
| 980 | 
            +
                        s(:or,
         | 
| 981 | 
            +
                          locals_declare,
         | 
| 982 | 
            +
                          node))
         | 
| 983 | 
            +
                    end
         | 
| 984 | 
            +
             | 
| 951 985 | 
             
                    def no_matching_pattern
         | 
| 952 986 | 
             
                      raise_error(
         | 
| 953 987 | 
             
                        :NoMatchingPatternError,
         | 
| @@ -982,13 +1016,17 @@ module RubyNext | |
| 982 1016 |  | 
| 983 1017 | 
             
                    private
         | 
| 984 1018 |  | 
| 985 | 
            -
                    attr_reader :deconstructed_keys, :predicates
         | 
| 1019 | 
            +
                    attr_reader :deconstructed_keys, :predicates, :lvars
         | 
| 986 1020 |  | 
| 987 1021 | 
             
                    # Raise SyntaxError if match-var is used within alternation
         | 
| 988 1022 | 
             
                    # https://github.com/ruby/ruby/blob/672213ef1ca2b71312084057e27580b340438796/compile.c#L5900
         | 
| 989 1023 | 
             
                    def check_match_var_alternation!(name)
         | 
| 990 1024 | 
             
                      return unless locals.key?(ALTERNATION_MARKER)
         | 
| 991 1025 |  | 
| 1026 | 
            +
                      if name.is_a?(::Parser::AST::Node)
         | 
| 1027 | 
            +
                        raise ::SyntaxError, "illegal variable in alternative pattern (#{name.children.first})"
         | 
| 1028 | 
            +
                      end
         | 
| 1029 | 
            +
             | 
| 992 1030 | 
             
                      return if name.start_with?("_")
         | 
| 993 1031 |  | 
| 994 1032 | 
             
                      raise ::SyntaxError, "illegal variable in alternative pattern (#{name})"
         | 
| @@ -1008,7 +1046,10 @@ module RubyNext | |
| 1008 1046 |  | 
| 1009 1047 | 
             
                    # Value could be omitted for mass assignment
         | 
| 1010 1048 | 
             
                    def build_var_assignment(var, value = nil)
         | 
| 1011 | 
            -
                       | 
| 1049 | 
            +
                      unless var.is_a?(::Parser::AST::Node)
         | 
| 1050 | 
            +
                        lvars << var
         | 
| 1051 | 
            +
                        return s(:lvasgn, *[var, value].compact)
         | 
| 1052 | 
            +
                      end
         | 
| 1012 1053 |  | 
| 1013 1054 | 
             
                      asign_type = :"#{var.type.to_s[0]}vasgn"
         | 
| 1014 1055 |  | 
    
        data/lib/ruby-next/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: ruby-next-core
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.14. | 
| 4 | 
            +
              version: 0.14.1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Vladimir Dementyev
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2022-01-21 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: ruby-next-parser
         | 
| @@ -67,6 +67,7 @@ files: | |
| 67 67 | 
             
            - lib/.rbnext/2.3/ruby-next/language/rewriters/base.rb
         | 
| 68 68 | 
             
            - lib/.rbnext/2.3/ruby-next/utils.rb
         | 
| 69 69 | 
             
            - lib/.rbnext/2.7/ruby-next/core.rb
         | 
| 70 | 
            +
            - lib/.rbnext/2.7/ruby-next/language/rewriters/2.7/pattern_matching.rb
         | 
| 70 71 | 
             
            - lib/ruby-next.rb
         | 
| 71 72 | 
             
            - lib/ruby-next/cli.rb
         | 
| 72 73 | 
             
            - lib/ruby-next/commands/base.rb
         |