Add @rust-attr on scturct (#2785)

Fixes: #2660
This commit is contained in:
Amirhossein Akhlaghpour 2023-06-05 17:59:55 +03:30 committed by GitHub
parent bef2e3617d
commit 3a4f3c61d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 196 additions and 16 deletions

View file

@ -4,6 +4,7 @@
use super::element::{parse_element, parse_element_content};
use super::prelude::*;
use super::r#type::parse_struct_declaration;
use crate::parser::r#type::parse_rustattr;
#[cfg_attr(test, parser_test)]
/// ```test,Document
@ -45,6 +46,35 @@ pub fn parse_document(p: &mut impl Parser) -> bool {
break;
}
}
"@" if p.nth(1).as_str() == "rust-attr" => {
let mut is_export = false;
let mut i = 0;
loop {
let value = p.nth(i);
if value.as_str() == ")" && p.nth(i + 1).as_str() == "export" {
is_export = true;
break;
} else if (value.as_str() == ")"
&& p.nth(i + 1).as_str() != "struct"
&& p.nth(i + 1).as_str() != "export"
&& p.nth(i + 1).as_str() != ")")
|| (value.as_str() == ")" && p.nth(i + 1).as_str() == "struct")
{
break;
}
i += 1;
}
if is_export {
let mut p = p.start_node(SyntaxKind::ExportsList);
if !parse_rustattr(&mut *p) {
break;
}
} else {
if !parse_rustattr(&mut *p) {
break;
}
}
}
_ => {
if !parse_component(&mut *p) {
break;

View file

@ -85,3 +85,57 @@ pub fn parse_struct_declaration(p: &mut impl Parser) -> bool {
parse_type_object(&mut *p);
true
}
pub fn parse_rustattr(p: &mut impl Parser) -> bool {
let checkpoint = p.checkpoint();
debug_assert_eq!(p.peek().as_str(), "@");
p.consume(); // "@"
if p.peek().as_str() != "rust-attr" {
p.expect(SyntaxKind::AtRustAttr);
}
p.consume(); // "rust-attr"
p.expect(SyntaxKind::LParent);
parse_parentheses(&mut *p);
if p.peek().as_str() == "export" {
p.consume();
}
let mut p = p.start_node_at(checkpoint, SyntaxKind::StructDeclaration);
p.consume(); // "struct"
{
let mut p = p.start_node(SyntaxKind::DeclaredIdentifier);
p.expect(SyntaxKind::Identifier);
}
if p.peek().kind() == SyntaxKind::ColonEqual {
p.warning("':=' to declare a struct is deprecated. Remove the ':='");
p.consume();
}
parse_type_object(&mut *p);
true
}
fn parse_parentheses(p: &mut impl Parser) -> bool {
let mut p = p.start_node(SyntaxKind::AtRustAttr);
let mut opened = 0;
let mut closed = 0;
while closed <= opened {
if p.peek().kind() == SyntaxKind::LParent {
opened += 1;
}
if p.peek().kind() == SyntaxKind::RParent {
closed += 1;
}
if closed == opened && opened != 0 && closed != 0 && p.peek().kind() != SyntaxKind::RParent
{
p.error("Parse error: `)` or `,`");
return false;
}
p.consume();
}
if p.peek().as_str() != "struct" && p.peek().as_str() != "export" {
p.error("Parse error: expected `struct` or `export`");
return false;
}
true
}