-
Notifications
You must be signed in to change notification settings - Fork 1
Add MethodDefinition#signatures to Ruby API #697
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| #include "signature.h" | ||
| #include "definition.h" | ||
| #include "handle.h" | ||
| #include "location.h" | ||
|
|
||
| VALUE cSignature; | ||
| VALUE cParameter; | ||
| VALUE cPositionalParameter; | ||
| VALUE cOptionalPositionalParameter; | ||
| VALUE cRestPositionalParameter; | ||
| VALUE cKeywordParameter; | ||
| VALUE cOptionalKeywordParameter; | ||
| VALUE cRestKeywordParameter; | ||
| VALUE cBlockParameter; | ||
| VALUE cForwardParameter; | ||
|
|
||
| static VALUE parameter_class_for_kind(ParameterKind kind) { | ||
| switch (kind) { | ||
| case ParameterKind_RequiredPositional: return cPositionalParameter; | ||
| case ParameterKind_OptionalPositional: return cOptionalPositionalParameter; | ||
| case ParameterKind_Rest: return cRestPositionalParameter; | ||
| case ParameterKind_RequiredKeyword: return cKeywordParameter; | ||
| case ParameterKind_OptionalKeyword: return cOptionalKeywordParameter; | ||
| case ParameterKind_RestKeyword: return cRestKeywordParameter; | ||
| case ParameterKind_Block: return cBlockParameter; | ||
| case ParameterKind_Forward: return cForwardParameter; | ||
| default: rb_raise(rb_eRuntimeError, "Unknown ParameterKind: %d", kind); | ||
| } | ||
| } | ||
|
|
||
| VALUE rdxi_signatures_to_ruby(SignatureArray *arr, VALUE graph_obj, VALUE default_method_def) { | ||
| if (arr == NULL || arr->len == 0) { | ||
| if (arr != NULL) { | ||
| rdx_definition_signatures_free(arr); | ||
| } | ||
| return rb_ary_new(); | ||
| } | ||
|
|
||
| VALUE signatures = rb_ary_new_capa((long)arr->len); | ||
|
|
||
| for (size_t i = 0; i < arr->len; i++) { | ||
| SignatureEntry sig_entry = arr->items[i]; | ||
|
|
||
| VALUE method_def; | ||
| if (default_method_def != Qnil) { | ||
| method_def = default_method_def; | ||
| } else { | ||
| VALUE def_argv[] = {graph_obj, ULL2NUM(sig_entry.definition_id)}; | ||
| method_def = rb_class_new_instance(2, def_argv, cMethodDefinition); | ||
| } | ||
|
|
||
| VALUE parameters = rb_ary_new_capa((long)sig_entry.parameters_len); | ||
| for (size_t j = 0; j < sig_entry.parameters_len; j++) { | ||
| ParameterEntry param_entry = sig_entry.parameters[j]; | ||
|
|
||
| VALUE param_class = parameter_class_for_kind(param_entry.kind); | ||
| VALUE name_sym = ID2SYM(rb_intern(param_entry.name)); | ||
| VALUE location = rdxi_build_location_value(param_entry.location); | ||
| VALUE param_argv[] = {name_sym, location}; | ||
| VALUE param = rb_class_new_instance(2, param_argv, param_class); | ||
|
|
||
| rb_ary_push(parameters, param); | ||
| } | ||
|
|
||
| VALUE sig_argv[] = {parameters, method_def}; | ||
| VALUE signature = rb_class_new_instance(2, sig_argv, cSignature); | ||
|
|
||
| rb_ary_push(signatures, signature); | ||
| } | ||
|
|
||
| rdx_definition_signatures_free(arr); | ||
| return signatures; | ||
| } | ||
|
|
||
| void rdxi_initialize_signature(VALUE mRubydex) { | ||
| cSignature = rb_define_class_under(mRubydex, "Signature", rb_cObject); | ||
|
|
||
| cParameter = rb_define_class_under(cSignature, "Parameter", rb_cObject); | ||
| cPositionalParameter = rb_define_class_under(cSignature, "PositionalParameter", cParameter); | ||
| cOptionalPositionalParameter = rb_define_class_under(cSignature, "OptionalPositionalParameter", cParameter); | ||
| cRestPositionalParameter = rb_define_class_under(cSignature, "RestPositionalParameter", cParameter); | ||
| cKeywordParameter = rb_define_class_under(cSignature, "KeywordParameter", cParameter); | ||
| cOptionalKeywordParameter = rb_define_class_under(cSignature, "OptionalKeywordParameter", cParameter); | ||
| cRestKeywordParameter = rb_define_class_under(cSignature, "RestKeywordParameter", cParameter); | ||
| cBlockParameter = rb_define_class_under(cSignature, "BlockParameter", cParameter); | ||
| cForwardParameter = rb_define_class_under(cSignature, "ForwardParameter", cParameter); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| #ifndef RUBYDEX_SIGNATURE_H | ||
| #define RUBYDEX_SIGNATURE_H | ||
|
|
||
| #include "ruby.h" | ||
| #include "rustbindings.h" | ||
|
|
||
| extern VALUE cSignature; | ||
| extern VALUE cParameter; | ||
| extern VALUE cPositionalParameter; | ||
| extern VALUE cOptionalPositionalParameter; | ||
| extern VALUE cRestPositionalParameter; | ||
| extern VALUE cKeywordParameter; | ||
| extern VALUE cOptionalKeywordParameter; | ||
| extern VALUE cRestKeywordParameter; | ||
| extern VALUE cBlockParameter; | ||
| extern VALUE cForwardParameter; | ||
|
|
||
| // Convert a SignatureArray into a Ruby array of Rubydex::Signature objects. | ||
| // If default_method_def is not Qnil, it is used as method_definition for all signatures. | ||
| // Otherwise, a new MethodDefinition handle is built from each SignatureEntry's definition_id. | ||
| // The SignatureArray is freed after conversion. | ||
| VALUE rdxi_signatures_to_ruby(SignatureArray *arr, VALUE graph_obj, VALUE default_method_def); | ||
|
|
||
| void rdxi_initialize_signature(VALUE mRubydex); | ||
|
|
||
| #endif // RUBYDEX_SIGNATURE_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| module Rubydex | ||
| class Signature | ||
| class Parameter | ||
| #: Symbol | ||
| attr_reader :name | ||
|
|
||
| #: Location | ||
| attr_reader :location | ||
|
|
||
| #: (Symbol, Location) -> void | ||
| def initialize(name, location) | ||
| @name = name | ||
| @location = location | ||
| end | ||
| end | ||
|
|
||
| #: Array[Parameter] | ||
| attr_reader :parameters | ||
|
|
||
| #: MethodDefinition | ||
| attr_reader :method_definition | ||
|
|
||
| #: (Array[Parameter], MethodDefinition) -> void | ||
| def initialize(parameters, method_definition) | ||
| @parameters = parameters | ||
| @method_definition = method_definition | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need this back link? Considering that consumers will interact with the API like this: declaration.definitions.first.signaturesI think we can remove this.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is for We can drop the backlink and add a new class or use tuple for
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's discuss in the team sync, but I think exposing signatures at the declaration level has the potential to be a bit confusing. Maybe we can handle the alias case in some other way. |
||
| end | ||
| end | ||
| end | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we define these in Ruby? It seems like we may not even need new C files. We could just put the
rdxi_signatures_to_rubyhelper indefinition.c.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also for
MethodDeclaration#signatures. That will be indeclaration.cand then therdxi_signatures_to_rubywill be used from two files.Another question is if
Rubydex::Signatureis a good place to define the class. DoesRubydex::MethodDefinition::Signaturemake more sense?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So far, we haven't really nested any of the classes in sub-modules. I think
Rubydex::Signatureis fine for now.