From b8d3eb30e211dfde42e17df50aa0c4be55217865 Mon Sep 17 00:00:00 2001 From: Alexander Momchilov Date: Thu, 31 Oct 2024 14:12:40 -0400 Subject: [PATCH] Add templating mechanism to generate .c/.h files Generate the c/h code for constant definitions and object initialization. We make sure the Rake task builds the required templates so we can compile the extension. Co-authored-by: Alexandre Terrasa --- Rakefile | 8 + config.yml | 323 +++++++++++++++ ext/rbs_extension/constants.c | 77 ++-- ext/rbs_extension/constants.h | 26 +- ext/rbs_extension/parser.c | 151 ++++--- ext/rbs_extension/ruby_objs.c | 426 ++++++++++++++------ ext/rbs_extension/ruby_objs.h | 35 +- templates/ext/rbs_extension/constants.c.erb | 179 ++++++++ templates/ext/rbs_extension/constants.h.erb | 92 +++++ templates/ext/rbs_extension/ruby_objs.c.erb | 117 ++++++ templates/ext/rbs_extension/ruby_objs.h.erb | 60 +++ templates/template.rb | 130 ++++++ 12 files changed, 1371 insertions(+), 253 deletions(-) create mode 100644 config.yml create mode 100644 templates/ext/rbs_extension/constants.c.erb create mode 100644 templates/ext/rbs_extension/constants.h.erb create mode 100644 templates/ext/rbs_extension/ruby_objs.c.erb create mode 100644 templates/ext/rbs_extension/ruby_objs.h.erb create mode 100644 templates/template.rb diff --git a/Rakefile b/Rakefile index c835e31e2..45a2543cd 100644 --- a/Rakefile +++ b/Rakefile @@ -43,7 +43,15 @@ task :confirm_annotation do sh "git diff --exit-code core stdlib" end +task :templates do + sh "ruby templates/template.rb ext/rbs_extension/constants.h" + sh "ruby templates/template.rb ext/rbs_extension/ruby_objs.h" + sh "ruby templates/template.rb ext/rbs_extension/constants.c" + sh "ruby templates/template.rb ext/rbs_extension/ruby_objs.c" +end + task :compile => "ext/rbs_extension/lexer.c" +Rake::Task[:compile].prereqs.prepend :templates task :test_doc do files = Dir.chdir(File.expand_path('..', __FILE__)) do diff --git a/config.yml b/config.yml new file mode 100644 index 000000000..58c825506 --- /dev/null +++ b/config.yml @@ -0,0 +1,323 @@ +nodes: + - name: RBS::AST::Annotation + fields: + - name: string + - name: location + - name: RBS::AST::Comment + fields: + - name: string + - name: location + - name: RBS::AST::Declarations::Class + fields: + - name: name + - name: type_params + - name: super_class + - name: members + - name: annotations + - name: location + - name: comment + - name: RBS::AST::Declarations::Class::Super + fields: + - name: name + - name: args + - name: location + - name: RBS::AST::Declarations::ClassAlias + fields: + - name: new_name + - name: old_name + - name: location + - name: comment + - name: RBS::AST::Declarations::Constant + fields: + - name: name + - name: type + - name: location + - name: comment + - name: RBS::AST::Declarations::Global + fields: + - name: name + - name: type + - name: location + - name: comment + - name: RBS::AST::Declarations::Interface + fields: + - name: name + - name: type_params + - name: members + - name: annotations + - name: location + - name: comment + - name: RBS::AST::Declarations::Module + fields: + - name: name + - name: type_params + - name: self_types + - name: members + - name: annotations + - name: location + - name: comment + - name: RBS::AST::Declarations::Module::Self + fields: + - name: name + - name: args + - name: location + - name: RBS::AST::Declarations::ModuleAlias + fields: + - name: new_name + - name: old_name + - name: location + - name: comment + - name: RBS::AST::Declarations::TypeAlias + fields: + - name: name + - name: type_params + - name: type + - name: annotations + - name: location + - name: comment + - name: RBS::AST::Directives::Use + fields: + - name: clauses + - name: location + - name: RBS::AST::Directives::Use::SingleClause + fields: + - name: type_name + - name: new_name + - name: location + - name: RBS::AST::Directives::Use::WildcardClause + fields: + - name: namespace + - name: location + - name: RBS::AST::Members::Alias + fields: + - name: new_name + - name: old_name + - name: kind + - name: annotations + - name: location + - name: comment + - name: RBS::AST::Members::AttrAccessor + fields: + - name: name + - name: type + - name: ivar_name + - name: kind + - name: annotations + - name: location + - name: comment + - name: visibility + - name: RBS::AST::Members::AttrReader + fields: + - name: name + - name: type + - name: ivar_name + - name: kind + - name: annotations + - name: location + - name: comment + - name: visibility + - name: RBS::AST::Members::AttrWriter + fields: + - name: name + - name: type + - name: ivar_name + - name: kind + - name: annotations + - name: location + - name: comment + - name: visibility + - name: RBS::AST::Members::ClassInstanceVariable + fields: + - name: name + - name: type + - name: location + - name: comment + - name: RBS::AST::Members::ClassVariable + fields: + - name: name + - name: type + - name: location + - name: comment + - name: RBS::AST::Members::Extend + fields: + - name: name + - name: args + - name: annotations + - name: location + - name: comment + - name: RBS::AST::Members::Include + fields: + - name: name + - name: args + - name: annotations + - name: location + - name: comment + - name: RBS::AST::Members::InstanceVariable + fields: + - name: name + - name: type + - name: location + - name: comment + - name: RBS::AST::Members::MethodDefinition + fields: + - name: name + - name: kind + - name: overloads + - name: annotations + - name: location + - name: comment + - name: overloading + - name: visibility + - name: RBS::AST::Members::MethodDefinition::Overload + fields: + - name: annotations + - name: method_type + - name: RBS::AST::Members::Prepend + fields: + - name: name + - name: args + - name: annotations + - name: location + - name: comment + - name: RBS::AST::Members::Private + fields: + - name: location + - name: RBS::AST::Members::Public + fields: + - name: location + - name: RBS::AST::TypeParam + fields: + - name: name + - name: variance + - name: upper_bound + - name: default_type + - name: location + - name: RBS::MethodType + fields: + - name: type_params + - name: type + - name: block + - name: location + - name: RBS::Namespace + fields: + - name: path + - name: absolute + - name: RBS::TypeName + fields: + - name: namespace + - name: name + - name: RBS::Types::Alias + fields: + - name: name + c_name: typename # Temporary name to match existing C code. Will be removed in next PR. + - name: args + - name: location + - name: RBS::Types::Bases::Any + fields: + - name: location + - name: RBS::Types::Bases::Bool + fields: + - name: location + - name: RBS::Types::Bases::Bottom + fields: + - name: location + - name: RBS::Types::Bases::Class + fields: + - name: location + - name: RBS::Types::Bases::Instance + fields: + - name: location + - name: RBS::Types::Bases::Nil + fields: + - name: location + - name: RBS::Types::Bases::Self + fields: + - name: location + - name: RBS::Types::Bases::Top + fields: + - name: location + - name: RBS::Types::Bases::Void + fields: + - name: location + - name: RBS::Types::Block + fields: + - name: type + - name: required + - name: self_type + - name: RBS::Types::ClassInstance + fields: + - name: name + c_name: typename # Temporary name to match existing C code. Will be removed in next PR. + - name: args + c_name: type_args # Temporary name to match existing C code. Will be removed in next PR. + - name: location + - name: RBS::Types::ClassSingleton + fields: + - name: name + c_name: typename # Temporary name to match existing C code. Will be removed in next PR. + - name: location + - name: RBS::Types::Function + fields: + - name: required_positionals + c_name: required_positional_params # Temporary name to match existing C code. Will be removed in next PR. + - name: optional_positionals + c_name: optional_positional_params # Temporary name to match existing C code. Will be removed in next PR. + - name: rest_positionals + c_name: rest_positional_params # Temporary name to match existing C code. Will be removed in next PR. + - name: trailing_positionals + c_name: trailing_positional_params # Temporary name to match existing C code. Will be removed in next PR. + - name: required_keywords + - name: optional_keywords + - name: rest_keywords + - name: return_type + - name: RBS::Types::Function::Param + fields: + - name: type + - name: name + - name: location + - name: RBS::Types::Interface + fields: + - name: name + c_name: typename # Temporary name to match existing C code. Will be removed in next PR. + - name: args + c_name: type_args # Temporary name to match existing C code. Will be removed in next PR. + - name: location + - name: RBS::Types::Intersection + fields: + - name: types + - name: location + - name: RBS::Types::Literal + fields: + - name: literal + - name: location + - name: RBS::Types::Optional + fields: + - name: type + - name: location + - name: RBS::Types::Proc + fields: + - name: type + c_name: function # Temporary name to match existing C code. Will be removed in next PR. + - name: block + - name: location + - name: self_type + - name: RBS::Types::Record + fields: + - name: all_fields + c_name: fields # Temporary name to match existing C code. Will be removed in next PR. + - name: location + - name: RBS::Types::Tuple + fields: + - name: types + - name: location + - name: RBS::Types::Union + fields: + - name: types + - name: location + - name: RBS::Types::UntypedFunction + fields: + - name: return_type + - name: RBS::Types::Variable + fields: + - name: name + - name: location diff --git a/ext/rbs_extension/constants.c b/ext/rbs_extension/constants.c index 0e21a1860..a72adbf6c 100644 --- a/ext/rbs_extension/constants.c +++ b/ext/rbs_extension/constants.c @@ -1,34 +1,40 @@ +/*----------------------------------------------------------------------------*/ +/* This file is generated by the templates/template.rb script and should not */ +/* be modified manually. */ +/* To change the template see */ +/* templates/ext/rbs_extension/constants.c.erb */ +/*----------------------------------------------------------------------------*/ + #include "rbs_extension.h" VALUE RBS_Parser; VALUE RBS; VALUE RBS_AST; -VALUE RBS_AST_Comment; -VALUE RBS_AST_Annotation; -VALUE RBS_AST_TypeParam; - VALUE RBS_AST_Declarations; +VALUE RBS_AST_Directives; +VALUE RBS_AST_Members; +VALUE RBS_Parser; +VALUE RBS_Types; +VALUE RBS_Types_Bases; -VALUE RBS_AST_Declarations_TypeAlias; + +VALUE RBS_AST_Annotation; +VALUE RBS_AST_Comment; +VALUE RBS_AST_Declarations_Class; +VALUE RBS_AST_Declarations_Class_Super; +VALUE RBS_AST_Declarations_ClassAlias; VALUE RBS_AST_Declarations_Constant; VALUE RBS_AST_Declarations_Global; VALUE RBS_AST_Declarations_Interface; VALUE RBS_AST_Declarations_Module; VALUE RBS_AST_Declarations_Module_Self; -VALUE RBS_AST_Declarations_Class; -VALUE RBS_AST_Declarations_Class_Super; VALUE RBS_AST_Declarations_ModuleAlias; -VALUE RBS_AST_Declarations_ClassAlias; - -VALUE RBS_AST_Directives; +VALUE RBS_AST_Declarations_TypeAlias; VALUE RBS_AST_Directives_Use; VALUE RBS_AST_Directives_Use_SingleClause; VALUE RBS_AST_Directives_Use_WildcardClause; - -VALUE RBS_AST_Members; VALUE RBS_AST_Members_Alias; -VALUE RBS_AST_Members_AttrAccessor; VALUE RBS_AST_Members_AttrReader; VALUE RBS_AST_Members_AttrWriter; VALUE RBS_AST_Members_ClassInstanceVariable; @@ -41,10 +47,10 @@ VALUE RBS_AST_Members_MethodDefinition_Overload; VALUE RBS_AST_Members_Prepend; VALUE RBS_AST_Members_Private; VALUE RBS_AST_Members_Public; - +VALUE RBS_AST_TypeParam; +VALUE RBS_MethodType; VALUE RBS_Namespace; VALUE RBS_TypeName; - VALUE RBS_Types_Alias; VALUE RBS_Types_Bases_Any; VALUE RBS_Types_Bases_Bool; @@ -55,13 +61,11 @@ VALUE RBS_Types_Bases_Nil; VALUE RBS_Types_Bases_Self; VALUE RBS_Types_Bases_Top; VALUE RBS_Types_Bases_Void; -VALUE RBS_Types_Bases; VALUE RBS_Types_Block; VALUE RBS_Types_ClassInstance; VALUE RBS_Types_ClassSingleton; -VALUE RBS_Types_Function_Param; VALUE RBS_Types_Function; -VALUE RBS_Types_UntypedFunction; +VALUE RBS_Types_Function_Param; VALUE RBS_Types_Interface; VALUE RBS_Types_Intersection; VALUE RBS_Types_Literal; @@ -70,9 +74,9 @@ VALUE RBS_Types_Proc; VALUE RBS_Types_Record; VALUE RBS_Types_Tuple; VALUE RBS_Types_Union; +VALUE RBS_Types_UntypedFunction; VALUE RBS_Types_Variable; -VALUE RBS_Types; -VALUE RBS_MethodType; +VALUE RBS_AST_Members_AttrAccessor; VALUE RBS_ParsingError; @@ -83,31 +87,29 @@ void rbs__init_constants(void) { IMPORT_CONSTANT(RBS_ParsingError, RBS, "ParsingError"); IMPORT_CONSTANT(RBS_AST, RBS, "AST"); - IMPORT_CONSTANT(RBS_AST_Comment, RBS_AST, "Comment"); - IMPORT_CONSTANT(RBS_AST_Annotation, RBS_AST, "Annotation"); - IMPORT_CONSTANT(RBS_AST_TypeParam, RBS_AST, "TypeParam"); - IMPORT_CONSTANT(RBS_AST_Declarations, RBS_AST, "Declarations"); + IMPORT_CONSTANT(RBS_AST_Directives, RBS_AST, "Directives"); + IMPORT_CONSTANT(RBS_AST_Members, RBS_AST, "Members"); + IMPORT_CONSTANT(RBS_Types, RBS, "Types"); + IMPORT_CONSTANT(RBS_Types_Bases, RBS_Types, "Bases"); - IMPORT_CONSTANT(RBS_AST_Declarations_TypeAlias, RBS_AST_Declarations, "TypeAlias"); + + IMPORT_CONSTANT(RBS_AST_Annotation, RBS_AST, "Annotation"); + IMPORT_CONSTANT(RBS_AST_Comment, RBS_AST, "Comment"); + IMPORT_CONSTANT(RBS_AST_Declarations_Class, RBS_AST_Declarations, "Class"); + IMPORT_CONSTANT(RBS_AST_Declarations_Class_Super, RBS_AST_Declarations_Class, "Super"); + IMPORT_CONSTANT(RBS_AST_Declarations_ClassAlias, RBS_AST_Declarations, "ClassAlias"); IMPORT_CONSTANT(RBS_AST_Declarations_Constant, RBS_AST_Declarations, "Constant"); IMPORT_CONSTANT(RBS_AST_Declarations_Global, RBS_AST_Declarations, "Global"); IMPORT_CONSTANT(RBS_AST_Declarations_Interface, RBS_AST_Declarations, "Interface"); IMPORT_CONSTANT(RBS_AST_Declarations_Module, RBS_AST_Declarations, "Module"); IMPORT_CONSTANT(RBS_AST_Declarations_Module_Self, RBS_AST_Declarations_Module, "Self"); - IMPORT_CONSTANT(RBS_AST_Declarations_Class, RBS_AST_Declarations, "Class"); - IMPORT_CONSTANT(RBS_AST_Declarations_Class_Super, RBS_AST_Declarations_Class, "Super"); - IMPORT_CONSTANT(RBS_AST_Declarations_ClassAlias, RBS_AST_Declarations, "ClassAlias"); IMPORT_CONSTANT(RBS_AST_Declarations_ModuleAlias, RBS_AST_Declarations, "ModuleAlias"); - - IMPORT_CONSTANT(RBS_AST_Directives, RBS_AST, "Directives"); + IMPORT_CONSTANT(RBS_AST_Declarations_TypeAlias, RBS_AST_Declarations, "TypeAlias"); IMPORT_CONSTANT(RBS_AST_Directives_Use, RBS_AST_Directives, "Use"); IMPORT_CONSTANT(RBS_AST_Directives_Use_SingleClause, RBS_AST_Directives_Use, "SingleClause"); IMPORT_CONSTANT(RBS_AST_Directives_Use_WildcardClause, RBS_AST_Directives_Use, "WildcardClause"); - - IMPORT_CONSTANT(RBS_AST_Members, RBS_AST, "Members"); IMPORT_CONSTANT(RBS_AST_Members_Alias, RBS_AST_Members, "Alias"); - IMPORT_CONSTANT(RBS_AST_Members_AttrAccessor, RBS_AST_Members, "AttrAccessor"); IMPORT_CONSTANT(RBS_AST_Members_AttrReader, RBS_AST_Members, "AttrReader"); IMPORT_CONSTANT(RBS_AST_Members_AttrWriter, RBS_AST_Members, "AttrWriter"); IMPORT_CONSTANT(RBS_AST_Members_ClassInstanceVariable, RBS_AST_Members, "ClassInstanceVariable"); @@ -120,12 +122,11 @@ void rbs__init_constants(void) { IMPORT_CONSTANT(RBS_AST_Members_Prepend, RBS_AST_Members, "Prepend"); IMPORT_CONSTANT(RBS_AST_Members_Private, RBS_AST_Members, "Private"); IMPORT_CONSTANT(RBS_AST_Members_Public, RBS_AST_Members, "Public"); - + IMPORT_CONSTANT(RBS_AST_TypeParam, RBS_AST, "TypeParam"); + IMPORT_CONSTANT(RBS_MethodType, RBS, "MethodType"); IMPORT_CONSTANT(RBS_Namespace, RBS, "Namespace"); IMPORT_CONSTANT(RBS_TypeName, RBS, "TypeName"); - IMPORT_CONSTANT(RBS_Types, RBS, "Types"); IMPORT_CONSTANT(RBS_Types_Alias, RBS_Types, "Alias"); - IMPORT_CONSTANT(RBS_Types_Bases, RBS_Types, "Bases"); IMPORT_CONSTANT(RBS_Types_Bases_Any, RBS_Types_Bases, "Any"); IMPORT_CONSTANT(RBS_Types_Bases_Bool, RBS_Types_Bases, "Bool"); IMPORT_CONSTANT(RBS_Types_Bases_Bottom, RBS_Types_Bases, "Bottom"); @@ -139,7 +140,6 @@ void rbs__init_constants(void) { IMPORT_CONSTANT(RBS_Types_ClassInstance, RBS_Types, "ClassInstance"); IMPORT_CONSTANT(RBS_Types_ClassSingleton, RBS_Types, "ClassSingleton"); IMPORT_CONSTANT(RBS_Types_Function, RBS_Types, "Function"); - IMPORT_CONSTANT(RBS_Types_UntypedFunction, RBS_Types, "UntypedFunction"); IMPORT_CONSTANT(RBS_Types_Function_Param, RBS_Types_Function, "Param"); IMPORT_CONSTANT(RBS_Types_Interface, RBS_Types, "Interface"); IMPORT_CONSTANT(RBS_Types_Intersection, RBS_Types, "Intersection"); @@ -149,6 +149,7 @@ void rbs__init_constants(void) { IMPORT_CONSTANT(RBS_Types_Record, RBS_Types, "Record"); IMPORT_CONSTANT(RBS_Types_Tuple, RBS_Types, "Tuple"); IMPORT_CONSTANT(RBS_Types_Union, RBS_Types, "Union"); + IMPORT_CONSTANT(RBS_Types_UntypedFunction, RBS_Types, "UntypedFunction"); IMPORT_CONSTANT(RBS_Types_Variable, RBS_Types, "Variable"); - IMPORT_CONSTANT(RBS_MethodType, RBS, "MethodType"); + IMPORT_CONSTANT(RBS_AST_Members_AttrAccessor, RBS_AST_Members, "AttrAccessor"); } diff --git a/ext/rbs_extension/constants.h b/ext/rbs_extension/constants.h index 2d1ca63bf..ece29c97b 100644 --- a/ext/rbs_extension/constants.h +++ b/ext/rbs_extension/constants.h @@ -1,14 +1,26 @@ +/*----------------------------------------------------------------------------*/ +/* This file is generated by the templates/template.rb script and should not */ +/* be modified manually. */ +/* To change the template see */ +/* templates/ext/rbs_extension/constants.h.erb */ +/*----------------------------------------------------------------------------*/ + #ifndef RBS__CONSTANTS_H #define RBS__CONSTANTS_H extern VALUE RBS; extern VALUE RBS_AST; +extern VALUE RBS_AST_Declarations; +extern VALUE RBS_AST_Directives; +extern VALUE RBS_AST_Members; +extern VALUE RBS_Types; +extern VALUE RBS_Types_Bases; +extern VALUE RBS_ParsingError; + extern VALUE RBS_AST_Annotation; extern VALUE RBS_AST_Comment; extern VALUE RBS_AST_TypeParam; - -extern VALUE RBS_AST_Declarations; extern VALUE RBS_AST_Declarations_TypeAlias; extern VALUE RBS_AST_Declarations_Class_Super; extern VALUE RBS_AST_Declarations_Class; @@ -19,13 +31,9 @@ extern VALUE RBS_AST_Declarations_Module_Self; extern VALUE RBS_AST_Declarations_Module; extern VALUE RBS_AST_Declarations_ModuleAlias; extern VALUE RBS_AST_Declarations_ClassAlias; - -extern VALUE RBS_AST_Directives; extern VALUE RBS_AST_Directives_Use; extern VALUE RBS_AST_Directives_Use_SingleClause; extern VALUE RBS_AST_Directives_Use_WildcardClause; - -extern VALUE RBS_AST_Members; extern VALUE RBS_AST_Members_Alias; extern VALUE RBS_AST_Members_AttrAccessor; extern VALUE RBS_AST_Members_AttrReader; @@ -40,16 +48,10 @@ extern VALUE RBS_AST_Members_MethodDefinition_Overload; extern VALUE RBS_AST_Members_Prepend; extern VALUE RBS_AST_Members_Private; extern VALUE RBS_AST_Members_Public; - extern VALUE RBS_MethodType; extern VALUE RBS_Namespace; - -extern VALUE RBS_ParsingError; extern VALUE RBS_TypeName; - -extern VALUE RBS_Types; extern VALUE RBS_Types_Alias; -extern VALUE RBS_Types_Bases; extern VALUE RBS_Types_Bases_Any; extern VALUE RBS_Types_Bases_Bool; extern VALUE RBS_Types_Bases_Bottom; diff --git a/ext/rbs_extension/parser.c b/ext/rbs_extension/parser.c index d99f29ade..ad081e120 100644 --- a/ext/rbs_extension/parser.c +++ b/ext/rbs_extension/parser.c @@ -963,25 +963,25 @@ static VALUE parse_simple(parserstate *state) { return type; } case kBOOL: - return rbs_base_type(RBS_Types_Bases_Bool, rbs_location_current_token(state)); + return rbs_bases_bool(rbs_location_current_token(state)); case kBOT: - return rbs_base_type(RBS_Types_Bases_Bottom, rbs_location_current_token(state)); + return rbs_bases_bottom(rbs_location_current_token(state)); case kCLASS: - return rbs_base_type(RBS_Types_Bases_Class, rbs_location_current_token(state)); + return rbs_bases_class(rbs_location_current_token(state)); case kINSTANCE: - return rbs_base_type(RBS_Types_Bases_Instance, rbs_location_current_token(state)); + return rbs_bases_instance(rbs_location_current_token(state)); case kNIL: - return rbs_base_type(RBS_Types_Bases_Nil, rbs_location_current_token(state)); + return rbs_bases_nil(rbs_location_current_token(state)); case kSELF: - return rbs_base_type(RBS_Types_Bases_Self, rbs_location_current_token(state)); + return rbs_bases_self(rbs_location_current_token(state)); case kTOP: - return rbs_base_type(RBS_Types_Bases_Top, rbs_location_current_token(state)); + return rbs_bases_top(rbs_location_current_token(state)); case kVOID: - return rbs_base_type(RBS_Types_Bases_Void, rbs_location_current_token(state)); + return rbs_bases_void(rbs_location_current_token(state)); case kUNTYPED: - return rbs_base_type(RBS_Types_Bases_Any, rbs_location_current_token(state)); + return rbs_bases_any(rbs_location_current_token(state)); case k__TODO__: { - VALUE type = rbs_base_type(RBS_Types_Bases_Any, rbs_location_current_token(state)); + VALUE type = rbs_bases_any(rbs_location_current_token(state)); rb_funcall(type, rb_intern("todo!"), 0); return type; } @@ -1219,7 +1219,12 @@ VALUE parse_type_params(parserstate *state, range *rg, bool module_type_params) rbs_loc_add_optional_child(loc, rb_intern("upper_bound"), upper_bound_range); rbs_loc_add_optional_child(loc, rb_intern("default"), default_type_range); - VALUE param = rbs_ast_type_param(name, variance, unchecked, upper_bound, default_type, location); + VALUE param = rbs_ast_type_param(name, variance, upper_bound, default_type, location); + + if (unchecked) { + rb_funcall(param, rb_intern("unchecked!"), 0); + } + melt_array(¶ms); rb_ary_push(params, param); @@ -1780,25 +1785,23 @@ VALUE parse_mixin_member(parserstate *state, bool from_interface, position comme range keyword_range; range args_range = NULL_RANGE; bool reset_typevar_scope; + enum TokenType type; member_range.start = state->current_token.range.start; comment_pos = nonnull_pos_or(comment_pos, member_range.start); + type = state->current_token.type; keyword_range = state->current_token.range; - VALUE klass = Qnil; - switch (state->current_token.type) + switch (type) { case kINCLUDE: - klass = RBS_AST_Members_Include; reset_typevar_scope = false; break; case kEXTEND: - klass = RBS_AST_Members_Extend; reset_typevar_scope = true; break; case kPREPEND: - klass = RBS_AST_Members_Prepend; reset_typevar_scope = false; break; default: @@ -1836,14 +1839,18 @@ VALUE parse_mixin_member(parserstate *state, bool from_interface, position comme rbs_loc_add_required_child(loc, rb_intern("keyword"), keyword_range); rbs_loc_add_optional_child(loc, rb_intern("args"), args_range); - return rbs_ast_members_mixin( - klass, - name, - args, - annotations, - location, - get_comment(state, comment_pos.line) - ); + VALUE comment = get_comment(state, comment_pos.line); + switch (type) + { + case kINCLUDE: + return rbs_ast_members_include(name, args, annotations, location, comment); + case kEXTEND: + return rbs_ast_members_extend(name, args, annotations, location, comment); + case kPREPEND: + return rbs_ast_members_prepend(name, args, annotations, location, comment); + default: + rbs_abort(); + } } /** @@ -1921,6 +1928,7 @@ VALUE parse_variable_member(parserstate *state, position comment_pos, VALUE anno range member_range; range name_range, colon_range; range kind_range = NULL_RANGE; + rbs_loc *loc; if (rb_array_len(annotations) > 0) { raise_syntax_error( @@ -1934,7 +1942,6 @@ VALUE parse_variable_member(parserstate *state, position comment_pos, VALUE anno comment_pos = nonnull_pos_or(comment_pos, member_range.start); VALUE comment = get_comment(state, comment_pos.line); - VALUE klass; VALUE location; VALUE name; VALUE type; @@ -1942,8 +1949,6 @@ VALUE parse_variable_member(parserstate *state, position comment_pos, VALUE anno switch (state->current_token.type) { case tAIDENT: - klass = RBS_AST_Members_InstanceVariable; - name_range = state->current_token.range; name = ID2SYM(INTERN_TOKEN(state, state->current_token)); @@ -1953,11 +1958,16 @@ VALUE parse_variable_member(parserstate *state, position comment_pos, VALUE anno type = parse_type(state); member_range.end = state->current_token.range.end; - break; + location = rbs_new_location(state->buffer, member_range); + loc = rbs_check_location(location); + rbs_loc_alloc_children(loc, 3); + rbs_loc_add_required_child(loc, rb_intern("name"), name_range); + rbs_loc_add_required_child(loc, rb_intern("colon"), colon_range); + rbs_loc_add_optional_child(loc, rb_intern("kind"), kind_range); - case tA2IDENT: - klass = RBS_AST_Members_ClassVariable; + return rbs_ast_members_instance_variable(name, type, location, comment); + case tA2IDENT: name_range = state->current_token.range; name = ID2SYM(INTERN_TOKEN(state, state->current_token)); @@ -1969,11 +1979,16 @@ VALUE parse_variable_member(parserstate *state, position comment_pos, VALUE anno parser_pop_typevar_table(state); member_range.end = state->current_token.range.end; - break; + location = rbs_new_location(state->buffer, member_range); + loc = rbs_check_location(location); + rbs_loc_alloc_children(loc, 3); + rbs_loc_add_required_child(loc, rb_intern("name"), name_range); + rbs_loc_add_required_child(loc, rb_intern("colon"), colon_range); + rbs_loc_add_optional_child(loc, rb_intern("kind"), kind_range); - case kSELF: - klass = RBS_AST_Members_ClassInstanceVariable; + return rbs_ast_members_class_variable(name, type, location, comment); + case kSELF: kind_range.start = state->current_token.range.start; kind_range.end = state->next_token.range.end; @@ -1991,20 +2006,18 @@ VALUE parse_variable_member(parserstate *state, position comment_pos, VALUE anno parser_pop_typevar_table(state); member_range.end = state->current_token.range.end; - break; + location = rbs_new_location(state->buffer, member_range); + loc = rbs_check_location(location); + rbs_loc_alloc_children(loc, 3); + rbs_loc_add_required_child(loc, rb_intern("name"), name_range); + rbs_loc_add_required_child(loc, rb_intern("colon"), colon_range); + rbs_loc_add_optional_child(loc, rb_intern("kind"), kind_range); + + return rbs_ast_members_class_instance_variable(name, type, location, comment); default: rbs_abort(); } - - location = rbs_new_location(state->buffer, member_range); - rbs_loc *loc = rbs_check_location(location); - rbs_loc_alloc_children(loc, 3); - rbs_loc_add_required_child(loc, rb_intern("name"), name_range); - rbs_loc_add_required_child(loc, rb_intern("colon"), colon_range); - rbs_loc_add_optional_child(loc, rb_intern("kind"), kind_range); - - return rbs_ast_members_variable(klass, name, type, location, comment); } /* @@ -2020,24 +2033,17 @@ VALUE parse_visibility_member(parserstate *state, VALUE annotations) { ); } - VALUE klass; + VALUE location = rbs_new_location(state->buffer, state->current_token.range); switch (state->current_token.type) { case kPUBLIC: - klass = RBS_AST_Members_Public; - break; + return rbs_ast_members_public(location); case kPRIVATE: - klass = RBS_AST_Members_Private; - break; + return rbs_ast_members_private(location); default: rbs_abort(); } - - return rbs_ast_members_visibility( - klass, - rbs_new_location(state->buffer, state->current_token.range) - ); } /* @@ -2060,7 +2066,6 @@ VALUE parse_attribute_member(parserstate *state, position comment_pos, VALUE ann range kind_range = NULL_RANGE, ivar_range = NULL_RANGE, ivar_name_range = NULL_RANGE, visibility_range = NULL_RANGE; InstanceSingletonKind is_kind; - VALUE klass; VALUE kind; VALUE attr_name; VALUE ivar_name; @@ -2069,6 +2074,7 @@ VALUE parse_attribute_member(parserstate *state, position comment_pos, VALUE ann VALUE location; VALUE visibility; rbs_loc *loc; + enum TokenType attr_type; member_range.start = state->current_token.range.start; comment_pos = nonnull_pos_or(comment_pos, member_range.start); @@ -2092,21 +2098,8 @@ VALUE parse_attribute_member(parserstate *state, position comment_pos, VALUE ann break; } + attr_type = state->current_token.type; keyword_range = state->current_token.range; - switch (state->current_token.type) - { - case kATTRREADER: - klass = RBS_AST_Members_AttrReader; - break; - case kATTRWRITER: - klass = RBS_AST_Members_AttrWriter; - break; - case kATTRACCESSOR: - klass = RBS_AST_Members_AttrAccessor; - break; - default: - rbs_abort(); - } is_kind = parse_instance_singleton_kind(state, false, &kind_range); if (is_kind == INSTANCE_KIND) { @@ -2153,17 +2146,17 @@ VALUE parse_attribute_member(parserstate *state, position comment_pos, VALUE ann rbs_loc_add_optional_child(loc, rb_intern("ivar_name"), ivar_name_range); rbs_loc_add_optional_child(loc, rb_intern("visibility"), visibility_range); - return rbs_ast_members_attribute( - klass, - attr_name, - type, - ivar_name, - kind, - annotations, - location, - comment, - visibility - ); + switch (attr_type) + { + case kATTRREADER: + return rbs_ast_members_attr_reader(attr_name, type, ivar_name, kind, annotations, location, comment, visibility); + case kATTRWRITER: + return rbs_ast_members_attr_writer(attr_name, type, ivar_name, kind, annotations, location, comment, visibility); + case kATTRACCESSOR: + return rbs_ast_members_attr_accessor(attr_name, type, ivar_name, kind, annotations, location, comment, visibility); + default: + rbs_abort(); + } } /* diff --git a/ext/rbs_extension/ruby_objs.c b/ext/rbs_extension/ruby_objs.c index 1391a1514..b8696c453 100644 --- a/ext/rbs_extension/ruby_objs.c +++ b/ext/rbs_extension/ruby_objs.c @@ -1,3 +1,10 @@ +/*----------------------------------------------------------------------------*/ +/* This file is generated by the templates/template.rb script and should not */ +/* be modified manually. */ +/* To change the template see */ +/* templates/ext/rbs_extension/ruby_objs.c.erb */ +/*----------------------------------------------------------------------------*/ + #include "rbs_extension.h" #ifdef RB_PASS_KEYWORDS @@ -10,16 +17,6 @@ rb_class_new_instance(argc, argv, receiver) #endif -VALUE rbs_base_type(VALUE klass, VALUE location) { - VALUE args = rb_hash_new(); - rb_hash_aset(args, ID2SYM(rb_intern("location")), location); - - return CLASS_NEW_INSTANCE( - klass, - 1, - &args - ); -} VALUE rbs_namespace(VALUE path, VALUE absolute) { VALUE args = rb_hash_new(); @@ -181,33 +178,6 @@ VALUE rbs_untyped_function(VALUE return_type) { ); } -VALUE rbs_function( - VALUE required_positional_params, - VALUE optional_positional_params, - VALUE rest_positional_param, - VALUE trailing_positional_params, - VALUE required_keyword_params, - VALUE optional_keyword_params, - VALUE rest_keyword_param, - VALUE return_type -) { - VALUE args = rb_hash_new(); - rb_hash_aset(args, ID2SYM(rb_intern("required_positionals")), required_positional_params); - rb_hash_aset(args, ID2SYM(rb_intern("optional_positionals")), optional_positional_params); - rb_hash_aset(args, ID2SYM(rb_intern("rest_positionals")), rest_positional_param); - rb_hash_aset(args, ID2SYM(rb_intern("trailing_positionals")), trailing_positional_params); - rb_hash_aset(args, ID2SYM(rb_intern("required_keywords")), required_keyword_params); - rb_hash_aset(args, ID2SYM(rb_intern("optional_keywords")), optional_keyword_params); - rb_hash_aset(args, ID2SYM(rb_intern("rest_keywords")), rest_keyword_param); - rb_hash_aset(args, ID2SYM(rb_intern("return_type")), return_type); - - return CLASS_NEW_INSTANCE( - RBS_Types_Function, - 1, - &args - ); -} - VALUE rbs_proc(VALUE function, VALUE block, VALUE location, VALUE self_type) { VALUE args = rb_hash_new(); rb_hash_aset(args, ID2SYM(rb_intern("type")), function); @@ -222,21 +192,10 @@ VALUE rbs_proc(VALUE function, VALUE block, VALUE location, VALUE self_type) { ); } -VALUE rbs_void(VALUE location) { - VALUE args = rb_hash_new(); - rb_hash_aset(args, ID2SYM(rb_intern("location")), location); - - return CLASS_NEW_INSTANCE( - RBS_Types_Bases_Void, - 1, - &args - ); -} - VALUE rbs_literal(VALUE literal, VALUE location) { VALUE args = rb_hash_new(); - rb_hash_aset(args, ID2SYM(rb_intern("location")), location); rb_hash_aset(args, ID2SYM(rb_intern("literal")), literal); + rb_hash_aset(args, ID2SYM(rb_intern("location")), location); return CLASS_NEW_INSTANCE( RBS_Types_Literal, @@ -245,10 +204,10 @@ VALUE rbs_literal(VALUE literal, VALUE location) { ); } -VALUE rbs_record(VALUE fields,VALUE location) { +VALUE rbs_record(VALUE fields, VALUE location) { VALUE args = rb_hash_new(); - rb_hash_aset(args, ID2SYM(rb_intern("location")), location); rb_hash_aset(args, ID2SYM(rb_intern("all_fields")), fields); + rb_hash_aset(args, ID2SYM(rb_intern("location")), location); return CLASS_NEW_INSTANCE( RBS_Types_Record, @@ -259,8 +218,8 @@ VALUE rbs_record(VALUE fields,VALUE location) { VALUE rbs_variable(VALUE name, VALUE location) { VALUE args = rb_hash_new(); - rb_hash_aset(args, ID2SYM(rb_intern("location")), location); rb_hash_aset(args, ID2SYM(rb_intern("name")), name); + rb_hash_aset(args, ID2SYM(rb_intern("location")), location); return CLASS_NEW_INSTANCE( RBS_Types_Variable, @@ -307,7 +266,7 @@ VALUE rbs_ast_annotation(VALUE string, VALUE location) { ); } -VALUE rbs_ast_type_param(VALUE name, VALUE variance, bool unchecked, VALUE upper_bound, VALUE default_type, VALUE location) { +VALUE rbs_ast_type_param(VALUE name, VALUE variance, VALUE upper_bound, VALUE default_type, VALUE location) { VALUE args = rb_hash_new(); rb_hash_aset(args, ID2SYM(rb_intern("name")), name); rb_hash_aset(args, ID2SYM(rb_intern("variance")), variance); @@ -315,13 +274,11 @@ VALUE rbs_ast_type_param(VALUE name, VALUE variance, bool unchecked, VALUE upper rb_hash_aset(args, ID2SYM(rb_intern("default_type")), default_type); rb_hash_aset(args, ID2SYM(rb_intern("location")), location); - VALUE type_param = CLASS_NEW_INSTANCE(RBS_AST_TypeParam, 1, &args); - - if (unchecked) { - rb_funcall(type_param, rb_intern("unchecked!"), 0); - } - - return type_param; + return CLASS_NEW_INSTANCE( + RBS_AST_TypeParam, + 1, + &args + ); } VALUE rbs_ast_decl_constant(VALUE name, VALUE type, VALUE location, VALUE comment) { @@ -472,131 +429,366 @@ VALUE rbs_ast_members_method_definition(VALUE name, VALUE kind, VALUE overloads, ); } -VALUE rbs_ast_members_variable(VALUE klass, VALUE name, VALUE type, VALUE location, VALUE comment) { +VALUE rbs_ast_members_alias(VALUE new_name, VALUE old_name, VALUE kind, VALUE annotations, VALUE location, VALUE comment) { VALUE args = rb_hash_new(); - rb_hash_aset(args, ID2SYM(rb_intern("name")), name); - rb_hash_aset(args, ID2SYM(rb_intern("type")), type); + rb_hash_aset(args, ID2SYM(rb_intern("new_name")), new_name); + rb_hash_aset(args, ID2SYM(rb_intern("old_name")), old_name); + rb_hash_aset(args, ID2SYM(rb_intern("kind")), kind); + rb_hash_aset(args, ID2SYM(rb_intern("annotations")), annotations); rb_hash_aset(args, ID2SYM(rb_intern("location")), location); rb_hash_aset(args, ID2SYM(rb_intern("comment")), comment); return CLASS_NEW_INSTANCE( - klass, + RBS_AST_Members_Alias, 1, &args ); } -VALUE rbs_ast_members_mixin(VALUE klass, VALUE name, VALUE module_args, VALUE annotations, VALUE location, VALUE comment) { - VALUE args = rb_hash_new(); - rb_hash_aset(args, ID2SYM(rb_intern("name")), name); - rb_hash_aset(args, ID2SYM(rb_intern("args")), module_args); - rb_hash_aset(args, ID2SYM(rb_intern("annotations")), annotations); - rb_hash_aset(args, ID2SYM(rb_intern("location")), location); - rb_hash_aset(args, ID2SYM(rb_intern("comment")), comment); +VALUE rbs_ast_decl_class_super(VALUE name, VALUE args, VALUE location) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("name")), name); + rb_hash_aset(kwargs, ID2SYM(rb_intern("args")), args); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); return CLASS_NEW_INSTANCE( - klass, + RBS_AST_Declarations_Class_Super, 1, - &args + &kwargs ); } -VALUE rbs_ast_members_attribute(VALUE klass, VALUE name, VALUE type, VALUE ivar_name, VALUE kind, VALUE annotations, VALUE location, VALUE comment, VALUE visibility) { - VALUE args = rb_hash_new(); - rb_hash_aset(args, ID2SYM(rb_intern("name")), name); - rb_hash_aset(args, ID2SYM(rb_intern("type")), type); - rb_hash_aset(args, ID2SYM(rb_intern("ivar_name")), ivar_name); - rb_hash_aset(args, ID2SYM(rb_intern("kind")), kind); - rb_hash_aset(args, ID2SYM(rb_intern("annotations")), annotations); - rb_hash_aset(args, ID2SYM(rb_intern("location")), location); - rb_hash_aset(args, ID2SYM(rb_intern("comment")), comment); - rb_hash_aset(args, ID2SYM(rb_intern("visibility")), visibility); +VALUE rbs_ast_decl_class(VALUE name, VALUE type_params, VALUE super_class, VALUE members, VALUE annotations, VALUE location, VALUE comment) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("name")), name); + rb_hash_aset(kwargs, ID2SYM(rb_intern("type_params")), type_params); + rb_hash_aset(kwargs, ID2SYM(rb_intern("super_class")), super_class); + rb_hash_aset(kwargs, ID2SYM(rb_intern("members")), members); + rb_hash_aset(kwargs, ID2SYM(rb_intern("annotations")), annotations); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + rb_hash_aset(kwargs, ID2SYM(rb_intern("comment")), comment); return CLASS_NEW_INSTANCE( - klass, + RBS_AST_Declarations_Class, 1, - &args + &kwargs ); } -VALUE rbs_ast_members_visibility(VALUE klass, VALUE location) { - VALUE args = rb_hash_new(); - rb_hash_aset(args, ID2SYM(rb_intern("location")), location); +VALUE rbs_ast_directives_use(VALUE clauses, VALUE location) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("clauses")), clauses); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); return CLASS_NEW_INSTANCE( - klass, + RBS_AST_Directives_Use, 1, - &args + &kwargs ); } -VALUE rbs_ast_members_alias(VALUE new_name, VALUE old_name, VALUE kind, VALUE annotations, VALUE location, VALUE comment) { - VALUE args = rb_hash_new(); - rb_hash_aset(args, ID2SYM(rb_intern("new_name")), new_name); - rb_hash_aset(args, ID2SYM(rb_intern("old_name")), old_name); - rb_hash_aset(args, ID2SYM(rb_intern("kind")), kind); - rb_hash_aset(args, ID2SYM(rb_intern("annotations")), annotations); - rb_hash_aset(args, ID2SYM(rb_intern("location")), location); - rb_hash_aset(args, ID2SYM(rb_intern("comment")), comment); +VALUE rbs_ast_directives_use_single_clause(VALUE type_name, VALUE new_name, VALUE location) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("type_name")), type_name); + rb_hash_aset(kwargs, ID2SYM(rb_intern("new_name")), new_name); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); return CLASS_NEW_INSTANCE( - RBS_AST_Members_Alias, + RBS_AST_Directives_Use_SingleClause, 1, - &args + &kwargs ); } -VALUE rbs_ast_decl_class_super(VALUE name, VALUE args, VALUE location) { +VALUE rbs_ast_directives_use_wildcard_clause(VALUE namespace, VALUE location) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("namespace")), namespace); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + + return CLASS_NEW_INSTANCE( + RBS_AST_Directives_Use_WildcardClause, + 1, + &kwargs + ); +} + +VALUE rbs_function(VALUE required_positional_params, VALUE optional_positional_params, VALUE rest_positional_params, VALUE trailing_positional_params, VALUE required_keywords, VALUE optional_keywords, VALUE rest_keywords, VALUE return_type) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("required_positionals")), required_positional_params); + rb_hash_aset(kwargs, ID2SYM(rb_intern("optional_positionals")), optional_positional_params); + rb_hash_aset(kwargs, ID2SYM(rb_intern("rest_positionals")), rest_positional_params); + rb_hash_aset(kwargs, ID2SYM(rb_intern("trailing_positionals")), trailing_positional_params); + rb_hash_aset(kwargs, ID2SYM(rb_intern("required_keywords")), required_keywords); + rb_hash_aset(kwargs, ID2SYM(rb_intern("optional_keywords")), optional_keywords); + rb_hash_aset(kwargs, ID2SYM(rb_intern("rest_keywords")), rest_keywords); + rb_hash_aset(kwargs, ID2SYM(rb_intern("return_type")), return_type); + + return CLASS_NEW_INSTANCE( + RBS_Types_Function, + 1, + &kwargs + ); +} + +VALUE rbs_bases_void(VALUE location) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + + return CLASS_NEW_INSTANCE( + RBS_Types_Bases_Void, + 1, + &kwargs + ); +} + +VALUE rbs_bases_top(VALUE location) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + + return CLASS_NEW_INSTANCE( + RBS_Types_Bases_Top, + 1, + &kwargs + ); +} + +VALUE rbs_ast_members_class_instance_variable(VALUE name, VALUE type, VALUE location, VALUE comment) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("name")), name); + rb_hash_aset(kwargs, ID2SYM(rb_intern("type")), type); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + rb_hash_aset(kwargs, ID2SYM(rb_intern("comment")), comment); + + return CLASS_NEW_INSTANCE( + RBS_AST_Members_ClassInstanceVariable, + 1, + &kwargs + ); +} + +VALUE rbs_ast_members_class_variable(VALUE name, VALUE type, VALUE location, VALUE comment) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("name")), name); + rb_hash_aset(kwargs, ID2SYM(rb_intern("type")), type); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + rb_hash_aset(kwargs, ID2SYM(rb_intern("comment")), comment); + + return CLASS_NEW_INSTANCE( + RBS_AST_Members_ClassVariable, + 1, + &kwargs + ); +} + +VALUE rbs_ast_members_extend(VALUE name, VALUE args, VALUE annotations, VALUE location, VALUE comment) { VALUE kwargs = rb_hash_new(); rb_hash_aset(kwargs, ID2SYM(rb_intern("name")), name); rb_hash_aset(kwargs, ID2SYM(rb_intern("args")), args); + rb_hash_aset(kwargs, ID2SYM(rb_intern("annotations")), annotations); rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + rb_hash_aset(kwargs, ID2SYM(rb_intern("comment")), comment); return CLASS_NEW_INSTANCE( - RBS_AST_Declarations_Class_Super, + RBS_AST_Members_Extend, 1, &kwargs ); } -VALUE rbs_ast_decl_class(VALUE name, VALUE type_params, VALUE super_class, VALUE members, VALUE annotations, VALUE location, VALUE comment) { +VALUE rbs_ast_members_include(VALUE name, VALUE args, VALUE annotations, VALUE location, VALUE comment) { VALUE kwargs = rb_hash_new(); rb_hash_aset(kwargs, ID2SYM(rb_intern("name")), name); - rb_hash_aset(kwargs, ID2SYM(rb_intern("type_params")), type_params); - rb_hash_aset(kwargs, ID2SYM(rb_intern("super_class")), super_class); - rb_hash_aset(kwargs, ID2SYM(rb_intern("members")), members); + rb_hash_aset(kwargs, ID2SYM(rb_intern("args")), args); rb_hash_aset(kwargs, ID2SYM(rb_intern("annotations")), annotations); rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); rb_hash_aset(kwargs, ID2SYM(rb_intern("comment")), comment); return CLASS_NEW_INSTANCE( - RBS_AST_Declarations_Class, + RBS_AST_Members_Include, 1, &kwargs ); } -VALUE rbs_ast_directives_use(VALUE clauses, VALUE location) { +VALUE rbs_ast_members_instance_variable(VALUE name, VALUE type, VALUE location, VALUE comment) { VALUE kwargs = rb_hash_new(); - rb_hash_aset(kwargs, ID2SYM(rb_intern("clauses")), clauses); + rb_hash_aset(kwargs, ID2SYM(rb_intern("name")), name); + rb_hash_aset(kwargs, ID2SYM(rb_intern("type")), type); rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + rb_hash_aset(kwargs, ID2SYM(rb_intern("comment")), comment); - return CLASS_NEW_INSTANCE(RBS_AST_Directives_Use, 1, &kwargs); + return CLASS_NEW_INSTANCE( + RBS_AST_Members_InstanceVariable, + 1, + &kwargs + ); } -VALUE rbs_ast_directives_use_single_clause(VALUE type_name, VALUE new_name, VALUE location) { +VALUE rbs_ast_members_prepend(VALUE name, VALUE args, VALUE annotations, VALUE location, VALUE comment) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("name")), name); + rb_hash_aset(kwargs, ID2SYM(rb_intern("args")), args); + rb_hash_aset(kwargs, ID2SYM(rb_intern("annotations")), annotations); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + rb_hash_aset(kwargs, ID2SYM(rb_intern("comment")), comment); + + return CLASS_NEW_INSTANCE( + RBS_AST_Members_Prepend, + 1, + &kwargs + ); +} + +VALUE rbs_ast_members_private(VALUE location) { VALUE kwargs = rb_hash_new(); - rb_hash_aset(kwargs, ID2SYM(rb_intern("type_name")), type_name); - rb_hash_aset(kwargs, ID2SYM(rb_intern("new_name")), new_name); rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); - return CLASS_NEW_INSTANCE(RBS_AST_Directives_Use_SingleClause, 1, &kwargs); + return CLASS_NEW_INSTANCE( + RBS_AST_Members_Private, + 1, + &kwargs + ); } -VALUE rbs_ast_directives_use_wildcard_clause(VALUE namespace, VALUE location) { +VALUE rbs_ast_members_public(VALUE location) { VALUE kwargs = rb_hash_new(); - rb_hash_aset(kwargs, ID2SYM(rb_intern("namespace")), namespace); rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); - return CLASS_NEW_INSTANCE(RBS_AST_Directives_Use_WildcardClause, 1, &kwargs); + return CLASS_NEW_INSTANCE( + RBS_AST_Members_Public, + 1, + &kwargs + ); } + +VALUE rbs_ast_members_attr_writer(VALUE name, VALUE type, VALUE ivar_name, VALUE kind, VALUE annotations, VALUE location, VALUE comment, VALUE visibility) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("name")), name); + rb_hash_aset(kwargs, ID2SYM(rb_intern("type")), type); + rb_hash_aset(kwargs, ID2SYM(rb_intern("ivar_name")), ivar_name); + rb_hash_aset(kwargs, ID2SYM(rb_intern("kind")), kind); + rb_hash_aset(kwargs, ID2SYM(rb_intern("annotations")), annotations); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + rb_hash_aset(kwargs, ID2SYM(rb_intern("comment")), comment); + rb_hash_aset(kwargs, ID2SYM(rb_intern("visibility")), visibility); + + return CLASS_NEW_INSTANCE( + RBS_AST_Members_AttrWriter, + 1, + &kwargs + ); +} + +VALUE rbs_ast_members_attr_reader(VALUE name, VALUE type, VALUE ivar_name, VALUE kind, VALUE annotations, VALUE location, VALUE comment, VALUE visibility) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("name")), name); + rb_hash_aset(kwargs, ID2SYM(rb_intern("type")), type); + rb_hash_aset(kwargs, ID2SYM(rb_intern("ivar_name")), ivar_name); + rb_hash_aset(kwargs, ID2SYM(rb_intern("kind")), kind); + rb_hash_aset(kwargs, ID2SYM(rb_intern("annotations")), annotations); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + rb_hash_aset(kwargs, ID2SYM(rb_intern("comment")), comment); + rb_hash_aset(kwargs, ID2SYM(rb_intern("visibility")), visibility); + + return CLASS_NEW_INSTANCE( + RBS_AST_Members_AttrReader, + 1, + &kwargs + ); +} + +VALUE rbs_ast_members_attr_accessor(VALUE name, VALUE type, VALUE ivar_name, VALUE kind, VALUE annotations, VALUE location, VALUE comment, VALUE visibility) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("name")), name); + rb_hash_aset(kwargs, ID2SYM(rb_intern("type")), type); + rb_hash_aset(kwargs, ID2SYM(rb_intern("ivar_name")), ivar_name); + rb_hash_aset(kwargs, ID2SYM(rb_intern("kind")), kind); + rb_hash_aset(kwargs, ID2SYM(rb_intern("annotations")), annotations); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + rb_hash_aset(kwargs, ID2SYM(rb_intern("comment")), comment); + rb_hash_aset(kwargs, ID2SYM(rb_intern("visibility")), visibility); + + return CLASS_NEW_INSTANCE( + RBS_AST_Members_AttrAccessor, + 1, + &kwargs + ); +} + +VALUE rbs_bases_any(VALUE location) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + + return CLASS_NEW_INSTANCE( + RBS_Types_Bases_Any, + 1, + &kwargs + ); +} + +VALUE rbs_bases_bool(VALUE location) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + + return CLASS_NEW_INSTANCE( + RBS_Types_Bases_Bool, + 1, + &kwargs + ); +} + +VALUE rbs_bases_bottom(VALUE location) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + + return CLASS_NEW_INSTANCE( + RBS_Types_Bases_Bottom, + 1, + &kwargs + ); +} + +VALUE rbs_bases_class(VALUE location) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + + return CLASS_NEW_INSTANCE( + RBS_Types_Bases_Class, + 1, + &kwargs + ); +} + +VALUE rbs_bases_instance(VALUE location) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + + return CLASS_NEW_INSTANCE( + RBS_Types_Bases_Instance, + 1, + &kwargs + ); +} + +VALUE rbs_bases_nil(VALUE location) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + + return CLASS_NEW_INSTANCE( + RBS_Types_Bases_Nil, + 1, + &kwargs + ); +} + +VALUE rbs_bases_self(VALUE location) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("location")), location); + + return CLASS_NEW_INSTANCE( + RBS_Types_Bases_Self, + 1, + &kwargs + ); +} + diff --git a/ext/rbs_extension/ruby_objs.h b/ext/rbs_extension/ruby_objs.h index 427b39e46..0f6c06af4 100644 --- a/ext/rbs_extension/ruby_objs.h +++ b/ext/rbs_extension/ruby_objs.h @@ -1,3 +1,10 @@ +/*----------------------------------------------------------------------------*/ +/* This file is generated by the templates/template.rb script and should not */ +/* be modified manually. */ +/* To change the template see */ +/* templates/ext/rbs_extension/ruby_objs.h.erb */ +/*----------------------------------------------------------------------------*/ + #ifndef RBS__RUBY_OBJS_H #define RBS__RUBY_OBJS_H @@ -6,7 +13,7 @@ VALUE rbs_alias(VALUE typename, VALUE args, VALUE location); VALUE rbs_ast_annotation(VALUE string, VALUE location); VALUE rbs_ast_comment(VALUE string, VALUE location); -VALUE rbs_ast_type_param(VALUE name, VALUE variance, bool unchecked, VALUE upper_bound, VALUE default_type, VALUE location); +VALUE rbs_ast_type_param(VALUE name, VALUE variance, VALUE upper_bound, VALUE default_type, VALUE location); VALUE rbs_ast_decl_type_alias(VALUE name, VALUE type_params, VALUE type, VALUE annotations, VALUE location, VALUE comment); VALUE rbs_ast_decl_class_super(VALUE name, VALUE args, VALUE location); VALUE rbs_ast_decl_class(VALUE name, VALUE type_params, VALUE super_class, VALUE members, VALUE annotations, VALUE location, VALUE comment); @@ -18,13 +25,8 @@ VALUE rbs_ast_decl_module(VALUE name, VALUE type_params, VALUE self_types, VALUE VALUE rbs_ast_decl_module_alias(VALUE new_name, VALUE old_name, VALUE location, VALUE comment); VALUE rbs_ast_decl_class_alias(VALUE new_name, VALUE old_name, VALUE location, VALUE comment); VALUE rbs_ast_members_alias(VALUE new_name, VALUE old_name, VALUE kind, VALUE annotations, VALUE location, VALUE comment); -VALUE rbs_ast_members_attribute(VALUE klass, VALUE name, VALUE type, VALUE ivar_name, VALUE kind, VALUE annotations, VALUE location, VALUE comment, VALUE visibility); VALUE rbs_ast_members_method_definition(VALUE name, VALUE kind, VALUE overloads, VALUE annotations, VALUE location, VALUE comment, VALUE overloading, VALUE visibility); VALUE rbs_ast_members_method_definition_overload(VALUE annotations, VALUE method_type); -VALUE rbs_ast_members_mixin(VALUE klass, VALUE name, VALUE args, VALUE annotations, VALUE location, VALUE comment); -VALUE rbs_ast_members_variable(VALUE klass, VALUE name, VALUE type, VALUE location, VALUE comment); -VALUE rbs_ast_members_visibility(VALUE klass, VALUE location); -VALUE rbs_base_type(VALUE klass, VALUE location); VALUE rbs_block(VALUE type, VALUE required, VALUE self_type); VALUE rbs_class_instance(VALUE typename, VALUE type_args, VALUE location); VALUE rbs_class_singleton(VALUE typename, VALUE location); @@ -43,9 +45,28 @@ VALUE rbs_tuple(VALUE types, VALUE location); VALUE rbs_type_name(VALUE namespace, VALUE name); VALUE rbs_union(VALUE types, VALUE location); VALUE rbs_variable(VALUE name, VALUE location); - VALUE rbs_ast_directives_use(VALUE clauses, VALUE location); VALUE rbs_ast_directives_use_single_clause(VALUE type_name, VALUE new_name, VALUE location); VALUE rbs_ast_directives_use_wildcard_clause(VALUE namespace, VALUE location); +VALUE rbs_ast_members_attr_accessor(VALUE name, VALUE type, VALUE ivar_name, VALUE kind, VALUE annotations, VALUE location, VALUE comment, VALUE visibility); +VALUE rbs_ast_members_attr_reader(VALUE name, VALUE type, VALUE ivar_name, VALUE kind, VALUE annotations, VALUE location, VALUE comment, VALUE visibility); +VALUE rbs_ast_members_attr_writer(VALUE name, VALUE type, VALUE ivar_name, VALUE kind, VALUE annotations, VALUE location, VALUE comment, VALUE visibility); +VALUE rbs_ast_members_class_instance_variable(VALUE name, VALUE type, VALUE location, VALUE comment); +VALUE rbs_ast_members_class_variable(VALUE name, VALUE type, VALUE location, VALUE comment); +VALUE rbs_ast_members_extend(VALUE name, VALUE args, VALUE annotations, VALUE location, VALUE comment); +VALUE rbs_bases_void(VALUE location); +VALUE rbs_bases_top(VALUE location); +VALUE rbs_bases_self(VALUE location); +VALUE rbs_bases_nil(VALUE location); +VALUE rbs_bases_instance(VALUE location); +VALUE rbs_bases_class(VALUE location); +VALUE rbs_bases_bottom(VALUE location); +VALUE rbs_bases_bool(VALUE location); +VALUE rbs_bases_any(VALUE location); +VALUE rbs_ast_members_include(VALUE name, VALUE args, VALUE annotations, VALUE location, VALUE comment); +VALUE rbs_ast_members_instance_variable(VALUE name, VALUE type, VALUE location, VALUE comment); +VALUE rbs_ast_members_prepend(VALUE name, VALUE args, VALUE annotations, VALUE location, VALUE comment); +VALUE rbs_ast_members_private(VALUE location); +VALUE rbs_ast_members_public(VALUE location); #endif diff --git a/templates/ext/rbs_extension/constants.c.erb b/templates/ext/rbs_extension/constants.c.erb new file mode 100644 index 000000000..08035a0ee --- /dev/null +++ b/templates/ext/rbs_extension/constants.c.erb @@ -0,0 +1,179 @@ +#include "rbs_extension.h" + +VALUE RBS_Parser; + +VALUE RBS; +VALUE RBS_AST; +VALUE RBS_AST_Declarations; +VALUE RBS_AST_Directives; +VALUE RBS_AST_Members; +VALUE RBS_Parser; +VALUE RBS_Types; +VALUE RBS_Types_Bases; + +<%- +# This list contains the symbols in the order that they used to be defined in the C code. +# We'll temporarily rearrange our auto-generated code to match this order, to minimize the diff. +# It's temporary and will be removed in a follow-up PR. +ordered_constant_names = [ + "RBS", + "RBS_AST", + "RBS_AST_Declarations", + "RBS_AST_Directives", + "RBS_AST_Members", + "RBS_Parser", + "RBS_Types", + "RBS_Types_Bases", + "RBS_AST_Annotation", + "RBS_AST_Comment", + "RBS_AST_Declarations_Class", + "RBS_AST_Declarations_Class_Super", + "RBS_AST_Declarations_ClassAlias", + "RBS_AST_Declarations_Constant", + "RBS_AST_Declarations_Global", + "RBS_AST_Declarations_Interface", + "RBS_AST_Declarations_Module", + "RBS_AST_Declarations_Module_Self", + "RBS_AST_Declarations_ModuleAlias", + "RBS_AST_Declarations_TypeAlias", + "RBS_AST_Directives_Use", + "RBS_AST_Directives_Use_SingleClause", + "RBS_AST_Directives_Use_WildcardClause", + "RBS_AST_Members_Alias", + "RBS_AST_Members_AttrReader", + "RBS_AST_Members_AttrWriter", + "RBS_AST_Members_Attribute", + "RBS_AST_Members_ClassInstanceVariable", + "RBS_AST_Members_ClassVariable", + "RBS_AST_Members_Extend", + "RBS_AST_Members_Include", + "RBS_AST_Members_InstanceVariable", + "RBS_AST_Members_MethodDefinition", + "RBS_AST_Members_MethodDefinition_Overload", + "RBS_AST_Members_Prepend", + "RBS_AST_Members_Private", + "RBS_AST_Members_Public", + "RBS_AST_TypeParam", + "RBS_MethodType", + "RBS_Namespace", + "RBS_TypeName", + "RBS_Types_Alias", + "RBS_Types_Bases_Any", + "RBS_Types_Bases_Bool", + "RBS_Types_Bases_Bottom", + "RBS_Types_Bases_Class", + "RBS_Types_Bases_Instance", + "RBS_Types_Bases_Nil", + "RBS_Types_Bases_Self", + "RBS_Types_Bases_Top", + "RBS_Types_Bases_Void", + "RBS_Types_Block", + "RBS_Types_ClassInstance", + "RBS_Types_ClassSingleton", + "RBS_Types_Function", + "RBS_Types_Function_Param", + "RBS_Types_Interface", + "RBS_Types_Intersection", + "RBS_Types_Literal", + "RBS_Types_Optional", + "RBS_Types_Proc", + "RBS_Types_Record", + "RBS_Types_Tuple", + "RBS_Types_Union", + "RBS_Types_UntypedFunction", + "RBS_Types_Variable", + "RBS_ParsingError", +] -%> + +<%- nodes.sort_by { |node| ordered_constant_names.index(node.c_constant_name) || 999 }.each do |node| -%> +VALUE <%= node.c_constant_name %>; +<%- end -%> + +VALUE RBS_ParsingError; + +#define IMPORT_CONSTANT(var, parent, name) { var = rb_const_get(parent, rb_intern(name)); rb_gc_register_mark_object(var); } + +void rbs__init_constants(void) { + IMPORT_CONSTANT(RBS, rb_cObject, "RBS"); + IMPORT_CONSTANT(RBS_ParsingError, RBS, "ParsingError"); + + IMPORT_CONSTANT(RBS_AST, RBS, "AST"); + IMPORT_CONSTANT(RBS_AST_Declarations, RBS_AST, "Declarations"); + IMPORT_CONSTANT(RBS_AST_Directives, RBS_AST, "Directives"); + IMPORT_CONSTANT(RBS_AST_Members, RBS_AST, "Members"); + IMPORT_CONSTANT(RBS_Types, RBS, "Types"); + IMPORT_CONSTANT(RBS_Types_Bases, RBS_Types, "Bases"); + + <%- ordered_constant_names = [ + "RBS", + "RBS_ParsingError", + "RBS_AST", + "RBS_AST_Declarations", + "RBS_AST_Directives", + "RBS_AST_Members", + "RBS_Types", + "RBS_Types_Bases", + "RBS_AST_Annotation", + "RBS_AST_Comment", + "RBS_AST_Declarations_Class", + "RBS_AST_Declarations_Class_Super", + "RBS_AST_Declarations_ClassAlias", + "RBS_AST_Declarations_Constant", + "RBS_AST_Declarations_Global", + "RBS_AST_Declarations_Interface", + "RBS_AST_Declarations_Module", + "RBS_AST_Declarations_Module_Self", + "RBS_AST_Declarations_ModuleAlias", + "RBS_AST_Declarations_TypeAlias", + "RBS_AST_Directives_Use", + "RBS_AST_Directives_Use_SingleClause", + "RBS_AST_Directives_Use_WildcardClause", + "RBS_AST_Members_Alias", + "RBS_AST_Members_AttrReader", + "RBS_AST_Members_AttrWriter", + "RBS_AST_Members_Attribute", + "RBS_AST_Members_ClassInstanceVariable", + "RBS_AST_Members_ClassVariable", + "RBS_AST_Members_Extend", + "RBS_AST_Members_Include", + "RBS_AST_Members_InstanceVariable", + "RBS_AST_Members_MethodDefinition", + "RBS_AST_Members_MethodDefinition_Overload", + "RBS_AST_Members_Prepend", + "RBS_AST_Members_Private", + "RBS_AST_Members_Public", + "RBS_AST_TypeParam", + "RBS_MethodType", + "RBS_Namespace", + "RBS_TypeName", + "RBS_Types_Alias", + "RBS_Types_Bases_Any", + "RBS_Types_Bases_Bool", + "RBS_Types_Bases_Bottom", + "RBS_Types_Bases_Class", + "RBS_Types_Bases_Instance", + "RBS_Types_Bases_Nil", + "RBS_Types_Bases_Self", + "RBS_Types_Bases_Top", + "RBS_Types_Bases_Void", + "RBS_Types_Block", + "RBS_Types_ClassInstance", + "RBS_Types_ClassSingleton", + "RBS_Types_Function", + "RBS_Types_Function_Param", + "RBS_Types_Interface", + "RBS_Types_Intersection", + "RBS_Types_Literal", + "RBS_Types_Optional", + "RBS_Types_Proc", + "RBS_Types_Record", + "RBS_Types_Tuple", + "RBS_Types_Union", + "RBS_Types_UntypedFunction", + "RBS_Types_Variable", + ] -%> + + <%- nodes.sort_by { |node| ordered_constant_names.index(node.c_constant_name) || 999 }.each do |node| -%> + IMPORT_CONSTANT(<%= node.c_constant_name %>, <%= node.c_parent_constant_name %>, "<%= node.ruby_class_name %>"); + <%- end -%> +} diff --git a/templates/ext/rbs_extension/constants.h.erb b/templates/ext/rbs_extension/constants.h.erb new file mode 100644 index 000000000..0feed50e3 --- /dev/null +++ b/templates/ext/rbs_extension/constants.h.erb @@ -0,0 +1,92 @@ +#ifndef RBS__CONSTANTS_H +#define RBS__CONSTANTS_H + +extern VALUE RBS; + +extern VALUE RBS_AST; +extern VALUE RBS_AST_Declarations; +extern VALUE RBS_AST_Directives; +extern VALUE RBS_AST_Members; +extern VALUE RBS_Types; +extern VALUE RBS_Types_Bases; +extern VALUE RBS_ParsingError; + +<%- +# This list contains the symbols in the order that they used to be defined in the C code. +# We'll temporarily rearrange our auto-generated code to match this order, to minimize the diff. +# It's temporary and will be removed in a follow-up PR. +ordered_constant_names = [ + "RBS", + "RBS_AST", + "RBS_AST_Annotation", + "RBS_AST_Comment", + "RBS_AST_TypeParam", + "RBS_AST_Declarations", + "RBS_AST_Declarations_TypeAlias", + "RBS_AST_Declarations_Class_Super", + "RBS_AST_Declarations_Class", + "RBS_AST_Declarations_Constant", + "RBS_AST_Declarations_Global", + "RBS_AST_Declarations_Interface", + "RBS_AST_Declarations_Module_Self", + "RBS_AST_Declarations_Module", + "RBS_AST_Declarations_ModuleAlias", + "RBS_AST_Declarations_ClassAlias", + "RBS_AST_Directives", + "RBS_AST_Directives_Use", + "RBS_AST_Directives_Use_SingleClause", + "RBS_AST_Directives_Use_WildcardClause", + "RBS_AST_Members", + "RBS_AST_Members_Alias", + "RBS_AST_Members_AttrAccessor", + "RBS_AST_Members_AttrReader", + "RBS_AST_Members_AttrWriter", + "RBS_AST_Members_ClassInstanceVariable", + "RBS_AST_Members_ClassVariable", + "RBS_AST_Members_Extend", + "RBS_AST_Members_Include", + "RBS_AST_Members_InstanceVariable", + "RBS_AST_Members_MethodDefinition", + "RBS_AST_Members_MethodDefinition_Overload", + "RBS_AST_Members_Prepend", + "RBS_AST_Members_Private", + "RBS_AST_Members_Public", + "RBS_MethodType", + "RBS_Namespace", + "RBS_ParsingError", + "RBS_TypeName", + "RBS_Types", + "RBS_Types_Alias", + "RBS_Types_Bases", + "RBS_Types_Bases_Any", + "RBS_Types_Bases_Bool", + "RBS_Types_Bases_Bottom", + "RBS_Types_Bases_Class", + "RBS_Types_Bases_Instance", + "RBS_Types_Bases_Nil", + "RBS_Types_Bases_Self", + "RBS_Types_Bases_Top", + "RBS_Types_Bases_Void", + "RBS_Types_Block", + "RBS_Types_ClassInstance", + "RBS_Types_ClassSingleton", + "RBS_Types_Function_Param", + "RBS_Types_Function", + "RBS_Types_UntypedFunction", + "RBS_Types_Interface", + "RBS_Types_Intersection", + "RBS_Types_Literal", + "RBS_Types_Optional", + "RBS_Types_Proc", + "RBS_Types_Record", + "RBS_Types_Tuple", + "RBS_Types_Union", + "RBS_Types_Variable", +] -%> +<%- nodes.sort_by { |node| ordered_constant_names.index(node.c_constant_name) || 999 }.each do |node| -%> +extern VALUE <%= node.c_constant_name %>; +<%- end -%> + +void rbs__init_constants(); + +#endif diff --git a/templates/ext/rbs_extension/ruby_objs.c.erb b/templates/ext/rbs_extension/ruby_objs.c.erb new file mode 100644 index 000000000..f8e482523 --- /dev/null +++ b/templates/ext/rbs_extension/ruby_objs.c.erb @@ -0,0 +1,117 @@ +#include "rbs_extension.h" + +#ifdef RB_PASS_KEYWORDS + // Ruby 2.7 or later + #define CLASS_NEW_INSTANCE(klass, argc, argv)\ + rb_class_new_instance_kw(argc, argv, klass, RB_PASS_KEYWORDS) +#else + // Ruby 2.6 + #define CLASS_NEW_INSTANCE(receiver, argc, argv)\ + rb_class_new_instance(argc, argv, receiver) +#endif + +<%- +# This list contains the symbols in the order that they used to be defined in the C code. +# We'll temporarily rearrange our auto-generated code to match this order, to minimize the diff. +# It's temporary and will be removed in a follow-up PR. +ordered_function_names = [ + "rbs_base_type", + "rbs_namespace", + "rbs_type_name", + "rbs_class_instance", + "rbs_class_singleton", + "rbs_alias", + "rbs_interface", + "rbs_union", + "rbs_intersection", + "rbs_tuple", + "rbs_optional", + "rbs_block", + "rbs_function_param", + "rbs_untyped_function", + "rbs_proc", + "rbs_void", + "rbs_literal", + "rbs_record", + "rbs_variable", + "rbs_method_type", + "rbs_ast_comment", + "rbs_ast_annotation", + "rbs_ast_type_param", + "rbs_ast_decl_constant", + "rbs_ast_decl_global", + "rbs_ast_decl_type_alias", + "rbs_ast_decl_interface", + "rbs_ast_decl_module_self", + "rbs_ast_decl_module", + "rbs_ast_decl_class_alias", + "rbs_ast_decl_module_alias", + "rbs_ast_members_method_definition_overload", + "rbs_ast_members_method_definition", + "rbs_ast_members_variable", + "rbs_ast_members_mixin", + "rbs_ast_members_attribute", + "rbs_ast_members_visibility", + "rbs_ast_members_alias", + "rbs_ast_decl_class_super", + "rbs_ast_decl_class", + "rbs_ast_directives_use", + "rbs_ast_directives_use_single_clause", + "rbs_ast_directives_use_wildcard_clause", +] + +# This list contains the functions that use "args" for their local variable name, instead of "kwargs". +# We'll use this in our auto-generated code to the existing naming, to minimize the diff. +# It's temporary and will be removed in a follow-up PR. +uses_args_hash = [ + "rbs_base_type", + "rbs_namespace", + "rbs_type_name", + "rbs_class_instance", + "rbs_class_singleton", + "rbs_interface", + "rbs_union", + "rbs_intersection", + "rbs_optional", + "rbs_untyped_function", + "rbs_ast_type_param", + "rbs_ast_decl_constant", + "rbs_ast_decl_global", + "rbs_ast_decl_type_alias", + "rbs_ast_decl_interface", + # "rbs_ast_decl_module_self", + "rbs_ast_decl_module", + "rbs_ast_decl_class_alias", + "rbs_ast_decl_module_alias", + "rbs_ast_members_method_definition_overload", + "rbs_ast_members_method_definition", + "rbs_ast_members_alias", + "rbs_tuple", + "rbs_block", + "rbs_function_param", + "rbs_proc", + "rbs_literal", + "rbs_record", + "rbs_variable", + "rbs_method_type", + "rbs_ast_comment", + "rbs_ast_annotation" +]-%> + +<%- nodes.sort_by { |node| ordered_function_names.index(node.c_function_name) || 999 }.each do |node| -%> +VALUE <%= node.c_function_name %>(<%= node.fields.map { |field| "#{field.c_type} #{field.c_name}" }.join(", ") %>) { + <%- hash_var = uses_args_hash.include?(node.c_function_name) ? "args" : "kwargs" -%> + <%- hash_var = "kw_args" if node.c_function_name == "rbs_ast_decl_module_self" -%> + VALUE <%= hash_var %> = rb_hash_new(); + <%- node.fields.each do |field| -%> + rb_hash_aset(<%= hash_var %>, ID2SYM(rb_intern("<%= field.name %>")), <%= field.c_name %>); + <%- end -%> + + return CLASS_NEW_INSTANCE( + <%= node.c_constant_name %>, + 1, + &<%= hash_var %> + ); +} + +<%- end -%> diff --git a/templates/ext/rbs_extension/ruby_objs.h.erb b/templates/ext/rbs_extension/ruby_objs.h.erb new file mode 100644 index 000000000..1bb62aeab --- /dev/null +++ b/templates/ext/rbs_extension/ruby_objs.h.erb @@ -0,0 +1,60 @@ +#ifndef RBS__RUBY_OBJS_H +#define RBS__RUBY_OBJS_H + +#include "ruby.h" + +<%- +# This list contains the symbols in the order that they used to be defined in the C code. +# We'll temporarily rearrange our auto-generated code to match this order, to minimize the diff. +# It's temporary and will be removed in a follow-up PR. +ordered_function_names = [ + "rbs_alias", + "rbs_ast_annotation", + "rbs_ast_comment", + "rbs_ast_type_param", + "rbs_ast_decl_type_alias", + "rbs_ast_decl_class_super", + "rbs_ast_decl_class", + "rbs_ast_decl_constant", + "rbs_ast_decl_global", + "rbs_ast_decl_interface", + "rbs_ast_decl_module_self", + "rbs_ast_decl_module", + "rbs_ast_decl_module_alias", + "rbs_ast_decl_class_alias", + "rbs_ast_members_alias", + "rbs_ast_members_attribute", + "rbs_ast_members_method_definition", + "rbs_ast_members_method_definition_overload", + "rbs_ast_members_mixin", + "rbs_ast_members_variable", + "rbs_ast_members_visibility", + "rbs_base_type", + "rbs_block", + "rbs_class_instance", + "rbs_class_singleton", + "rbs_function_param", + "rbs_function", + "rbs_untyped_function", + "rbs_interface", + "rbs_intersection", + "rbs_literal", + "rbs_method_type", + "rbs_namespace", + "rbs_optional", + "rbs_proc", + "rbs_record", + "rbs_tuple", + "rbs_type_name", + "rbs_union", + "rbs_variable", + "rbs_ast_directives_use", + "rbs_ast_directives_use_single_clause", + "rbs_ast_directives_use_wildcard_clause", +] + +nodes.sort_by { |node| ordered_function_names.index(node.c_function_name) || 999 }.each do |node| -%> +VALUE <%= node.c_function_name %>(<%= node.fields.map { |field| "#{field.c_type} #{field.c_name}" }.join(", ") %>); +<%- end -%> + +#endif diff --git a/templates/template.rb b/templates/template.rb new file mode 100644 index 000000000..cbd67d73e --- /dev/null +++ b/templates/template.rb @@ -0,0 +1,130 @@ +# frozen_string_literal: true + +require "erb" +require "fileutils" +require "yaml" + +require "active_support" +require "active_support/core_ext/string/inflections" + +module RBS + class Template + class Field + attr_reader :name + attr_reader :c_name + attr_reader :c_type + + def initialize(yaml) + @name = yaml["name"] + @c_name = yaml["c_name"] || @name + @c_type = "VALUE" + end + end + + class Type + # The fully-qualified name of the auto-generated Ruby class for this type, + # e.g. `RBS::AST::Declarations::TypeAlias` + attr_reader :ruby_full_name #: String + + # The name of the name of the auto-generated Ruby class for this type, + # e.g. `TypeAlias` + attr_reader :ruby_class_name #: String + + # The name of the auto-generated C struct for this type, + # e.g. `rbs_ast_declarations_typealias_t` + attr_reader :c_type_name #: String + + # The name of the pre-existing C function which constructs new Ruby objects of this type. + # e.g. `rbs_ast_declarations_typealias_new` + attr_reader :c_function_name #: String + + # The name of the C constant which stores the Ruby VALUE pointing to the generated class. + # e.g. `RBS_AST_Declarations_TypeAlias` + attr_reader :c_constant_name #: String + + # The name of the C constant in which the `c_constant_name` is nested. + # e.g. `RBS_AST_Declarations` + attr_reader :c_parent_constant_name #: String + + attr_reader :fields #: Array[RBS::Template::Field] + + def initialize(yaml) + @ruby_full_name = yaml["name"] + @ruby_class_name = @ruby_full_name.demodulize + @c_function_name = if @ruby_full_name =~ /^RBS::Types/ + name = @ruby_full_name.gsub("::", "_").underscore + name.gsub("_types_", "_") + else + name = @ruby_full_name.gsub("::", "_").underscore + name.gsub("_declarations_", "_decl_") + end + @c_constant_name = @ruby_full_name.gsub("::", "_") + @c_parent_constant_name = @ruby_full_name.split("::")[0..-2].join("::").gsub("::", "_") + + @fields = yaml.fetch("fields", []).map { |field| Field.new(field) }.freeze + end + end + + class << self + def render(out_file) + filepath = "templates/#{out_file}.erb" + template = File.expand_path("../#{filepath}", __dir__) + + erb = read_template(template) + extension = File.extname(filepath.gsub(".erb", "")) + + heading = <<~HEADING + /*----------------------------------------------------------------------------*/ + /* This file is generated by the templates/template.rb script and should not */ + /* be modified manually. */ + /* To change the template see */ + /* #{filepath + " " * (74 - filepath.size) } */ + /*----------------------------------------------------------------------------*/ + HEADING + + write_to = File.expand_path("../#{out_file}", __dir__) + contents = heading + "\n" + erb.result_with_hash(locals) + + if (extension == ".c" || extension == ".h") && !contents.ascii_only? + # Enforce that we only have ASCII characters here. This is necessary + # for non-UTF-8 locales that only allow ASCII characters in C source + # files. + contents.each_line.with_index(1) do |line, line_number| + raise "Non-ASCII character on line #{line_number} of #{write_to}" unless line.ascii_only? + end + end + + FileUtils.mkdir_p(File.dirname(write_to)) + File.write(write_to, contents) + end + + private + + def read_template(filepath) + template = File.read(filepath, encoding: Encoding::UTF_8) + erb = erb(template) + erb.filename = filepath + erb + end + + def erb(template) + ERB.new(template, trim_mode: "-") + end + + def locals + config = YAML.load_file(File.expand_path("../config.yml", __dir__)) + { + nodes: config.fetch("nodes").map { |node| Type.new(node) }.sort_by(&:ruby_full_name), + } + end + end + end +end + +unless ARGV.size == 1 + $stderr.puts "Usage: ruby template.rb " + exit 1 +end + +out_file = ARGV.first +RBS::Template.render(out_file)