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);
|