Merge pull request #88 from mist-go/separate-self-param
Separate self param
This commit is contained in:
@@ -51,7 +51,7 @@ impl ClassProcessedData {
|
||||
if matches!(method.item.visibility, Visibility::Public) {
|
||||
match &method.item.is_override {
|
||||
None => {
|
||||
if method.item.is_using_self() {
|
||||
if method.item.self_param.is_some() {
|
||||
v_table.push(method.item.name.clone());
|
||||
}
|
||||
}
|
||||
@@ -263,7 +263,7 @@ impl ClassProcessedData {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let TypeExpr::Ref { mutable, .. } = params.remove(0) {
|
||||
if let Some((_, _, mutable)) = &method.item.self_param {
|
||||
method.gen_span(cg);
|
||||
cg.add_indented(&format!("{}::__m_", target_rust_path));
|
||||
cg.add(&method.item.name.get_rust());
|
||||
@@ -273,7 +273,7 @@ impl ClassProcessedData {
|
||||
0,
|
||||
TypeExpr::Ref {
|
||||
lifetime: None,
|
||||
mutable,
|
||||
mutable: *mutable,
|
||||
ty: Box::new(get_type_from_path(&target_path)),
|
||||
},
|
||||
);
|
||||
@@ -375,20 +375,6 @@ impl ClassProcessedData {
|
||||
cg.indent -= 1;
|
||||
cg.add_indentedln("}\n");
|
||||
|
||||
let mut constructor_params = vec![VarDecl {
|
||||
name: Pattern::Path(false, Path(vec![Identifier(String::from("self"))])),
|
||||
type_: Some(TypeExpr::Ref {
|
||||
lifetime: None,
|
||||
mutable: true,
|
||||
ty: Box::new(TypeExpr::Path(
|
||||
Path(vec![Identifier(String::from("Self"))]),
|
||||
None,
|
||||
)),
|
||||
}),
|
||||
}];
|
||||
|
||||
constructor_params.append(&mut constructor.item.params.0.clone());
|
||||
|
||||
Spanned {
|
||||
line: constructor.line,
|
||||
column: constructor.column,
|
||||
@@ -397,7 +383,8 @@ impl ClassProcessedData {
|
||||
is_override: None,
|
||||
name: Identifier(String::from("constructor")),
|
||||
generics: constructor.item.generics.clone(),
|
||||
params: ParamList(constructor_params),
|
||||
params: constructor.item.params.clone(),
|
||||
self_param: Some((true, None, true)),
|
||||
return_type: Some(TypeExpr::Tuple(Vec::new())),
|
||||
body: Some(constructor.item.body.clone()),
|
||||
},
|
||||
@@ -409,7 +396,7 @@ impl ClassProcessedData {
|
||||
for method in &self.methods {
|
||||
match method.item.visibility {
|
||||
Visibility::Public => {
|
||||
if method.item.is_using_self() {
|
||||
if method.item.self_param.is_some() {
|
||||
if method.item.is_override.is_none() {
|
||||
gen_method_point(&method.item, ctx, cg);
|
||||
}
|
||||
@@ -513,6 +500,7 @@ fn construct_pattern(pat: &Pattern, idx: usize) -> Pattern {
|
||||
}
|
||||
|
||||
pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustCodegen) {
|
||||
let mutable_self = if let Some((is_ref, lifetime, is_mut)) = &method.self_param {
|
||||
cg.add_indented(&format!(
|
||||
"{}fn {}{}(",
|
||||
method.visibility.get_rust(),
|
||||
@@ -520,6 +508,25 @@ pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustC
|
||||
method.generics.get_rust(),
|
||||
));
|
||||
|
||||
if *is_ref {
|
||||
cg.add("&");
|
||||
}
|
||||
|
||||
if let Some(lifetime) = lifetime {
|
||||
cg.add(&format!("'{} ", lifetime.0));
|
||||
}
|
||||
|
||||
if *is_mut {
|
||||
cg.add("mut ");
|
||||
}
|
||||
|
||||
cg.add("self,");
|
||||
|
||||
*is_mut
|
||||
} else {
|
||||
panic!();
|
||||
};
|
||||
|
||||
let params = method
|
||||
.params
|
||||
.0
|
||||
@@ -566,14 +573,10 @@ pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustC
|
||||
.filter_map(|v| v.type_)
|
||||
.collect();
|
||||
|
||||
let TypeExpr::Ref { mutable, .. } = param_types.remove(0) else {
|
||||
panic!("")
|
||||
};
|
||||
|
||||
param_types.insert(
|
||||
0,
|
||||
TypeExpr::UnsafePtr {
|
||||
mutable,
|
||||
mutable: mutable_self,
|
||||
ty: Box::new(TypeExpr::Path(
|
||||
Path(vec![
|
||||
Identifier(String::from("std")),
|
||||
@@ -588,16 +591,13 @@ pub fn gen_method_point(method: &FunctionDecl, ctx: &mut Context, cg: &mut RustC
|
||||
cg.add(&TypeExpr::StaticFn(param_types, method.return_type.clone().map(Box::new)).get_rust());
|
||||
cg.addln(" = std::mem::transmute(func_ptr);");
|
||||
|
||||
if mutable {
|
||||
if mutable_self {
|
||||
cg.add_indented("func(self as *mut Self as *const std::ffi::c_void");
|
||||
} else {
|
||||
cg.add_indented("func(self as *const Self as *const std::ffi::c_void");
|
||||
}
|
||||
|
||||
for (i, param) in ¶ms {
|
||||
if *i == 0 {
|
||||
continue; // self already fulfills it
|
||||
}
|
||||
for (_, param) in ¶ms {
|
||||
cg.add(", ");
|
||||
ctx.expr_ensure_semicolon = false;
|
||||
param.name.gen_rust(ctx, cg);
|
||||
|
||||
@@ -80,6 +80,22 @@ impl GenRust for FunctionDecl {
|
||||
self.generics.get_rust(),
|
||||
));
|
||||
|
||||
if let Some((is_ref, lifetime, is_mut)) = &self.self_param {
|
||||
if *is_ref {
|
||||
cg.add("&");
|
||||
}
|
||||
|
||||
if let Some(lifetime) = lifetime {
|
||||
cg.add(&format!("'{} ", lifetime.0));
|
||||
}
|
||||
|
||||
if *is_mut {
|
||||
cg.add("mut ");
|
||||
}
|
||||
|
||||
cg.add("self,");
|
||||
}
|
||||
|
||||
for (i, param) in self.params.0.iter().enumerate() {
|
||||
if i > 0 {
|
||||
cg.add(", ");
|
||||
|
||||
@@ -100,6 +100,7 @@ pub struct FunctionDecl {
|
||||
pub is_override: Option<Override>,
|
||||
pub name: Identifier,
|
||||
pub generics: GenericsDecl,
|
||||
pub self_param: Option<(bool, Option<Identifier>, bool)>,
|
||||
pub params: ParamList,
|
||||
pub return_type: Option<TypeExpr>,
|
||||
pub body: Option<Block>,
|
||||
@@ -125,18 +126,3 @@ pub struct FieldDeclStmt {
|
||||
pub decl: FieldDecl,
|
||||
pub init: Option<Expression>,
|
||||
}
|
||||
|
||||
impl FunctionDecl {
|
||||
pub fn is_using_self(&self) -> bool {
|
||||
match self.params.0.get(0) {
|
||||
Some(VarDecl { name, .. }) => {
|
||||
if let Pattern::Path(_, v) = name {
|
||||
v.0.len() == 1 && v.0[0].0 == "self"
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::{
|
||||
ast::*,
|
||||
ast_ensure,
|
||||
error::{self, AstError, AstResult},
|
||||
parser::{consume_rule, listen_rule},
|
||||
parser::{consume_rule, consume_rule_map, listen_rule},
|
||||
};
|
||||
|
||||
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
|
||||
@@ -25,43 +25,19 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
|
||||
.transpose()
|
||||
.map(|v| v.unwrap_or_default())?;
|
||||
|
||||
let self_param = consume_rule(&mut inner, Rule::self_param).map(|param| {
|
||||
let self_param = consume_rule_map(&mut inner, Rule::self_param, |param| {
|
||||
let mut param_inner = param.into_inner();
|
||||
|
||||
let is_ref = listen_rule(&mut param_inner, Rule::ref_px);
|
||||
let lifetime = consume_rule(&mut param_inner, Rule::lifetime);
|
||||
let mutable = listen_rule(&mut param_inner, Rule::mutable);
|
||||
let name = Pattern::Path(mutable && !is_ref, Path(vec![Identifier(String::from("self"))]));
|
||||
let self_ty = TypeExpr::Path(Path(vec![Identifier(String::from("Self"))]), None);
|
||||
|
||||
VarDecl {
|
||||
name: name.clone(),
|
||||
type_: Some(if is_ref {
|
||||
TypeExpr::Ref {
|
||||
lifetime:
|
||||
lifetime.map(|v| Lifetime::try_from(v.into_inner().next().unwrap()))
|
||||
.transpose()
|
||||
.expect("Failed to get lifetime identifier"),
|
||||
mutable,
|
||||
ty: Box::new(self_ty)
|
||||
}
|
||||
} else {
|
||||
self_ty
|
||||
}),
|
||||
}
|
||||
});
|
||||
Ok((is_ref, lifetime.map(|v| -> AstResult<Identifier> {
|
||||
Identifier::try_from(v.into_inner().next().unwrap())
|
||||
}).transpose()?, mutable))
|
||||
})?;
|
||||
|
||||
let params = consume_rule(&mut inner, Rule::param_list)
|
||||
.map({
|
||||
let self_param = self_param.clone();
|
||||
|params_pair| -> AstResult<'a, ParamList> {
|
||||
let mut params = ParamList::try_from(params_pair)?;
|
||||
if let Some(x) = self_param {
|
||||
params.0.insert(0, x);
|
||||
}
|
||||
Ok(params)
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|| Ok(ParamList(self_param.into_iter().collect())))?;
|
||||
let params = consume_rule(&mut inner, Rule::param_list).map(ParamList::try_from).transpose()?.unwrap_or_default();
|
||||
|
||||
let is_override = consume_rule(&mut inner, Rule::override_kw).map(Override::try_from).transpose()?;
|
||||
|
||||
@@ -73,6 +49,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
|
||||
return_type: return_type,
|
||||
name: name,
|
||||
generics: generics,
|
||||
self_param: self_param,
|
||||
params: params,
|
||||
body: body,
|
||||
})
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
pub mod common;
|
||||
pub mod items;
|
||||
|
||||
use crate::{Rule, ast::Spanned, error::AstError};
|
||||
use crate::{
|
||||
Rule,
|
||||
ast::Spanned,
|
||||
error::{AstError, AstResult},
|
||||
};
|
||||
|
||||
pub fn listen_rule(pairs: &mut pest::iterators::Pairs<'_, Rule>, rule: Rule) -> bool {
|
||||
let consumed = pairs
|
||||
@@ -28,6 +32,20 @@ pub fn consume_rule<'a>(
|
||||
if consumed { pairs.next() } else { None }
|
||||
}
|
||||
|
||||
pub fn consume_rule_map<'a, T>(
|
||||
pairs: &mut pest::iterators::Pairs<'a, Rule>,
|
||||
rule: Rule,
|
||||
map: impl Fn(pest::iterators::Pair<'a, Rule>) -> AstResult<'a, T>,
|
||||
) -> AstResult<'a, Option<T>> {
|
||||
let pair = consume_rule(pairs, rule);
|
||||
|
||||
if let Some(pair) = pair {
|
||||
Some(map(pair)).transpose()
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Spanned<T> {
|
||||
fn new_pair(pair: pest::iterators::Pair<'_, Rule>, item: T) -> Self {
|
||||
let span = pair.as_span().start_pos().line_col();
|
||||
|
||||
@@ -22,7 +22,7 @@ pub fn find_function_call<'a>(
|
||||
) -> Option<&'a Spanned<FunctionDecl>> {
|
||||
items.iter().find_map(|v| {
|
||||
if let ClassItem::Method(m) = v {
|
||||
if m.item.is_using_self() && &m.item.name == name {
|
||||
if m.item.self_param.is_some() && &m.item.name == name {
|
||||
Some(m)
|
||||
} else {
|
||||
None
|
||||
|
||||
@@ -11,7 +11,7 @@ pub class Animal {
|
||||
"Unknown".to_string()
|
||||
}
|
||||
|
||||
pub void test_speak(&self) {
|
||||
pub void test_speak<'a>(&'a self) {
|
||||
assert_eq!(self.speak(), "Woof!");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user