Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,8 @@ nodes:
- optional: args
- name: RBS::AST::Members::Private
rust_name: PrivateNode
- name: RBS::AST::Members::Protected
rust_name: ProtectedNode
- name: RBS::AST::Members::Public
rust_name: PublicNode
- name: RBS::AST::TypeParam
Expand Down Expand Up @@ -887,6 +889,7 @@ enums:
- unspecified
- public
- private
- protected
attribute_kind:
symbols:
- instance
Expand All @@ -906,6 +909,7 @@ enums:
- unspecified
- public
- private
- protected
type_param_variance:
symbols:
- invariant
Expand Down
9 changes: 9 additions & 0 deletions core/pathname.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,15 @@ class Pathname
SEPARATOR_PAT: Regexp

TO_PATH: Symbol

# <!-- rdoc-file=pathname.rb -->
# The internal string representation of the path.
#
# This is exposed as a protected attribute so that two `Pathname` instances
# can compare and combine their underlying paths without exposing the
# accessor to outside callers.
#
protected attr_reader path: String
end

%a{annotate:rdoc:skip}
Expand Down
9 changes: 7 additions & 2 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,11 @@ enums:
- unspecified
- public
- private
- protected
```

For example, the `attribute_visibility` enum is a data type for `visibility` attribute of `attr_reader`, `attr_writer`, and `attr_accessor` definitions.
The `visibility` attribute can be one of `unspecified`, `public`, and `private`.
The `visibility` attribute can be one of `unspecified`, `public`, `private`, and `protected`.

### Symbol enums

Expand All @@ -137,6 +138,7 @@ enums:
- unspecified
- public
- private
- protected
```

It defines an `enum` in C AST definition.
Expand All @@ -146,6 +148,7 @@ enum RBS_ATTRIBUTE_VISIBILITY_TAG {
RBS_ATTRIBUTE_VISIBILITY_TAG_UNSPECIFIED,
RBS_ATTRIBUTE_VISIBILITY_TAG_PUBLIC,
RBS_ATTRIBUTE_VISIBILITY_TAG_PRIVATE,
RBS_ATTRIBUTE_VISIBILITY_TAG_PROTECTED,
};
```

Expand All @@ -160,12 +163,14 @@ VALUE rbs_attribute_visibility_to_ruby(enum rbs_attribute_visibility value) {
return rb_id2sym(rb_intern("public"));
case RBS_ATTRIBUTE_VISIBILITY_PRIVATE:
return rb_id2sym(rb_intern("private"));
case RBS_ATTRIBUTE_VISIBILITY_PROTECTED:
return rb_id2sym(rb_intern("protected"));
default:
rb_fatal("unknown enum rbs_attribute_visibility value: %d", value);
}
}
```

`RBS_ATTRIBUTE_VISIBILITY_PUBLIC` and `RBS_ATTRIBUTE_VISIBILITY_PRIVATE` are translated to Ruby symbols `:public` and `:private` respectively.
`RBS_ATTRIBUTE_VISIBILITY_PUBLIC`, `RBS_ATTRIBUTE_VISIBILITY_PRIVATE`, and `RBS_ATTRIBUTE_VISIBILITY_PROTECTED` are translated to Ruby symbols `:public`, `:private`, and `:protected` respectively.

Note that the first `RBS_ATTRIBUTE_VISIBILITY_UNSPECIFIED` is translated to `nil` in Ruby. This is specified by the `optional: true` attribute in YAML. When `optional: true` is set, the first enum value is translated to `nil`.
16 changes: 13 additions & 3 deletions docs/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ _attribute-member_ ::= _visibility_ _attribute-type_ _method-name_ `:` _type_
| _visibility_ _attribute-type_ `self.` _method-name_ `:` _type_ # Singleton attribute
| _visibility_ _attribute-type_ `self.` _method-name_ `(` _ivar-name_ `) :` _type_ # Singleton attribute with variable name specification
| _visibility_ _attribute-type_ `self.` _method-name_ `() :` _type_ # Singleton attribute without variable
_visibility_ ::= `public` | `private`
_visibility_ ::= `public` | `private` | `protected`

_attribute-type_ ::= `attr_reader` | `attr_writer` | `attr_accessor`

Expand Down Expand Up @@ -502,11 +502,13 @@ def +: (Float | Integer) -> (Float | Integer)
| (Numeric) -> Numeric
```

Adding `public` and `private` modifier changes the visibility of the method.
Adding `public`, `private`, and `protected` modifiers changes the visibility of the method.

```rbs
private def puts: (*untyped) -> void # Defines private instance method

protected def size: () -> Integer # Defines protected instance method

public def self.puts: (*untyped) -> void # Defines public singleton method

public def self?.puts: (*untyped) -> void # 🚨🚨🚨 Error: `?.` has own visibility semantics (== `module_function`) 🚨🚨🚨
Expand Down Expand Up @@ -537,11 +539,13 @@ attr_accessor people (): Array[Person]
# def people=: (Array[Person]) -> Array[Person]
```

Attribute definitions can have the `public` and `private` modifiers like method definitions:
Attribute definitions can have the `public`, `private`, and `protected` modifiers like method definitions:

```rbs
private attr_accessor id: Integer

protected attr_reader path: String

private attr_reader self.name: String
```

Expand Down Expand Up @@ -593,6 +597,12 @@ private
def bar: () -> void # private instance method

attr_reader email: String # private instance attribute

protected

def baz: () -> void # protected instance method

attr_reader path: String # protected instance attribute
```

The visibility _modifiers_ overwrite the default visibility per member bases.
Expand Down
17 changes: 17 additions & 0 deletions ext/rbs_extension/ast_translation.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ VALUE rbs_attribute_visibility_to_ruby(enum rbs_attribute_visibility value) {
return rb_id2sym(rb_intern("public"));
case RBS_ATTRIBUTE_VISIBILITY_PRIVATE:
return rb_id2sym(rb_intern("private"));
case RBS_ATTRIBUTE_VISIBILITY_PROTECTED:
return rb_id2sym(rb_intern("protected"));
default:
rb_fatal("unknown enum rbs_attribute_visibility value: %d", value);
}
Expand Down Expand Up @@ -149,6 +151,8 @@ VALUE rbs_method_definition_visibility_to_ruby(enum rbs_method_definition_visibi
return rb_id2sym(rb_intern("public"));
case RBS_METHOD_DEFINITION_VISIBILITY_PRIVATE:
return rb_id2sym(rb_intern("private"));
case RBS_METHOD_DEFINITION_VISIBILITY_PROTECTED:
return rb_id2sym(rb_intern("protected"));
default:
rb_fatal("unknown enum rbs_method_definition_visibility value: %d", value);
}
Expand Down Expand Up @@ -996,6 +1000,19 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan
rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
return CLASS_NEW_INSTANCE(RBS_AST_Members_Private, 1, &h);
}
case RBS_AST_MEMBERS_PROTECTED: {
rbs_ast_members_protected_t *node = (rbs_ast_members_protected_t *) instance;

// Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);

// Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
// Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
VALUE h = ctx.reusable_kwargs_hash;
rb_hash_clear(h);
rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
return CLASS_NEW_INSTANCE(RBS_AST_Members_Protected, 1, &h);
}
case RBS_AST_MEMBERS_PUBLIC: {
rbs_ast_members_public_t *node = (rbs_ast_members_public_t *) instance;

Expand Down
2 changes: 2 additions & 0 deletions ext/rbs_extension/class_constants.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ VALUE RBS_AST_Members_MethodDefinition;
VALUE RBS_AST_Members_MethodDefinition_Overload;
VALUE RBS_AST_Members_Prepend;
VALUE RBS_AST_Members_Private;
VALUE RBS_AST_Members_Protected;
VALUE RBS_AST_Members_Public;
VALUE RBS_AST_Ruby_Annotations_BlockParamTypeAnnotation;
VALUE RBS_AST_Ruby_Annotations_ClassAliasAnnotation;
Expand Down Expand Up @@ -140,6 +141,7 @@ void rbs__init_constants(void) {
IMPORT_CONSTANT(RBS_AST_Members_MethodDefinition_Overload, RBS_AST_Members_MethodDefinition, "Overload");
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_Protected, RBS_AST_Members, "Protected");
IMPORT_CONSTANT(RBS_AST_Members_Public, RBS_AST_Members, "Public");
IMPORT_CONSTANT(RBS_AST_Ruby_Annotations_BlockParamTypeAnnotation, RBS_AST_Ruby_Annotations, "BlockParamTypeAnnotation");
IMPORT_CONSTANT(RBS_AST_Ruby_Annotations_ClassAliasAnnotation, RBS_AST_Ruby_Annotations, "ClassAliasAnnotation");
Expand Down
1 change: 1 addition & 0 deletions ext/rbs_extension/class_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ extern VALUE RBS_AST_Members_MethodDefinition;
extern VALUE RBS_AST_Members_MethodDefinition_Overload;
extern VALUE RBS_AST_Members_Prepend;
extern VALUE RBS_AST_Members_Private;
extern VALUE RBS_AST_Members_Protected;
extern VALUE RBS_AST_Members_Public;
extern VALUE RBS_AST_Ruby_Annotations_BlockParamTypeAnnotation;
extern VALUE RBS_AST_Ruby_Annotations_ClassAliasAnnotation;
Expand Down
103 changes: 56 additions & 47 deletions include/rbs/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum rbs_attribute_visibility {
RBS_ATTRIBUTE_VISIBILITY_UNSPECIFIED, /* unspecified (nil) */
RBS_ATTRIBUTE_VISIBILITY_PUBLIC, /* public (:public) */
RBS_ATTRIBUTE_VISIBILITY_PRIVATE, /* private (:private) */
RBS_ATTRIBUTE_VISIBILITY_PROTECTED, /* protected (:protected) */
};

enum rbs_attribute_kind {
Expand All @@ -40,6 +41,7 @@ enum rbs_method_definition_visibility {
RBS_METHOD_DEFINITION_VISIBILITY_UNSPECIFIED, /* unspecified (nil) */
RBS_METHOD_DEFINITION_VISIBILITY_PUBLIC, /* public (:public) */
RBS_METHOD_DEFINITION_VISIBILITY_PRIVATE, /* private (:private) */
RBS_METHOD_DEFINITION_VISIBILITY_PROTECTED, /* protected (:protected) */
};

enum rbs_type_param_variance {
Expand Down Expand Up @@ -90,53 +92,54 @@ enum rbs_node_type {
RBS_AST_MEMBERS_METHOD_DEFINITION_OVERLOAD = 28,
RBS_AST_MEMBERS_PREPEND = 29,
RBS_AST_MEMBERS_PRIVATE = 30,
RBS_AST_MEMBERS_PUBLIC = 31,
RBS_AST_RUBY_ANNOTATIONS_BLOCK_PARAM_TYPE_ANNOTATION = 32,
RBS_AST_RUBY_ANNOTATIONS_CLASS_ALIAS_ANNOTATION = 33,
RBS_AST_RUBY_ANNOTATIONS_COLON_METHOD_TYPE_ANNOTATION = 34,
RBS_AST_RUBY_ANNOTATIONS_DOUBLE_SPLAT_PARAM_TYPE_ANNOTATION = 35,
RBS_AST_RUBY_ANNOTATIONS_INSTANCE_VARIABLE_ANNOTATION = 36,
RBS_AST_RUBY_ANNOTATIONS_METHOD_TYPES_ANNOTATION = 37,
RBS_AST_RUBY_ANNOTATIONS_MODULE_ALIAS_ANNOTATION = 38,
RBS_AST_RUBY_ANNOTATIONS_MODULE_SELF_ANNOTATION = 39,
RBS_AST_RUBY_ANNOTATIONS_NODE_TYPE_ASSERTION = 40,
RBS_AST_RUBY_ANNOTATIONS_PARAM_TYPE_ANNOTATION = 41,
RBS_AST_RUBY_ANNOTATIONS_RETURN_TYPE_ANNOTATION = 42,
RBS_AST_RUBY_ANNOTATIONS_SKIP_ANNOTATION = 43,
RBS_AST_RUBY_ANNOTATIONS_SPLAT_PARAM_TYPE_ANNOTATION = 44,
RBS_AST_RUBY_ANNOTATIONS_TYPE_APPLICATION_ANNOTATION = 45,
RBS_AST_STRING = 46,
RBS_AST_TYPE_PARAM = 47,
RBS_METHOD_TYPE = 48,
RBS_NAMESPACE = 49,
RBS_SIGNATURE = 50,
RBS_TYPE_NAME = 51,
RBS_TYPES_ALIAS = 52,
RBS_TYPES_BASES_ANY = 53,
RBS_TYPES_BASES_BOOL = 54,
RBS_TYPES_BASES_BOTTOM = 55,
RBS_TYPES_BASES_CLASS = 56,
RBS_TYPES_BASES_INSTANCE = 57,
RBS_TYPES_BASES_NIL = 58,
RBS_TYPES_BASES_SELF = 59,
RBS_TYPES_BASES_TOP = 60,
RBS_TYPES_BASES_VOID = 61,
RBS_TYPES_BLOCK = 62,
RBS_TYPES_CLASS_INSTANCE = 63,
RBS_TYPES_CLASS_SINGLETON = 64,
RBS_TYPES_FUNCTION = 65,
RBS_TYPES_FUNCTION_PARAM = 66,
RBS_TYPES_INTERFACE = 67,
RBS_TYPES_INTERSECTION = 68,
RBS_TYPES_LITERAL = 69,
RBS_TYPES_OPTIONAL = 70,
RBS_TYPES_PROC = 71,
RBS_TYPES_RECORD = 72,
RBS_TYPES_RECORD_FIELD_TYPE = 73,
RBS_TYPES_TUPLE = 74,
RBS_TYPES_UNION = 75,
RBS_TYPES_UNTYPED_FUNCTION = 76,
RBS_TYPES_VARIABLE = 77,
RBS_AST_MEMBERS_PROTECTED = 31,
RBS_AST_MEMBERS_PUBLIC = 32,
RBS_AST_RUBY_ANNOTATIONS_BLOCK_PARAM_TYPE_ANNOTATION = 33,
RBS_AST_RUBY_ANNOTATIONS_CLASS_ALIAS_ANNOTATION = 34,
RBS_AST_RUBY_ANNOTATIONS_COLON_METHOD_TYPE_ANNOTATION = 35,
RBS_AST_RUBY_ANNOTATIONS_DOUBLE_SPLAT_PARAM_TYPE_ANNOTATION = 36,
RBS_AST_RUBY_ANNOTATIONS_INSTANCE_VARIABLE_ANNOTATION = 37,
RBS_AST_RUBY_ANNOTATIONS_METHOD_TYPES_ANNOTATION = 38,
RBS_AST_RUBY_ANNOTATIONS_MODULE_ALIAS_ANNOTATION = 39,
RBS_AST_RUBY_ANNOTATIONS_MODULE_SELF_ANNOTATION = 40,
RBS_AST_RUBY_ANNOTATIONS_NODE_TYPE_ASSERTION = 41,
RBS_AST_RUBY_ANNOTATIONS_PARAM_TYPE_ANNOTATION = 42,
RBS_AST_RUBY_ANNOTATIONS_RETURN_TYPE_ANNOTATION = 43,
RBS_AST_RUBY_ANNOTATIONS_SKIP_ANNOTATION = 44,
RBS_AST_RUBY_ANNOTATIONS_SPLAT_PARAM_TYPE_ANNOTATION = 45,
RBS_AST_RUBY_ANNOTATIONS_TYPE_APPLICATION_ANNOTATION = 46,
RBS_AST_STRING = 47,
RBS_AST_TYPE_PARAM = 48,
RBS_METHOD_TYPE = 49,
RBS_NAMESPACE = 50,
RBS_SIGNATURE = 51,
RBS_TYPE_NAME = 52,
RBS_TYPES_ALIAS = 53,
RBS_TYPES_BASES_ANY = 54,
RBS_TYPES_BASES_BOOL = 55,
RBS_TYPES_BASES_BOTTOM = 56,
RBS_TYPES_BASES_CLASS = 57,
RBS_TYPES_BASES_INSTANCE = 58,
RBS_TYPES_BASES_NIL = 59,
RBS_TYPES_BASES_SELF = 60,
RBS_TYPES_BASES_TOP = 61,
RBS_TYPES_BASES_VOID = 62,
RBS_TYPES_BLOCK = 63,
RBS_TYPES_CLASS_INSTANCE = 64,
RBS_TYPES_CLASS_SINGLETON = 65,
RBS_TYPES_FUNCTION = 66,
RBS_TYPES_FUNCTION_PARAM = 67,
RBS_TYPES_INTERFACE = 68,
RBS_TYPES_INTERSECTION = 69,
RBS_TYPES_LITERAL = 70,
RBS_TYPES_OPTIONAL = 71,
RBS_TYPES_PROC = 72,
RBS_TYPES_RECORD = 73,
RBS_TYPES_RECORD_FIELD_TYPE = 74,
RBS_TYPES_TUPLE = 75,
RBS_TYPES_UNION = 76,
RBS_TYPES_UNTYPED_FUNCTION = 77,
RBS_TYPES_VARIABLE = 78,
RBS_AST_SYMBOL,
};

Expand Down Expand Up @@ -560,6 +563,11 @@ typedef struct rbs_ast_members_private {

} rbs_ast_members_private_t;

typedef struct rbs_ast_members_protected {
rbs_node_t base;

} rbs_ast_members_protected_t;

typedef struct rbs_ast_members_public {
rbs_node_t base;

Expand Down Expand Up @@ -996,6 +1004,7 @@ rbs_ast_members_method_definition_t *RBS_NONNULL rbs_ast_members_method_definiti
rbs_ast_members_method_definition_overload_t *RBS_NONNULL rbs_ast_members_method_definition_overload_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_node_list_t *RBS_NONNULL annotations, rbs_node_t *RBS_NONNULL method_type);
rbs_ast_members_prepend_t *RBS_NONNULL rbs_ast_members_prepend_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_type_name_t *RBS_NONNULL name, rbs_node_list_t *RBS_NONNULL args, rbs_node_list_t *RBS_NONNULL annotations, rbs_ast_comment_t *RBS_NULLABLE comment, rbs_location_range name_range, rbs_location_range keyword_range);
rbs_ast_members_private_t *RBS_NONNULL rbs_ast_members_private_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location);
rbs_ast_members_protected_t *RBS_NONNULL rbs_ast_members_protected_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location);
rbs_ast_members_public_t *RBS_NONNULL rbs_ast_members_public_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location);
rbs_ast_ruby_annotations_block_param_type_annotation_t *RBS_NONNULL rbs_ast_ruby_annotations_block_param_type_annotation_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_location_range prefix_location, rbs_location_range ampersand_location, rbs_location_range name_location, rbs_location_range colon_location, rbs_location_range question_location, rbs_location_range type_location, rbs_node_t *RBS_NONNULL type_, rbs_location_range comment_location);
rbs_ast_ruby_annotations_class_alias_annotation_t *RBS_NONNULL rbs_ast_ruby_annotations_class_alias_annotation_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_location_range prefix_location, rbs_location_range keyword_location, rbs_type_name_t *RBS_NONNULL type_name, rbs_location_range type_name_location);
Expand Down
1 change: 1 addition & 0 deletions include/rbs/lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ enum RBSTokenType {
kOUT, /* out */
kPREPEND, /* prepend */
kPRIVATE, /* private */
kPROTECTED, /* protected */
kPUBLIC, /* public */
kSELF, /* self */
kSINGLETON, /* singleton */
Expand Down
8 changes: 8 additions & 0 deletions lib/rbs/ast/members.rb
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,14 @@ def to_json(state = nil)
end
end

class Protected < Base
include LocationOnly

def to_json(state = nil)
{ member: :protected, location: location }.to_json(state)
end
end

class Alias < Base
attr_reader :new_name
attr_reader :old_name
Expand Down
5 changes: 5 additions & 0 deletions lib/rbs/ast/visitor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ def visit(node)
visit_member_instance_variable(node)
when Members::Private
visit_member_private(node)
when Members::Protected
visit_member_protected(node)
when Members::Public
visit_member_public(node)
when Members::MethodDefinition
Expand Down Expand Up @@ -109,6 +111,9 @@ def visit_member_instance_variable(node)
def visit_member_private(node)
end

def visit_member_protected(node)
end

def visit_member_public(node)
end

Expand Down
4 changes: 4 additions & 0 deletions lib/rbs/definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ def private?
@accessibility == :private
end

def protected?
@accessibility == :protected
end

def sub(s)
return self if s.empty?

Expand Down
2 changes: 2 additions & 0 deletions lib/rbs/definition_builder/method_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ def each_rbs_member_with_accessibility(members, accessibility: :public)
accessibility = :public
when AST::Members::Private
accessibility = :private
when AST::Members::Protected
accessibility = :protected
else
yield member, accessibility
end
Expand Down
Loading
Loading