From 45436b63fe45587d561bd0b296a9a1317105f03b Mon Sep 17 00:00:00 2001 From: Wodann Date: Tue, 20 Feb 2024 20:38:58 +0000 Subject: [PATCH] feat: add self parameter --- crates/mun_syntax/src/ast/generated.rs | 27 ++++++ crates/mun_syntax/src/grammar.ron | 6 ++ crates/mun_syntax/src/parsing/grammar.rs | 6 +- .../mun_syntax/src/parsing/grammar/params.rs | 24 ++++- .../mun_syntax/src/syntax_kind/generated.rs | 2 + crates/mun_syntax/src/tests/parser.rs | 88 ++++++++++++++++++- crates/tools/src/lib.rs | 1 + 7 files changed, 146 insertions(+), 8 deletions(-) diff --git a/crates/mun_syntax/src/ast/generated.rs b/crates/mun_syntax/src/ast/generated.rs index df6695b9..f5b2d3ed 100644 --- a/crates/mun_syntax/src/ast/generated.rs +++ b/crates/mun_syntax/src/ast/generated.rs @@ -1558,6 +1558,33 @@ impl ReturnExpr { } } +// SelfParam + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct SelfParam { + pub(crate) syntax: SyntaxNode, +} + +impl AstNode for SelfParam { + fn can_cast(kind: SyntaxKind) -> bool { + matches!(kind, + SELF_PARAM + ) + } + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(SelfParam { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } +} +impl ast::TypeAscriptionOwner for SelfParam {} +impl SelfParam {} + // SourceFile #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/crates/mun_syntax/src/grammar.ron b/crates/mun_syntax/src/grammar.ron index b32cafaa..a7806cd2 100644 --- a/crates/mun_syntax/src/grammar.ron +++ b/crates/mun_syntax/src/grammar.ron @@ -129,6 +129,7 @@ Grammar( "PARAM_LIST", "PARAM", + "SELF_PARAM", "STRUCT_DEF", "TYPE_ALIAS_DEF", @@ -215,6 +216,11 @@ Grammar( "TypeAscriptionOwner" ], ), + "SelfParam": ( + traits: [ + "TypeAscriptionOwner", + ] + ), "StructDef": ( options: ["MemoryTypeSpecifier"], traits: [ diff --git a/crates/mun_syntax/src/parsing/grammar.rs b/crates/mun_syntax/src/parsing/grammar.rs index 191a21fe..9dfb5d5c 100644 --- a/crates/mun_syntax/src/parsing/grammar.rs +++ b/crates/mun_syntax/src/parsing/grammar.rs @@ -17,9 +17,9 @@ use super::{ LOOP_EXPR, MEMORY_TYPE_SPECIFIER, NAME, NAME_REF, NEVER_TYPE, PARAM, PARAM_LIST, PAREN_EXPR, PATH, PATH_EXPR, PATH_SEGMENT, PATH_TYPE, PLACEHOLDER_PAT, PREFIX_EXPR, RECORD_FIELD, RECORD_FIELD_DEF, RECORD_FIELD_DEF_LIST, RECORD_FIELD_LIST, RECORD_LIT, - RENAME, RETURN_EXPR, RET_TYPE, SOURCE_FILE, STRING, STRUCT_DEF, TUPLE_FIELD_DEF, - TUPLE_FIELD_DEF_LIST, TYPE_ALIAS_DEF, USE, USE_TREE, USE_TREE_LIST, VALUE_KW, VISIBILITY, - WHILE_EXPR, + RENAME, RETURN_EXPR, RET_TYPE, SELF_PARAM, SOURCE_FILE, STRING, STRUCT_DEF, + TUPLE_FIELD_DEF, TUPLE_FIELD_DEF_LIST, TYPE_ALIAS_DEF, USE, USE_TREE, USE_TREE_LIST, + VALUE_KW, VISIBILITY, WHILE_EXPR, }, }; diff --git a/crates/mun_syntax/src/parsing/grammar/params.rs b/crates/mun_syntax/src/parsing/grammar/params.rs index 0f005e40..f59fb996 100644 --- a/crates/mun_syntax/src/parsing/grammar/params.rs +++ b/crates/mun_syntax/src/parsing/grammar/params.rs @@ -1,4 +1,4 @@ -use super::{patterns, types, Parser, TokenSet, EOF, PARAM, PARAM_LIST}; +use super::{patterns, types, Parser, TokenSet, EOF, NAME, PARAM, PARAM_LIST, SELF_PARAM}; pub(super) fn param_list(p: &mut Parser<'_>) { list(p); @@ -6,8 +6,12 @@ pub(super) fn param_list(p: &mut Parser<'_>) { fn list(p: &mut Parser<'_>) { assert!(p.at(T!['('])); + let m = p.start(); p.bump(T!['(']); + + opt_self_param(p); + while !p.at(EOF) && !p.at(T![')']) { if !p.at_ts(VALUE_PARAMETER_FIRST) { p.error("expected value parameter"); @@ -30,3 +34,21 @@ fn param(p: &mut Parser<'_>) { types::ascription(p); m.complete(p, PARAM); } + +fn opt_self_param(p: &mut Parser<'_>) { + if p.at(T![self]) { + let m = p.start(); + self_as_name(p); + m.complete(p, SELF_PARAM); + + if !p.at(T![')']) { + p.expect(T![,]); + } + } +} + +fn self_as_name(p: &mut Parser<'_>) { + let m = p.start(); + p.bump(T![self]); + m.complete(p, NAME); +} diff --git a/crates/mun_syntax/src/syntax_kind/generated.rs b/crates/mun_syntax/src/syntax_kind/generated.rs index 43a5a909..9dae83d0 100644 --- a/crates/mun_syntax/src/syntax_kind/generated.rs +++ b/crates/mun_syntax/src/syntax_kind/generated.rs @@ -109,6 +109,7 @@ pub enum SyntaxKind { VISIBILITY, PARAM_LIST, PARAM, + SELF_PARAM, STRUCT_DEF, TYPE_ALIAS_DEF, MEMORY_TYPE_SPECIFIER, @@ -589,6 +590,7 @@ impl SyntaxKind { VISIBILITY => &SyntaxInfo { name: "VISIBILITY" }, PARAM_LIST => &SyntaxInfo { name: "PARAM_LIST" }, PARAM => &SyntaxInfo { name: "PARAM" }, + SELF_PARAM => &SyntaxInfo { name: "SELF_PARAM" }, STRUCT_DEF => &SyntaxInfo { name: "STRUCT_DEF" }, TYPE_ALIAS_DEF => &SyntaxInfo { name: "TYPE_ALIAS_DEF" }, MEMORY_TYPE_SPECIFIER => &SyntaxInfo { name: "MEMORY_TYPE_SPECIFIER" }, diff --git a/crates/mun_syntax/src/tests/parser.rs b/crates/mun_syntax/src/tests/parser.rs index 5b789836..d77fb9fc 100644 --- a/crates/mun_syntax/src/tests/parser.rs +++ b/crates/mun_syntax/src/tests/parser.rs @@ -1249,9 +1249,12 @@ fn function_calls() { fn foo(i:number) { bar(i+1) } + fn baz(self) { } + fn qux(self, i:number) { } + fn foo(self i:number) { } // error: expected comma "#, - ).debug_dump(), @r#" - SOURCE_FILE@0..74 + ).debug_dump(), @r###" + SOURCE_FILE@0..181 FUNCTION_DEF@0..25 WHITESPACE@0..5 "\n " FN_KW@5..7 "fn" @@ -1319,8 +1322,85 @@ fn function_calls() { R_PAREN@62..63 ")" WHITESPACE@63..68 "\n " R_CURLY@68..69 "}" - WHITESPACE@69..74 "\n " - "#); + FUNCTION_DEF@69..90 + WHITESPACE@69..74 "\n " + FN_KW@74..76 "fn" + WHITESPACE@76..77 " " + NAME@77..80 + IDENT@77..80 "baz" + PARAM_LIST@80..86 + L_PAREN@80..81 "(" + SELF_PARAM@81..85 + NAME@81..85 + SELF_KW@81..85 "self" + R_PAREN@85..86 ")" + WHITESPACE@86..87 " " + BLOCK_EXPR@87..90 + L_CURLY@87..88 "{" + WHITESPACE@88..89 " " + R_CURLY@89..90 "}" + FUNCTION_DEF@90..121 + WHITESPACE@90..95 "\n " + FN_KW@95..97 "fn" + WHITESPACE@97..98 " " + NAME@98..101 + IDENT@98..101 "qux" + PARAM_LIST@101..117 + L_PAREN@101..102 "(" + SELF_PARAM@102..106 + NAME@102..106 + SELF_KW@102..106 "self" + COMMA@106..107 "," + WHITESPACE@107..108 " " + PARAM@108..116 + BIND_PAT@108..109 + NAME@108..109 + IDENT@108..109 "i" + COLON@109..110 ":" + PATH_TYPE@110..116 + PATH@110..116 + PATH_SEGMENT@110..116 + NAME_REF@110..116 + IDENT@110..116 "number" + R_PAREN@116..117 ")" + WHITESPACE@117..118 " " + BLOCK_EXPR@118..121 + L_CURLY@118..119 "{" + WHITESPACE@119..120 " " + R_CURLY@120..121 "}" + FUNCTION_DEF@121..151 + WHITESPACE@121..126 "\n " + FN_KW@126..128 "fn" + WHITESPACE@128..129 " " + NAME@129..132 + IDENT@129..132 "foo" + PARAM_LIST@132..147 + L_PAREN@132..133 "(" + SELF_PARAM@133..137 + NAME@133..137 + SELF_KW@133..137 "self" + WHITESPACE@137..138 " " + PARAM@138..146 + BIND_PAT@138..139 + NAME@138..139 + IDENT@138..139 "i" + COLON@139..140 ":" + PATH_TYPE@140..146 + PATH@140..146 + PATH_SEGMENT@140..146 + NAME_REF@140..146 + IDENT@140..146 "number" + R_PAREN@146..147 ")" + WHITESPACE@147..148 " " + BLOCK_EXPR@148..151 + L_CURLY@148..149 "{" + WHITESPACE@149..150 " " + R_CURLY@150..151 "}" + WHITESPACE@151..152 " " + COMMENT@152..176 "// error: expected comma" + WHITESPACE@176..181 "\n " + error Offset(137): expected COMMA + "###); } #[test] diff --git a/crates/tools/src/lib.rs b/crates/tools/src/lib.rs index cd7882f2..05c7f7f0 100644 --- a/crates/tools/src/lib.rs +++ b/crates/tools/src/lib.rs @@ -36,6 +36,7 @@ fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> { fn reformat(text: impl std::fmt::Display) -> Result { let mut rustfmt = Command::new("rustfmt") + .arg("+nightly") //.arg("--config-path") //.arg(project_root().join("rustfmt.toml")) .stdin(Stdio::piped())