Support #[ruby_name = "blank?"]

Support using attributes to specify the Ruby name for a method.

At the same time, refactor the macro.
This commit is contained in:
Yehuda Katz 2017-04-21 17:52:56 -07:00
parent ea51eeb654
commit b72c306cd4
9 changed files with 110 additions and 60 deletions

View File

@ -9,14 +9,6 @@ case ENV["IMPLEMENTATION"]
when "RUST"
require "duration/native"
::Duration.class_eval do
alias_method :+, :plus
alias_method :-, :minus
alias_method :-@, :negate
alias_method :<=>, :cmp
alias_method :==, :eq
end
ActiveSupport::Duration = ::Duration
when "RAILS"
require "active_support/duration"

View File

@ -76,6 +76,7 @@ declare_types! {
self.value
}
#[ruby_name = "+"]
def plus(&self, other: &Duration) -> Duration {
Duration::new(
sum_part(self.seconds, other.seconds),
@ -88,10 +89,12 @@ declare_types! {
)
}
#[ruby_name = "-"]
def minus(&self, other: &Duration) -> Duration {
self.plus(&other.negate())
}
#[ruby_name = "-@"]
def negate(&self) -> Duration {
Duration::new(
negate_part(self.seconds),
@ -104,10 +107,12 @@ declare_types! {
)
}
#[ruby_name = "=="]
def eq(&self, other: &Duration) -> bool {
self.value == other.value
}
#[ruby_name = "<=>"]
def cmp(&self, other: &Duration) -> i32 {
match self.value.cmp(&other.value) {
Ordering::Less => -1,

View File

@ -30,7 +30,7 @@ def scenario(title, str, expected)
raise "Expected " + str.inspect + ".rails_5_blank? to be #{expected}"
end
unless str.is_blank == #{expected}
unless str.blank? == #{expected}
raise "Expected " + str.inspect + ".is_blank to be #{expected}"
end

View File

@ -17,7 +17,6 @@ class String
case ENV["IMPLEMENTATION"]
when "RUST"
alias blank? is_blank
when "RAILS_4_2"
alias blank? rails_4_2_blank?
when "RAILS_5"

View File

@ -3,6 +3,7 @@ extern crate helix_runtime as helix;
declare_types! {
reopen class RubyString {
#[ruby_name = "blank?"]
def is_blank(&self) -> bool {
// self.chars().all(|c| c.is_whitespace())
self.to_string().chars().all(|c| c.is_whitespace())

View File

@ -1,19 +1,13 @@
#[macro_export]
macro_rules! codegen {
{ [ $($ast:tt)* ] } => {
mod init_native {
codegen! {
type: top,
classes: [],
buffer: [ $($ast)* ]
}
codegen_init! { [ $($ast)* ] }
codegen! {
type: top,
classes: [],
buffer: [ $($ast)* ]
}
codegen_pub_classes!($($ast)*);
pub use self::init_native::Init_native;
codegen_init! { [ $($ast)* ] }
};
{
@ -160,7 +154,8 @@ macro_rules! codegen_method {
{
{
type: initializer,
name: $name:tt,
rust_name: $rust_name:tt,
ruby_name: $ruby_name:tt,
self: {
ownership: {},
name: $self:tt
@ -170,26 +165,28 @@ macro_rules! codegen_method {
body: $body:block
}
} => {
pub fn $name($self : $crate::Metadata, $($arg : $argty),*) -> $($ret)* $body
pub fn $rust_name($self : $crate::Metadata, $($arg : $argty),*) -> $($ret)* $body
};
{
{
type: class_method,
name: $name:tt,
rust_name: $rust_name:tt,
ruby_name: $ruby_name:tt,
self: (),
args: [ $($args:tt)* ],
ret: { $($ret:tt)* },
body: $body:block
}
} => {
pub fn $name($($args)*) -> $($ret)* $body
pub fn $rust_name($($args)*) -> $($ret)* $body
};
{
{
type: instance_method,
name: $name:tt,
rust_name: $rust_name:tt,
ruby_name: $ruby_name:tt,
self: {
ownership: { $($ownership:tt)* },
name: $self:tt
@ -199,7 +196,7 @@ macro_rules! codegen_method {
body: $body:block
}
} => {
pub fn $name($($ownership)* $self, $($args)*) -> $($ret)* $body
pub fn $rust_name($($ownership)* $self, $($args)*) -> $($ret)* $body
};
}

View File

@ -82,7 +82,8 @@ macro_rules! codegen_define_method {
$($rest:tt)*
}, {
type: class_method,
name: $name:tt,
rust_name: $rust_name:tt,
ruby_name: { $($ruby_name:tt)* },
self: (),
args: [ $($arg:tt : $argty:ty),* ],
ret: { $($ret:tt)* },
@ -134,11 +135,11 @@ macro_rules! codegen_define_method {
)*
handle_exception! {
$cls::$name($($arg),*)
$cls::$rust_name($($arg),*)
}
}
let name = cstr!(stringify!($name));
let name = cstr!($($ruby_name)*);
let method = __ruby_method__ as *const $crate::libc::c_void;
let arity = method_arity!($($arg)*);
@ -153,7 +154,8 @@ macro_rules! codegen_define_method {
$($rest:tt)*
}, {
type: instance_method,
name: $name:tt,
rust_name: $rust_name:tt,
ruby_name: { $($ruby_name:tt)* },
self: { ownership: { $($ownership:tt)* }, name: $self:tt },
args: [ $($arg:tt : $argty:ty),* ],
ret: { $($ret:tt)* },
@ -211,11 +213,11 @@ macro_rules! codegen_define_method {
)*
handle_exception! {
rust_self.$name($($arg),*)
rust_self.$rust_name($($arg),*)
}
}
let name = cstr!(stringify!($name));
let name = cstr!($($ruby_name)*);
let method = __ruby_method__ as *const $crate::libc::c_void;
let arity = method_arity!($($arg)*);
@ -230,7 +232,8 @@ macro_rules! codegen_define_method {
$($rest:tt)*
}, {
type: initializer,
name: $name:tt,
rust_name: $rust_name:tt,
ruby_name: { $($ruby_name:tt)* },
self: { ownership: {}, name: $self:tt },
args: [ $($arg:tt : $argty:ty),* ],
ret: { $($ret:tt)* },
@ -238,7 +241,7 @@ macro_rules! codegen_define_method {
}) => ({
impl $cls {
pub fn new($($arg : $argty),*) -> $($ret)* {
$cls::$name(unsafe { $crate::sys::Qnil } , $($arg),*)
$cls::$rust_name(unsafe { $crate::sys::Qnil } , $($arg),*)
}
}
@ -274,7 +277,7 @@ macro_rules! codegen_define_method {
let arity = method_arity!($($arg)*);
let method = __initialize__ as *const $crate::libc::c_void;
$def.define_method($crate::MethodDefinition::instance(cstr!("initialize"), method, arity));
$def.define_method($crate::MethodDefinition::instance(cstr!($($ruby_name)*), method, arity));
});
}

View File

@ -1,10 +1,18 @@
#[macro_use]
mod parser;
#[macro_use]
mod codegen;
#[macro_use]
mod init;
#[macro_use]
mod coercions;
#[macro_use]
mod alloc;
#[macro_export]
macro_rules! declare_types {
{ $($rest:tt)* } => {
@ -71,3 +79,4 @@ macro_rules! throw {
panic!($crate::ExceptionInfo::with_message(String::from($msg)))
}
}

View File

@ -228,13 +228,33 @@ macro_rules! parse {
{
state: parse_methods,
buffer: { def $($rest:tt)* },
stack: $stack:tt
buffer: { #[ruby_name = $ruby_name:tt] def $name:tt $($rest:tt)* },
stack: { $($stack:tt)* }
} => {
parse! {
state: parse_method,
buffer: { $($rest)* },
stack: $stack
stack: {
rust_name: $name,
ruby_name: { $ruby_name },
$($stack)*
}
}
};
{
state: parse_methods,
buffer: { def $name:tt $($rest:tt)* },
stack: { $($stack:tt)* }
} => {
parse! {
state: parse_method,
buffer: { $($rest)* },
stack: {
rust_name: $name,
ruby_name: { stringify!($name) },
$($stack)*
}
}
};
@ -260,8 +280,10 @@ macro_rules! parse {
{
state: parse_method,
buffer: { initialize ( $($args:tt)* ) $($rest:tt)* },
buffer: { ( $($args:tt)* ) $($rest:tt)* },
stack: {
rust_name: initialize,
ruby_name: $ruby_name:tt,
class: $class:tt,
$($stack:tt)*
}
@ -281,14 +303,19 @@ macro_rules! parse {
{
state: parse_method,
buffer: { $name:tt ( $($args:tt)* ) $($rest:tt)* },
stack: { $($stack:tt)* }
buffer: { ( $($args:tt)* ) $($rest:tt)* },
stack: {
rust_name: $rust_name:tt,
ruby_name: $ruby_name:tt,
$($stack:tt)*
}
} => {
parse! {
state: parse_arguments_self,
buffer: { $($args)* },
stack: {
name: $name,
rust_name: $rust_name,
ruby_name: $ruby_name,
class_body: { $($rest)* },
$($stack)*
}
@ -308,7 +335,8 @@ macro_rules! parse {
stack: {
method: {
type: initializer,
name: initialize,
rust_name: initialize,
ruby_name: { "initialize" },
self: {
ownership: { },
name: $helix_arg
@ -328,7 +356,8 @@ macro_rules! parse {
state: parse_arguments_self,
buffer: { &mut $self_arg:tt $($rest:tt)* },
stack: {
name: $name:tt,
rust_name: $rust_name:tt,
ruby_name: $ruby_name:tt,
$($stack:tt)*
}
} => {
@ -340,7 +369,8 @@ macro_rules! parse {
stack: {
method: {
type: instance_method,
name: $name,
rust_name: $rust_name,
ruby_name: $ruby_name,
self: {
ownership: { &mut },
name: $self_arg
@ -358,7 +388,8 @@ macro_rules! parse {
state: parse_arguments_self,
buffer: { & $self_arg:tt $($rest:tt)* },
stack: {
name: $name:tt,
rust_name: $rust_name:tt,
ruby_name: $ruby_name:tt,
$($stack:tt)*
}
} => {
@ -370,7 +401,8 @@ macro_rules! parse {
stack: {
method: {
type: instance_method,
name: $name,
rust_name: $rust_name,
ruby_name: $ruby_name,
self: {
ownership: { & },
name: $self_arg
@ -388,7 +420,8 @@ macro_rules! parse {
state: parse_arguments_self,
buffer: $buffer:tt,
stack: {
name: $name:tt,
rust_name: $rust_name:tt,
ruby_name: $ruby_name:tt,
$($stack:tt)*
}
} => {
@ -398,7 +431,8 @@ macro_rules! parse {
stack: {
method: {
type: class_method,
name: $name,
rust_name: $rust_name,
ruby_name: $ruby_name,
self: (),
args: uninitialized,
ret: uninitialized,
@ -443,7 +477,8 @@ macro_rules! parse {
stack: {
method: {
type: $type:tt,
name: $name:tt,
rust_name: $rust_name:tt,
ruby_name: $ruby_name:tt,
self: $self:tt,
args: uninitialized,
ret: uninitialized,
@ -459,7 +494,8 @@ macro_rules! parse {
stack: {
method: {
type: $type,
name: $name,
rust_name: $rust_name,
ruby_name: $ruby_name,
self: $self,
args: [ $($args)* ],
ret: uninitialized,
@ -478,7 +514,8 @@ macro_rules! parse {
stack: {
method: {
type: $type:tt,
name: $name:tt,
rust_name: $rust_name:tt,
ruby_name: $ruby_name:tt,
self: $self:tt,
args: $args:tt,
ret: uninitialized,
@ -495,7 +532,8 @@ macro_rules! parse {
stack: {
method: {
type: $type,
name: $name,
rust_name: $rust_name,
ruby_name: $ruby_name,
self: $self,
args: $args,
ret: { $ret },
@ -512,7 +550,8 @@ macro_rules! parse {
stack: {
method: {
type: initializer,
name: initialize,
rust_name: $rust_name:tt,
ruby_name: $ruby_name:tt,
self: $self:tt,
args: $args:tt,
ret: uninitialized,
@ -534,7 +573,8 @@ macro_rules! parse {
stack: {
method: {
type: initializer,
name: initialize,
rust_name: $rust_name,
ruby_name: $ruby_name,
self: $self,
args: $args,
ret: { $name },
@ -559,7 +599,8 @@ macro_rules! parse {
stack: {
method: {
type: initializer,
name: $name:tt,
rust_name: $rust_name:tt,
ruby_name: $ruby_name:tt,
self: $self:tt,
args: $args:tt,
ret: uninitialized,
@ -580,7 +621,8 @@ macro_rules! parse {
stack: {
method: {
type: initializer,
name: $name,
rust_name: $rust_name,
ruby_name: $ruby_name,
self: $self,
args: $args,
ret: { $class_name },
@ -604,7 +646,8 @@ macro_rules! parse {
stack: {
method: {
type: $type:tt,
name: $name:tt,
rust_name: $rust_name:tt,
ruby_name: $ruby_name:tt,
self: $self:tt,
args: $args:tt,
ret: uninitialized,
@ -619,7 +662,8 @@ macro_rules! parse {
stack: {
method: {
type: $type,
name: $name,
rust_name: $rust_name,
ruby_name: $ruby_name,
self: $self,
args: $args,
ret: { () },