rbs 1.7.0 → 2.0.0.pre1
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 +95 -3
- data/core/array.rbs +3 -3
- data/core/builtin.rbs +4 -0
- data/core/enumerable.rbs +3 -3
- data/core/thread.rbs +1 -1
- data/docs/collection.md +23 -1
- data/docs/syntax.md +117 -61
- data/ext/rbs_extension/constants.c +2 -6
- data/ext/rbs_extension/constants.h +1 -2
- data/ext/rbs_extension/parser.c +221 -185
- data/ext/rbs_extension/parserstate.c +6 -2
- data/ext/rbs_extension/parserstate.h +10 -0
- data/ext/rbs_extension/ruby_objs.c +17 -17
- data/ext/rbs_extension/ruby_objs.h +3 -4
- data/lib/rbs/ast/declarations.rb +6 -99
- data/lib/rbs/ast/type_param.rb +134 -0
- data/lib/rbs/cli.rb +33 -5
- data/lib/rbs/collection/config/lockfile_generator.rb +26 -18
- data/lib/rbs/collection/sources/git.rb +18 -7
- data/lib/rbs/collection/sources/rubygems.rb +7 -0
- data/lib/rbs/collection/sources/stdlib.rb +6 -0
- data/lib/rbs/definition.rb +9 -0
- data/lib/rbs/definition_builder.rb +78 -16
- data/lib/rbs/environment.rb +32 -8
- data/lib/rbs/environment_loader.rb +0 -2
- data/lib/rbs/environment_walker.rb +4 -1
- data/lib/rbs/errors.rb +31 -6
- data/lib/rbs/location_aux.rb +2 -0
- data/lib/rbs/method_type.rb +29 -6
- data/lib/rbs/prototype/rb.rb +3 -3
- data/lib/rbs/prototype/rbi.rb +8 -6
- data/lib/rbs/prototype/runtime.rb +4 -4
- data/lib/rbs/type_alias_regularity.rb +115 -0
- data/lib/rbs/types.rb +100 -23
- data/lib/rbs/validator.rb +99 -15
- data/lib/rbs/variance_calculator.rb +60 -31
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +2 -14
- data/lib/rbs.rb +2 -0
- data/schema/decls.json +19 -46
- data/schema/methodType.json +1 -1
- data/schema/typeParam.json +36 -0
- data/schema/types.json +8 -2
- data/sig/collection/collections.rbs +13 -2
- data/sig/collection/config.rbs +2 -2
- data/sig/declarations.rbs +15 -62
- data/sig/definition.rbs +11 -1
- data/sig/definition_builder.rbs +37 -1
- data/sig/environment.rbs +7 -1
- data/sig/environment_walker.rbs +26 -0
- data/sig/errors.rbs +28 -3
- data/sig/location.rbs +3 -1
- data/sig/locator.rbs +1 -1
- data/sig/method_types.rbs +25 -4
- data/sig/type_alias_regularity.rbs +92 -0
- data/sig/type_param.rbs +74 -0
- data/sig/types.rbs +37 -8
- data/sig/validator.rbs +38 -2
- data/sig/variance_calculator.rbs +50 -0
- data/sig/writer.rbs +1 -1
- data/stdlib/bigdecimal-math/0/manifest.yaml +2 -0
- data/stdlib/csv/0/manifest.yaml +2 -0
- data/stdlib/date/0/date.rbs +2 -2
- data/stdlib/logger/0/manifest.yaml +2 -0
- data/stdlib/net-http/0/manifest.yaml +2 -0
- data/stdlib/openssl/0/manifest.yaml +2 -0
- data/stdlib/prime/0/manifest.yaml +2 -0
- data/stdlib/resolv/0/manifest.yaml +3 -0
- data/stdlib/set/0/set.rbs +3 -3
- data/stdlib/uri/0/common.rbs +10 -5
- data/stdlib/uri/0/ftp.rbs +10 -0
- data/stdlib/uri/0/mailto.rbs +5 -0
- data/stdlib/uri/0/ws.rbs +10 -0
- data/stdlib/uri/0/wss.rbs +7 -0
- data/stdlib/yaml/0/manifest.yaml +3 -0
- data/steep/Gemfile.lock +10 -10
- metadata +21 -5
- data/lib/ruby/signature.rb +0 -7
    
        data/ext/rbs_extension/parser.c
    CHANGED
    
    | @@ -273,7 +273,7 @@ static VALUE parse_function_param(parserstate *state) { | |
| 273 273 | 
             
                param_range.start = type_range.start;
         | 
| 274 274 | 
             
                param_range.end = name_range.end;
         | 
| 275 275 |  | 
| 276 | 
            -
                VALUE name =  | 
| 276 | 
            +
                VALUE name = rb_to_symbol(rbs_unquote_string(state, state->current_token.range, 0));
         | 
| 277 277 | 
             
                VALUE location = rbs_new_location(state->buffer, param_range);
         | 
| 278 278 | 
             
                rbs_loc *loc = rbs_check_location(location);
         | 
| 279 279 | 
             
                rbs_loc_add_optional_child(loc, rb_intern("name"), name_range);
         | 
| @@ -741,6 +741,90 @@ static VALUE parse_symbol(parserstate *state) { | |
| 741 741 | 
             
              );
         | 
| 742 742 | 
             
            }
         | 
| 743 743 |  | 
| 744 | 
            +
            /*
         | 
| 745 | 
            +
             instance_type ::= {type_name} <type_args>
         | 
| 746 | 
            +
             | 
| 747 | 
            +
             type_args ::= {} <> /empty/
         | 
| 748 | 
            +
                         | {} `[` type_list <`]`>
         | 
| 749 | 
            +
             */
         | 
| 750 | 
            +
            static VALUE parse_instance_type(parserstate *state, bool parse_alias) {
         | 
| 751 | 
            +
                range name_range;
         | 
| 752 | 
            +
                range args_range;
         | 
| 753 | 
            +
                range type_range;
         | 
| 754 | 
            +
             | 
| 755 | 
            +
                TypeNameKind expected_kind = INTERFACE_NAME | CLASS_NAME;
         | 
| 756 | 
            +
                if (parse_alias) {
         | 
| 757 | 
            +
                  expected_kind |= ALIAS_NAME;
         | 
| 758 | 
            +
                }
         | 
| 759 | 
            +
             | 
| 760 | 
            +
                VALUE typename = parse_type_name(state, expected_kind, &name_range);
         | 
| 761 | 
            +
                VALUE types = rb_ary_new();
         | 
| 762 | 
            +
             | 
| 763 | 
            +
                TypeNameKind kind;
         | 
| 764 | 
            +
                if (state->current_token.type == tUIDENT) {
         | 
| 765 | 
            +
                  kind = CLASS_NAME;
         | 
| 766 | 
            +
                } else if (state->current_token.type == tULIDENT) {
         | 
| 767 | 
            +
                  kind = INTERFACE_NAME;
         | 
| 768 | 
            +
                } else if (state->current_token.type == tLIDENT) {
         | 
| 769 | 
            +
                  kind = ALIAS_NAME;
         | 
| 770 | 
            +
                } else {
         | 
| 771 | 
            +
                  rbs_abort();
         | 
| 772 | 
            +
                }
         | 
| 773 | 
            +
             | 
| 774 | 
            +
                if (state->next_token.type == pLBRACKET) {
         | 
| 775 | 
            +
                  parser_advance(state);
         | 
| 776 | 
            +
                  args_range.start = state->current_token.range.start;
         | 
| 777 | 
            +
                  parse_type_list(state, pRBRACKET, types);
         | 
| 778 | 
            +
                  parser_advance_assert(state, pRBRACKET);
         | 
| 779 | 
            +
                  args_range.end = state->current_token.range.end;
         | 
| 780 | 
            +
                } else {
         | 
| 781 | 
            +
                  args_range = NULL_RANGE;
         | 
| 782 | 
            +
                }
         | 
| 783 | 
            +
             | 
| 784 | 
            +
                type_range.start = name_range.start;
         | 
| 785 | 
            +
                type_range.end = nonnull_pos_or(args_range.end, name_range.end);
         | 
| 786 | 
            +
             | 
| 787 | 
            +
                VALUE location = rbs_new_location(state->buffer, type_range);
         | 
| 788 | 
            +
                rbs_loc *loc = rbs_check_location(location);
         | 
| 789 | 
            +
                rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
         | 
| 790 | 
            +
                rbs_loc_add_optional_child(loc, rb_intern("args"), args_range);
         | 
| 791 | 
            +
             | 
| 792 | 
            +
                if (kind == CLASS_NAME) {
         | 
| 793 | 
            +
                  return rbs_class_instance(typename, types, location);
         | 
| 794 | 
            +
                } else if (kind == INTERFACE_NAME) {
         | 
| 795 | 
            +
                  return rbs_interface(typename, types, location);
         | 
| 796 | 
            +
                } else if (kind == ALIAS_NAME) {
         | 
| 797 | 
            +
                  return rbs_alias(typename, types, location);
         | 
| 798 | 
            +
                } else {
         | 
| 799 | 
            +
                  return Qnil;
         | 
| 800 | 
            +
                }
         | 
| 801 | 
            +
            }
         | 
| 802 | 
            +
             | 
| 803 | 
            +
            /*
         | 
| 804 | 
            +
              singleton_type ::= {`singleton`} `(` type_name <`)`>
         | 
| 805 | 
            +
            */
         | 
| 806 | 
            +
            static VALUE parse_singleton_type(parserstate *state) {
         | 
| 807 | 
            +
              range name_range;
         | 
| 808 | 
            +
              range type_range;
         | 
| 809 | 
            +
             | 
| 810 | 
            +
              parser_assert(state, kSINGLETON);
         | 
| 811 | 
            +
             | 
| 812 | 
            +
              type_range.start = state->current_token.range.start;
         | 
| 813 | 
            +
              parser_advance_assert(state, pLPAREN);
         | 
| 814 | 
            +
              parser_advance(state);
         | 
| 815 | 
            +
             | 
| 816 | 
            +
              VALUE typename = parse_type_name(state, CLASS_NAME, &name_range);
         | 
| 817 | 
            +
             | 
| 818 | 
            +
              parser_advance_assert(state, pRPAREN);
         | 
| 819 | 
            +
              type_range.end = state->current_token.range.end;
         | 
| 820 | 
            +
             | 
| 821 | 
            +
              VALUE location = rbs_new_location(state->buffer, type_range);
         | 
| 822 | 
            +
              rbs_loc *loc = rbs_check_location(location);
         | 
| 823 | 
            +
              rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
         | 
| 824 | 
            +
             | 
| 825 | 
            +
              return rbs_class_singleton(typename, location);
         | 
| 826 | 
            +
            }
         | 
| 827 | 
            +
             | 
| 744 828 | 
             
            /*
         | 
| 745 829 | 
             
              simple ::= {} `(` type <`)`>
         | 
| 746 830 | 
             
                       | {} <base type>
         | 
| @@ -813,82 +897,12 @@ static VALUE parse_simple(parserstate *state) { | |
| 813 897 | 
             
                }
         | 
| 814 898 | 
             
                // fallthrough for type name
         | 
| 815 899 | 
             
              }
         | 
| 816 | 
            -
              case tULIDENT:
         | 
| 817 | 
            -
             | 
| 818 | 
            -
              case pCOLON2: | 
| 819 | 
            -
                 | 
| 820 | 
            -
             | 
| 821 | 
            -
                 | 
| 822 | 
            -
             | 
| 823 | 
            -
                VALUE typename = parse_type_name(state, INTERFACE_NAME | CLASS_NAME | ALIAS_NAME, &name_range);
         | 
| 824 | 
            -
                VALUE types = rb_ary_new();
         | 
| 825 | 
            -
             | 
| 826 | 
            -
                TypeNameKind kind;
         | 
| 827 | 
            -
                if (state->current_token.type == tUIDENT) {
         | 
| 828 | 
            -
                  kind = CLASS_NAME;
         | 
| 829 | 
            -
                } else if (state->current_token.type == tULIDENT) {
         | 
| 830 | 
            -
                  kind = INTERFACE_NAME;
         | 
| 831 | 
            -
                } else if (state->current_token.type == tLIDENT) {
         | 
| 832 | 
            -
                  kind = ALIAS_NAME;
         | 
| 833 | 
            -
                } else {
         | 
| 834 | 
            -
                  rbs_abort();
         | 
| 835 | 
            -
                }
         | 
| 836 | 
            -
             | 
| 837 | 
            -
                if (state->next_token.type == pLBRACKET) {
         | 
| 838 | 
            -
                  parser_advance(state);
         | 
| 839 | 
            -
                  args_range.start = state->current_token.range.start;
         | 
| 840 | 
            -
                  parse_type_list(state, pRBRACKET, types);
         | 
| 841 | 
            -
                  parser_advance_assert(state, pRBRACKET);
         | 
| 842 | 
            -
                  args_range.end = state->current_token.range.end;
         | 
| 843 | 
            -
                } else {
         | 
| 844 | 
            -
                  args_range = NULL_RANGE;
         | 
| 845 | 
            -
                }
         | 
| 846 | 
            -
             | 
| 847 | 
            -
                type_range.start = name_range.start;
         | 
| 848 | 
            -
                type_range.end = nonnull_pos_or(args_range.end, name_range.end);
         | 
| 849 | 
            -
             | 
| 850 | 
            -
                VALUE location = rbs_new_location(state->buffer, type_range);
         | 
| 851 | 
            -
                rbs_loc *loc = rbs_check_location(location);
         | 
| 852 | 
            -
                rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
         | 
| 853 | 
            -
                rbs_loc_add_optional_child(loc, rb_intern("args"), args_range);
         | 
| 854 | 
            -
             | 
| 855 | 
            -
                if (kind == CLASS_NAME) {
         | 
| 856 | 
            -
                  return rbs_class_instance(typename, types, location);
         | 
| 857 | 
            -
                } else if (kind == INTERFACE_NAME) {
         | 
| 858 | 
            -
                  return rbs_interface(typename, types, location);
         | 
| 859 | 
            -
                } else if (kind == ALIAS_NAME) {
         | 
| 860 | 
            -
                  return rbs_alias(typename, location);
         | 
| 861 | 
            -
                } else {
         | 
| 862 | 
            -
                  return Qnil;
         | 
| 863 | 
            -
                }
         | 
| 864 | 
            -
              }
         | 
| 865 | 
            -
              case tLIDENT: {
         | 
| 866 | 
            -
                VALUE location = rbs_location_current_token(state);
         | 
| 867 | 
            -
                rbs_loc *loc = rbs_check_location(location);
         | 
| 868 | 
            -
                rbs_loc_add_required_child(loc, rb_intern("name"), state->current_token.range);
         | 
| 869 | 
            -
                rbs_loc_add_optional_child(loc, rb_intern("args"), NULL_RANGE);
         | 
| 870 | 
            -
                VALUE typename = parse_type_name(state, ALIAS_NAME, NULL);
         | 
| 871 | 
            -
                return rbs_alias(typename, location);
         | 
| 872 | 
            -
              }
         | 
| 873 | 
            -
              case kSINGLETON: {
         | 
| 874 | 
            -
                range name_range;
         | 
| 875 | 
            -
                range type_range;
         | 
| 876 | 
            -
             | 
| 877 | 
            -
                type_range.start = state->current_token.range.start;
         | 
| 878 | 
            -
                parser_advance_assert(state, pLPAREN);
         | 
| 879 | 
            -
                parser_advance(state);
         | 
| 880 | 
            -
             | 
| 881 | 
            -
                VALUE typename = parse_type_name(state, CLASS_NAME, &name_range);
         | 
| 882 | 
            -
             | 
| 883 | 
            -
                parser_advance_assert(state, pRPAREN);
         | 
| 884 | 
            -
                type_range.end = state->current_token.range.end;
         | 
| 885 | 
            -
             | 
| 886 | 
            -
                VALUE location = rbs_new_location(state->buffer, type_range);
         | 
| 887 | 
            -
                rbs_loc *loc = rbs_check_location(location);
         | 
| 888 | 
            -
                rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
         | 
| 889 | 
            -
             | 
| 890 | 
            -
                return rbs_class_singleton(typename, location);
         | 
| 891 | 
            -
              }
         | 
| 900 | 
            +
              case tULIDENT: // fallthrough
         | 
| 901 | 
            +
              case tLIDENT: // fallthrough
         | 
| 902 | 
            +
              case pCOLON2:
         | 
| 903 | 
            +
                return parse_instance_type(state, true);
         | 
| 904 | 
            +
              case kSINGLETON:
         | 
| 905 | 
            +
                return parse_singleton_type(state);
         | 
| 892 906 | 
             
              case pLBRACKET: {
         | 
| 893 907 | 
             
                range rg;
         | 
| 894 908 | 
             
                rg.start = state->current_token.range.start;
         | 
| @@ -976,53 +990,151 @@ VALUE parse_type(parserstate *state) { | |
| 976 990 | 
             
            }
         | 
| 977 991 |  | 
| 978 992 | 
             
            /*
         | 
| 979 | 
            -
               | 
| 980 | 
            -
                            | {} | 
| 993 | 
            +
              type_params ::= {} `[` type_param `,` ... <`]`>
         | 
| 994 | 
            +
                            | {<>}
         | 
| 995 | 
            +
             | 
| 996 | 
            +
              type_param ::= kUNCHECKED? (kIN|kOUT|) tUIDENT    (module_type_params == true)
         | 
| 997 | 
            +
             | 
| 998 | 
            +
              type_param ::= tUIDENT                            (module_type_params == false)
         | 
| 981 999 | 
             
            */
         | 
| 982 | 
            -
            VALUE parse_method_type(parserstate *state) {
         | 
| 983 | 
            -
              VALUE function = Qnil;
         | 
| 984 | 
            -
              VALUE block = Qnil;
         | 
| 985 | 
            -
              id_table *table = parser_push_typevar_table(state, false);
         | 
| 986 1000 |  | 
| 987 | 
            -
             | 
| 1001 | 
            +
            VALUE parse_type_params(parserstate *state, range *rg, bool module_type_params) {
         | 
| 1002 | 
            +
              VALUE params = rb_ary_new();
         | 
| 988 1003 |  | 
| 989 1004 | 
             
              if (state->next_token.type == pLBRACKET) {
         | 
| 990 1005 | 
             
                parser_advance(state);
         | 
| 991 1006 |  | 
| 1007 | 
            +
                rg->start = state->current_token.range.start;
         | 
| 1008 | 
            +
             | 
| 992 1009 | 
             
                while (true) {
         | 
| 1010 | 
            +
                  VALUE name;
         | 
| 1011 | 
            +
                  bool unchecked = false;
         | 
| 1012 | 
            +
                  VALUE variance = ID2SYM(rb_intern("invariant"));
         | 
| 1013 | 
            +
                  VALUE upper_bound = Qnil;
         | 
| 1014 | 
            +
             | 
| 1015 | 
            +
                  range param_range = NULL_RANGE;
         | 
| 1016 | 
            +
                  range name_range;
         | 
| 1017 | 
            +
                  range variance_range = NULL_RANGE;
         | 
| 1018 | 
            +
                  range unchecked_range = NULL_RANGE;
         | 
| 1019 | 
            +
                  range upper_bound_range = NULL_RANGE;
         | 
| 1020 | 
            +
             | 
| 1021 | 
            +
                  param_range.start = state->next_token.range.start;
         | 
| 1022 | 
            +
             | 
| 1023 | 
            +
                  if (module_type_params) {
         | 
| 1024 | 
            +
                    if (state->next_token.type == kUNCHECKED) {
         | 
| 1025 | 
            +
                      unchecked = true;
         | 
| 1026 | 
            +
                      parser_advance(state);
         | 
| 1027 | 
            +
                      unchecked_range = state->current_token.range;
         | 
| 1028 | 
            +
                    }
         | 
| 1029 | 
            +
             | 
| 1030 | 
            +
                    if (state->next_token.type == kIN || state->next_token.type == kOUT) {
         | 
| 1031 | 
            +
                      switch (state->next_token.type) {
         | 
| 1032 | 
            +
                      case kIN:
         | 
| 1033 | 
            +
                        variance = ID2SYM(rb_intern("contravariant"));
         | 
| 1034 | 
            +
                        break;
         | 
| 1035 | 
            +
                      case kOUT:
         | 
| 1036 | 
            +
                        variance = ID2SYM(rb_intern("covariant"));
         | 
| 1037 | 
            +
                        break;
         | 
| 1038 | 
            +
                      default:
         | 
| 1039 | 
            +
                        rbs_abort();
         | 
| 1040 | 
            +
                      }
         | 
| 1041 | 
            +
             | 
| 1042 | 
            +
                      parser_advance(state);
         | 
| 1043 | 
            +
                      variance_range = state->current_token.range;
         | 
| 1044 | 
            +
                    }
         | 
| 1045 | 
            +
                  }
         | 
| 1046 | 
            +
             | 
| 993 1047 | 
             
                  parser_advance_assert(state, tUIDENT);
         | 
| 994 | 
            -
                   | 
| 995 | 
            -
                   | 
| 1048 | 
            +
                  name_range = state->current_token.range;
         | 
| 1049 | 
            +
                  param_range.end = state->current_token.range.end;
         | 
| 996 1050 |  | 
| 997 | 
            -
                   | 
| 1051 | 
            +
                  ID id = INTERN_TOKEN(state, state->current_token);
         | 
| 1052 | 
            +
                  name = ID2SYM(id);
         | 
| 1053 | 
            +
             | 
| 1054 | 
            +
                  parser_insert_typevar(state, id);
         | 
| 1055 | 
            +
             | 
| 1056 | 
            +
                  if (state->next_token.type == pLT) {
         | 
| 998 1057 | 
             
                    parser_advance(state);
         | 
| 999 | 
            -
             | 
| 1000 | 
            -
             | 
| 1058 | 
            +
             | 
| 1059 | 
            +
                    if (state->next_token.type == kSINGLETON) {
         | 
| 1060 | 
            +
                      parser_advance(state);
         | 
| 1061 | 
            +
                      upper_bound = parse_singleton_type(state);
         | 
| 1062 | 
            +
                    } else {
         | 
| 1063 | 
            +
                      parser_advance(state);
         | 
| 1064 | 
            +
                      upper_bound = parse_instance_type(state, false);
         | 
| 1001 1065 | 
             
                    }
         | 
| 1002 | 
            -
                  } | 
| 1066 | 
            +
                  }
         | 
| 1067 | 
            +
             | 
| 1068 | 
            +
                  VALUE location = rbs_new_location(state->buffer, param_range);
         | 
| 1069 | 
            +
                  rbs_loc *loc = rbs_check_location(location);
         | 
| 1070 | 
            +
                  rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
         | 
| 1071 | 
            +
                  rbs_loc_add_optional_child(loc, rb_intern("variance"), variance_range);
         | 
| 1072 | 
            +
                  rbs_loc_add_optional_child(loc, rb_intern("unchecked"), unchecked_range);
         | 
| 1073 | 
            +
                  rbs_loc_add_optional_child(loc, rb_intern("upper_bound"), upper_bound_range);
         | 
| 1074 | 
            +
             | 
| 1075 | 
            +
                  VALUE param = rbs_ast_type_param(name, variance, unchecked, upper_bound, location);
         | 
| 1076 | 
            +
                  rb_ary_push(params, param);
         | 
| 1077 | 
            +
             | 
| 1078 | 
            +
                  if (state->next_token.type == pCOMMA) {
         | 
| 1079 | 
            +
                    parser_advance(state);
         | 
| 1080 | 
            +
                  }
         | 
| 1081 | 
            +
             | 
| 1082 | 
            +
                  if (state->next_token.type == pRBRACKET) {
         | 
| 1003 1083 | 
             
                    break;
         | 
| 1004 1084 | 
             
                  }
         | 
| 1005 1085 | 
             
                }
         | 
| 1006 1086 |  | 
| 1007 1087 | 
             
                parser_advance_assert(state, pRBRACKET);
         | 
| 1088 | 
            +
                rg->end = state->current_token.range.end;
         | 
| 1089 | 
            +
              } else {
         | 
| 1090 | 
            +
                *rg = NULL_RANGE;
         | 
| 1008 1091 | 
             
              }
         | 
| 1009 1092 |  | 
| 1010 | 
            -
               | 
| 1093 | 
            +
              rb_funcall(
         | 
| 1094 | 
            +
                RBS_AST_TypeParam,
         | 
| 1095 | 
            +
                rb_intern("resolve_variables"),
         | 
| 1096 | 
            +
                1,
         | 
| 1097 | 
            +
                params
         | 
| 1098 | 
            +
              );
         | 
| 1011 1099 |  | 
| 1012 | 
            -
               | 
| 1100 | 
            +
              return params;
         | 
| 1101 | 
            +
            }
         | 
| 1013 1102 |  | 
| 1014 | 
            -
             | 
| 1015 | 
            -
               | 
| 1016 | 
            -
             | 
| 1017 | 
            -
             | 
| 1103 | 
            +
            /*
         | 
| 1104 | 
            +
              method_type ::= {} type_params <function>
         | 
| 1105 | 
            +
              */
         | 
| 1106 | 
            +
            VALUE parse_method_type(parserstate *state) {
         | 
| 1107 | 
            +
              range rg;
         | 
| 1108 | 
            +
              range params_range = NULL_RANGE;
         | 
| 1109 | 
            +
              range type_range;
         | 
| 1110 | 
            +
             | 
| 1111 | 
            +
              VALUE function = Qnil;
         | 
| 1112 | 
            +
              VALUE block = Qnil;
         | 
| 1113 | 
            +
              parser_push_typevar_table(state, false);
         | 
| 1114 | 
            +
             | 
| 1115 | 
            +
              rg.start = state->next_token.range.start;
         | 
| 1116 | 
            +
             | 
| 1117 | 
            +
              VALUE type_params = parse_type_params(state, ¶ms_range, false);
         | 
| 1118 | 
            +
             | 
| 1119 | 
            +
              type_range.start = state->next_token.range.start;
         | 
| 1120 | 
            +
             | 
| 1121 | 
            +
              parse_function(state, &function, &block);
         | 
| 1122 | 
            +
             | 
| 1123 | 
            +
              rg.end = state->current_token.range.end;
         | 
| 1124 | 
            +
              type_range.end = rg.end;
         | 
| 1018 1125 |  | 
| 1019 1126 | 
             
              parser_pop_typevar_table(state);
         | 
| 1020 1127 |  | 
| 1128 | 
            +
              VALUE location = rbs_new_location(state->buffer, rg);
         | 
| 1129 | 
            +
              rbs_loc *loc = rbs_check_location(location);
         | 
| 1130 | 
            +
              rbs_loc_add_required_child(loc, rb_intern("type"), type_range);
         | 
| 1131 | 
            +
              rbs_loc_add_optional_child(loc, rb_intern("type_params"), params_range);
         | 
| 1132 | 
            +
             | 
| 1021 1133 | 
             
              return rbs_method_type(
         | 
| 1022 1134 | 
             
                type_params,
         | 
| 1023 1135 | 
             
                function,
         | 
| 1024 1136 | 
             
                block,
         | 
| 1025 | 
            -
                 | 
| 1137 | 
            +
                location
         | 
| 1026 1138 | 
             
              );
         | 
| 1027 1139 | 
             
            }
         | 
| 1028 1140 |  | 
| @@ -1098,7 +1210,9 @@ VALUE parse_const_decl(parserstate *state) { | |
| 1098 1210 | 
             
            */
         | 
| 1099 1211 | 
             
            VALUE parse_type_decl(parserstate *state, position comment_pos, VALUE annotations) {
         | 
| 1100 1212 | 
             
              range decl_range;
         | 
| 1101 | 
            -
              range keyword_range, name_range, eq_range;
         | 
| 1213 | 
            +
              range keyword_range, name_range, params_range, eq_range;
         | 
| 1214 | 
            +
             | 
| 1215 | 
            +
              parser_push_typevar_table(state, true);
         | 
| 1102 1216 |  | 
| 1103 1217 | 
             
              decl_range.start = state->current_token.range.start;
         | 
| 1104 1218 | 
             
              comment_pos = nonnull_pos_or(comment_pos, decl_range.start);
         | 
| @@ -1108,6 +1222,8 @@ VALUE parse_type_decl(parserstate *state, position comment_pos, VALUE annotation | |
| 1108 1222 | 
             
              parser_advance(state);
         | 
| 1109 1223 | 
             
              VALUE typename = parse_type_name(state, ALIAS_NAME, &name_range);
         | 
| 1110 1224 |  | 
| 1225 | 
            +
              VALUE type_params = parse_type_params(state, ¶ms_range, true);
         | 
| 1226 | 
            +
             | 
| 1111 1227 | 
             
              parser_advance_assert(state, pEQ);
         | 
| 1112 1228 | 
             
              eq_range = state->current_token.range;
         | 
| 1113 1229 |  | 
| @@ -1118,10 +1234,14 @@ VALUE parse_type_decl(parserstate *state, position comment_pos, VALUE annotation | |
| 1118 1234 | 
             
              rbs_loc *loc = rbs_check_location(location);
         | 
| 1119 1235 | 
             
              rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range);
         | 
| 1120 1236 | 
             
              rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
         | 
| 1237 | 
            +
              rbs_loc_add_optional_child(loc, rb_intern("type_params"), params_range);
         | 
| 1121 1238 | 
             
              rbs_loc_add_required_child(loc, rb_intern("eq"), eq_range);
         | 
| 1122 1239 |  | 
| 1240 | 
            +
              parser_pop_typevar_table(state);
         | 
| 1241 | 
            +
             | 
| 1123 1242 | 
             
              return rbs_ast_decl_alias(
         | 
| 1124 1243 | 
             
                typename,
         | 
| 1244 | 
            +
                type_params,
         | 
| 1125 1245 | 
             
                type,
         | 
| 1126 1246 | 
             
                annotations,
         | 
| 1127 1247 | 
             
                location,
         | 
| @@ -1184,90 +1304,6 @@ VALUE parse_annotation(parserstate *state) { | |
| 1184 1304 | 
             
              return rbs_ast_annotation(string, location);
         | 
| 1185 1305 | 
             
            }
         | 
| 1186 1306 |  | 
| 1187 | 
            -
            /*
         | 
| 1188 | 
            -
              module_type_params ::= {} `[` module_type_param `,` ... <`]`>
         | 
| 1189 | 
            -
                                   | {<>}
         | 
| 1190 | 
            -
             | 
| 1191 | 
            -
              module_type_param ::= kUNCHECKED? (kIN|kOUT|) tUIDENT
         | 
| 1192 | 
            -
            */
         | 
| 1193 | 
            -
            VALUE parse_module_type_params(parserstate *state, range *rg) {
         | 
| 1194 | 
            -
              VALUE params = rbs_ast_decl_module_type_params();
         | 
| 1195 | 
            -
             | 
| 1196 | 
            -
              if (state->next_token.type == pLBRACKET) {
         | 
| 1197 | 
            -
                parser_advance(state);
         | 
| 1198 | 
            -
             | 
| 1199 | 
            -
                rg->start = state->current_token.range.start;
         | 
| 1200 | 
            -
             | 
| 1201 | 
            -
                while (true) {
         | 
| 1202 | 
            -
                  VALUE name;
         | 
| 1203 | 
            -
                  VALUE unchecked = Qfalse;
         | 
| 1204 | 
            -
                  VALUE variance = ID2SYM(rb_intern("invariant"));
         | 
| 1205 | 
            -
             | 
| 1206 | 
            -
                  range param_range = NULL_RANGE;
         | 
| 1207 | 
            -
                  range name_range;
         | 
| 1208 | 
            -
                  range variance_range = NULL_RANGE;
         | 
| 1209 | 
            -
                  range unchecked_range = NULL_RANGE;
         | 
| 1210 | 
            -
             | 
| 1211 | 
            -
                  param_range.start = state->next_token.range.start;
         | 
| 1212 | 
            -
             | 
| 1213 | 
            -
                  if (state->next_token.type == kUNCHECKED) {
         | 
| 1214 | 
            -
                    unchecked = Qtrue;
         | 
| 1215 | 
            -
                    parser_advance(state);
         | 
| 1216 | 
            -
                    unchecked_range = state->current_token.range;
         | 
| 1217 | 
            -
                  }
         | 
| 1218 | 
            -
             | 
| 1219 | 
            -
                  if (state->next_token.type == kIN || state->next_token.type == kOUT) {
         | 
| 1220 | 
            -
                    switch (state->next_token.type) {
         | 
| 1221 | 
            -
                    case kIN:
         | 
| 1222 | 
            -
                      variance = ID2SYM(rb_intern("contravariant"));
         | 
| 1223 | 
            -
                      break;
         | 
| 1224 | 
            -
                    case kOUT:
         | 
| 1225 | 
            -
                      variance = ID2SYM(rb_intern("covariant"));
         | 
| 1226 | 
            -
                      break;
         | 
| 1227 | 
            -
                    default:
         | 
| 1228 | 
            -
                      rbs_abort();
         | 
| 1229 | 
            -
                    }
         | 
| 1230 | 
            -
             | 
| 1231 | 
            -
                    parser_advance(state);
         | 
| 1232 | 
            -
                    variance_range = state->current_token.range;
         | 
| 1233 | 
            -
                  }
         | 
| 1234 | 
            -
             | 
| 1235 | 
            -
                  parser_advance_assert(state, tUIDENT);
         | 
| 1236 | 
            -
                  name_range = state->current_token.range;
         | 
| 1237 | 
            -
                  param_range.end = state->current_token.range.end;
         | 
| 1238 | 
            -
             | 
| 1239 | 
            -
                  ID id = INTERN_TOKEN(state, state->current_token);
         | 
| 1240 | 
            -
                  name = ID2SYM(id);
         | 
| 1241 | 
            -
             | 
| 1242 | 
            -
                  parser_insert_typevar(state, id);
         | 
| 1243 | 
            -
             | 
| 1244 | 
            -
                  VALUE location = rbs_new_location(state->buffer, param_range);
         | 
| 1245 | 
            -
                  rbs_loc *loc = rbs_check_location(location);
         | 
| 1246 | 
            -
                  rbs_loc_add_required_child(loc, rb_intern("name"), name_range);
         | 
| 1247 | 
            -
                  rbs_loc_add_optional_child(loc, rb_intern("variance"), variance_range);
         | 
| 1248 | 
            -
                  rbs_loc_add_optional_child(loc, rb_intern("unchecked"), unchecked_range);
         | 
| 1249 | 
            -
             | 
| 1250 | 
            -
                  VALUE param = rbs_ast_decl_module_type_params_param(name, variance, unchecked, location);
         | 
| 1251 | 
            -
                  rb_funcall(params, rb_intern("add"), 1, param);
         | 
| 1252 | 
            -
             | 
| 1253 | 
            -
                  if (state->next_token.type == pCOMMA) {
         | 
| 1254 | 
            -
                    parser_advance(state);
         | 
| 1255 | 
            -
                  }
         | 
| 1256 | 
            -
             | 
| 1257 | 
            -
                  if (state->next_token.type == pRBRACKET) {
         | 
| 1258 | 
            -
                    break;
         | 
| 1259 | 
            -
                  }
         | 
| 1260 | 
            -
                }
         | 
| 1261 | 
            -
             | 
| 1262 | 
            -
                parser_advance_assert(state, pRBRACKET);
         | 
| 1263 | 
            -
                rg->end = state->current_token.range.end;
         | 
| 1264 | 
            -
              } else {
         | 
| 1265 | 
            -
                *rg = NULL_RANGE;
         | 
| 1266 | 
            -
              }
         | 
| 1267 | 
            -
             | 
| 1268 | 
            -
              return params;
         | 
| 1269 | 
            -
            }
         | 
| 1270 | 
            -
             | 
| 1271 1307 | 
             
            /*
         | 
| 1272 1308 | 
             
              annotations ::= {} annotation ... <annotation>
         | 
| 1273 1309 | 
             
                            | {<>}
         | 
| @@ -1966,7 +2002,7 @@ VALUE parse_interface_decl(parserstate *state, position comment_pos, VALUE annot | |
| 1966 2002 | 
             
              parser_advance(state);
         | 
| 1967 2003 |  | 
| 1968 2004 | 
             
              VALUE name = parse_type_name(state, INTERFACE_NAME, &name_range);
         | 
| 1969 | 
            -
              VALUE params =  | 
| 2005 | 
            +
              VALUE params = parse_type_params(state, &type_params_range, true);
         | 
| 1970 2006 | 
             
              VALUE members = parse_interface_members(state);
         | 
| 1971 2007 |  | 
| 1972 2008 | 
             
              parser_advance_assert(state, kEND);
         | 
| @@ -2130,7 +2166,7 @@ VALUE parse_module_decl(parserstate *state, position comment_pos, VALUE annotati | |
| 2130 2166 |  | 
| 2131 2167 | 
             
              parser_advance(state);
         | 
| 2132 2168 | 
             
              VALUE module_name = parse_type_name(state, CLASS_NAME, &name_range);
         | 
| 2133 | 
            -
              VALUE type_params =  | 
| 2169 | 
            +
              VALUE type_params = parse_type_params(state, &type_params_range, true);
         | 
| 2134 2170 | 
             
              VALUE self_types = rb_ary_new();
         | 
| 2135 2171 |  | 
| 2136 2172 | 
             
              if (state->next_token.type == pCOLON) {
         | 
| @@ -2237,7 +2273,7 @@ VALUE parse_class_decl(parserstate *state, position comment_pos, VALUE annotatio | |
| 2237 2273 |  | 
| 2238 2274 | 
             
              parser_advance(state);
         | 
| 2239 2275 | 
             
              name = parse_type_name(state, CLASS_NAME, &name_range);
         | 
| 2240 | 
            -
              type_params =  | 
| 2276 | 
            +
              type_params = parse_type_params(state, &type_params_range, true);
         | 
| 2241 2277 | 
             
              super = parse_class_decl_super(state, <_range);
         | 
| 2242 2278 | 
             
              members = parse_module_members(state);
         | 
| 2243 2279 | 
             
              parser_advance_assert(state, kEND);
         | 
| @@ -130,8 +130,7 @@ bool parser_advance_if(parserstate *state, enum TokenType type) { | |
| 130 130 | 
             
              }
         | 
| 131 131 | 
             
            }
         | 
| 132 132 |  | 
| 133 | 
            -
            void  | 
| 134 | 
            -
              parser_advance(state);
         | 
| 133 | 
            +
            void parser_assert(parserstate *state, enum TokenType type) {
         | 
| 135 134 | 
             
              if (state->current_token.type != type) {
         | 
| 136 135 | 
             
                raise_syntax_error(
         | 
| 137 136 | 
             
                  state,
         | 
| @@ -142,6 +141,11 @@ void parser_advance_assert(parserstate *state, enum TokenType type) { | |
| 142 141 | 
             
              }
         | 
| 143 142 | 
             
            }
         | 
| 144 143 |  | 
| 144 | 
            +
            void parser_advance_assert(parserstate *state, enum TokenType type) {
         | 
| 145 | 
            +
              parser_advance(state);
         | 
| 146 | 
            +
              parser_assert(state, type);
         | 
| 147 | 
            +
            }
         | 
| 148 | 
            +
             | 
| 145 149 | 
             
            void print_token(token tok) {
         | 
| 146 150 | 
             
              printf(
         | 
| 147 151 | 
             
                "%s char=%d...%d\n",
         | 
| @@ -107,11 +107,21 @@ void free_parser(parserstate *parser); | |
| 107 107 | 
             
             * Advance one token.
         | 
| 108 108 | 
             
             * */
         | 
| 109 109 | 
             
            void parser_advance(parserstate *state);
         | 
| 110 | 
            +
             | 
| 111 | 
            +
            /**
         | 
| 112 | 
            +
             * @brief Raises an exception if `current_token->type != type`.
         | 
| 113 | 
            +
             *
         | 
| 114 | 
            +
             * @param state
         | 
| 115 | 
            +
             * @param type
         | 
| 116 | 
            +
             */
         | 
| 117 | 
            +
            void parser_assert(parserstate *state, enum TokenType type);
         | 
| 118 | 
            +
             | 
| 110 119 | 
             
            /**
         | 
| 111 120 | 
             
             * Advance one token, and assert the current token type.
         | 
| 112 121 | 
             
             * Raises an exception if `current_token->type != type`.
         | 
| 113 122 | 
             
             * */
         | 
| 114 123 | 
             
            void parser_advance_assert(parserstate *state, enum TokenType type);
         | 
| 124 | 
            +
             | 
| 115 125 | 
             
            /**
         | 
| 116 126 | 
             
             * Advance one token if the next_token is a token of the type.
         | 
| 117 127 | 
             
             * */
         | 
| @@ -70,15 +70,16 @@ VALUE rbs_class_singleton(VALUE typename, VALUE location) { | |
| 70 70 | 
             
              );
         | 
| 71 71 | 
             
            }
         | 
| 72 72 |  | 
| 73 | 
            -
            VALUE rbs_alias(VALUE typename, VALUE location) {
         | 
| 74 | 
            -
              VALUE  | 
| 75 | 
            -
              rb_hash_aset( | 
| 76 | 
            -
              rb_hash_aset( | 
| 73 | 
            +
            VALUE rbs_alias(VALUE typename, VALUE args, VALUE location) {
         | 
| 74 | 
            +
              VALUE kwargs = rb_hash_new();
         | 
| 75 | 
            +
              rb_hash_aset(kwargs, ID2SYM(rb_intern("name")), typename);
         | 
| 76 | 
            +
              rb_hash_aset(kwargs, ID2SYM(rb_intern("args")), args);
         | 
| 77 | 
            +
              rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location);
         | 
| 77 78 |  | 
| 78 79 | 
             
              return CLASS_NEW_INSTANCE(
         | 
| 79 80 | 
             
                RBS_Types_Alias,
         | 
| 80 81 | 
             
                1,
         | 
| 81 | 
            -
                & | 
| 82 | 
            +
                &kwargs
         | 
| 82 83 | 
             
              );
         | 
| 83 84 | 
             
            }
         | 
| 84 85 |  | 
| @@ -293,22 +294,20 @@ VALUE rbs_ast_annotation(VALUE string, VALUE location) { | |
| 293 294 | 
             
              );
         | 
| 294 295 | 
             
            }
         | 
| 295 296 |  | 
| 296 | 
            -
            VALUE  | 
| 297 | 
            -
              return rb_funcall(RBS_AST_Declarations_ModuleTypeParams, rb_intern("new"), 0);
         | 
| 298 | 
            -
            }
         | 
| 299 | 
            -
             | 
| 300 | 
            -
            VALUE rbs_ast_decl_module_type_params_param(VALUE name, VALUE variance, VALUE skip_validation, VALUE location) {
         | 
| 297 | 
            +
            VALUE rbs_ast_type_param(VALUE name, VALUE variance, bool unchecked, VALUE upper_bound, VALUE location) {
         | 
| 301 298 | 
             
              VALUE args = rb_hash_new();
         | 
| 302 299 | 
             
              rb_hash_aset(args, ID2SYM(rb_intern("name")), name);
         | 
| 303 300 | 
             
              rb_hash_aset(args, ID2SYM(rb_intern("variance")), variance);
         | 
| 304 | 
            -
              rb_hash_aset(args, ID2SYM(rb_intern(" | 
| 301 | 
            +
              rb_hash_aset(args, ID2SYM(rb_intern("upper_bound")), upper_bound);
         | 
| 305 302 | 
             
              rb_hash_aset(args, ID2SYM(rb_intern("location")), location);
         | 
| 306 303 |  | 
| 307 | 
            -
               | 
| 308 | 
            -
             | 
| 309 | 
            -
             | 
| 310 | 
            -
                 | 
| 311 | 
            -
               | 
| 304 | 
            +
              VALUE type_param = CLASS_NEW_INSTANCE(RBS_AST_TypeParam, 1, &args);
         | 
| 305 | 
            +
             | 
| 306 | 
            +
              if (unchecked) {
         | 
| 307 | 
            +
                rb_funcall(type_param, rb_intern("unchecked!"), 0);
         | 
| 308 | 
            +
              }
         | 
| 309 | 
            +
             | 
| 310 | 
            +
              return type_param;
         | 
| 312 311 | 
             
            }
         | 
| 313 312 |  | 
| 314 313 | 
             
            VALUE rbs_ast_decl_constant(VALUE name, VALUE type, VALUE location, VALUE comment) {
         | 
| @@ -339,9 +338,10 @@ VALUE rbs_ast_decl_global(VALUE name, VALUE type, VALUE location, VALUE comment) | |
| 339 338 | 
             
              );
         | 
| 340 339 | 
             
            }
         | 
| 341 340 |  | 
| 342 | 
            -
            VALUE rbs_ast_decl_alias(VALUE name, VALUE type, VALUE annotations, VALUE location, VALUE comment) {
         | 
| 341 | 
            +
            VALUE rbs_ast_decl_alias(VALUE name, VALUE type_params, VALUE type, VALUE annotations, VALUE location, VALUE comment) {
         | 
| 343 342 | 
             
              VALUE args = rb_hash_new();
         | 
| 344 343 | 
             
              rb_hash_aset(args, ID2SYM(rb_intern("name")), name);
         | 
| 344 | 
            +
              rb_hash_aset(args, ID2SYM(rb_intern("type_params")), type_params);
         | 
| 345 345 | 
             
              rb_hash_aset(args, ID2SYM(rb_intern("type")), type);
         | 
| 346 346 | 
             
              rb_hash_aset(args, ID2SYM(rb_intern("annotations")), annotations);
         | 
| 347 347 | 
             
              rb_hash_aset(args, ID2SYM(rb_intern("location")), location);
         | 
| @@ -3,18 +3,17 @@ | |
| 3 3 |  | 
| 4 4 | 
             
            #include "ruby.h"
         | 
| 5 5 |  | 
| 6 | 
            -
            VALUE rbs_alias(VALUE typename, VALUE location);
         | 
| 6 | 
            +
            VALUE rbs_alias(VALUE typename, VALUE args, VALUE location);
         | 
| 7 7 | 
             
            VALUE rbs_ast_annotation(VALUE string, VALUE location);
         | 
| 8 8 | 
             
            VALUE rbs_ast_comment(VALUE string, VALUE location);
         | 
| 9 | 
            -
            VALUE  | 
| 9 | 
            +
            VALUE rbs_ast_type_param(VALUE name, VALUE variance, bool unchecked, VALUE upper_bound, VALUE location);
         | 
| 10 | 
            +
            VALUE rbs_ast_decl_alias(VALUE name, VALUE type_params, VALUE type, VALUE annotations, VALUE location, VALUE comment);
         | 
| 10 11 | 
             
            VALUE rbs_ast_decl_class_super(VALUE name, VALUE args, VALUE location);
         | 
| 11 12 | 
             
            VALUE rbs_ast_decl_class(VALUE name, VALUE type_params, VALUE super_class, VALUE members, VALUE annotations, VALUE location, VALUE comment);
         | 
| 12 13 | 
             
            VALUE rbs_ast_decl_constant(VALUE name, VALUE type, VALUE location, VALUE comment);
         | 
| 13 14 | 
             
            VALUE rbs_ast_decl_global(VALUE name, VALUE type, VALUE location, VALUE comment);
         | 
| 14 15 | 
             
            VALUE rbs_ast_decl_interface(VALUE name, VALUE type_params, VALUE members, VALUE annotations, VALUE location, VALUE comment);
         | 
| 15 16 | 
             
            VALUE rbs_ast_decl_module_self(VALUE name, VALUE args, VALUE location);
         | 
| 16 | 
            -
            VALUE rbs_ast_decl_module_type_params_param(VALUE name, VALUE variance, VALUE skip_validation, VALUE location);
         | 
| 17 | 
            -
            VALUE rbs_ast_decl_module_type_params();
         | 
| 18 17 | 
             
            VALUE rbs_ast_decl_module(VALUE name, VALUE type_params, VALUE self_types, VALUE members, VALUE annotations, VALUE location, VALUE comment);
         | 
| 19 18 | 
             
            VALUE rbs_ast_members_alias(VALUE new_name, VALUE old_name, VALUE kind, VALUE annotations, VALUE location, VALUE comment);
         | 
| 20 19 | 
             
            VALUE rbs_ast_members_attribute(VALUE klass, VALUE name, VALUE type, VALUE ivar_name, VALUE kind, VALUE annotations, VALUE location, VALUE comment);
         |