Skip to content

Commit

Permalink
Fixes #3196
Browse files Browse the repository at this point in the history
gcc/rust/ChangeLog:

	* ast/rust-ast-collector.cc (TokenCollector::visit): Add behaviour.
	In Attribute visitor, recognize doc from comment and handle it.

	* ast/rust-ast.h: Changes Attribute constructor and add a boolean
	in the class for doc comments.

	* lex/rust-token.cc (Token::as_string): Return the correct string
	for the new DOC_STRING_LITERAL token.

	* lex/rust-token.h (enum PrimitiveCoreType): Add two tokens :
	DOC_STRING_LITERAL and DOC_END, for pretty-printing purposes.
	Also modify the string of two previous tokens.

	* parse/rust-parse-impl.h (Parser::parse_inner_attribute):
	Updates the Attribute constructor call.

	(Parser::parse_outer_attribute): Same as above.

Signed-off-by: lucas.plantrose <[email protected]>
  • Loading branch information
MajoraSans committed Oct 18, 2024
1 parent 6708d35 commit 91d4c03
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 34 deletions.
76 changes: 48 additions & 28 deletions gcc/rust/ast/rust-ast-collector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,38 +141,58 @@ TokenCollector::visit (VariadicParam &param)
void
TokenCollector::visit (Attribute &attrib)
{
push (Rust::Token::make (HASH, attrib.get_locus ()));
if (attrib.is_inner_attribute ())
push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
push (Rust::Token::make (LEFT_SQUARE, UNDEF_LOCATION));
visit (attrib.get_path ());

if (attrib.has_attr_input ())
if (attrib.is_from_comment () && attrib.has_attr_input ())
{
if (attrib.is_inner_attribute ())
push (Rust::Token::make (INNER_DOC_COMMENT, attrib.get_locus ()));
else
push (Rust::Token::make (OUTER_DOC_COMMENT, attrib.get_locus ()));
auto lit = (static_cast<AttrInputLiteral &> (attrib.get_attr_input ()))
.get_literal ()
.get_literal ();
push (Rust::Token::make_doc_string_literal (attrib.get_locus (),
lit.as_string ()));
push (Rust::Token::make (DOC_COMMENT_END, attrib.get_locus ()));
return;
}
else
{
switch (attrib.get_attr_input ().get_attr_input_type ())
push (Rust::Token::make (HASH, attrib.get_locus ()));
if (attrib.is_inner_attribute ())
push (Rust::Token::make (EXCLAM, UNDEF_LOCATION));
push (Rust::Token::make (LEFT_SQUARE, UNDEF_LOCATION));
visit (attrib.get_path ());

if (attrib.has_attr_input ())
{
case AST::AttrInput::AttrInputType::LITERAL: {
visit (static_cast<AttrInputLiteral &> (attrib.get_attr_input ()));
break;
}
case AST::AttrInput::AttrInputType::MACRO: {
visit (static_cast<AttrInputMacro &> (attrib.get_attr_input ()));
break;
}
case AST::AttrInput::AttrInputType::META_ITEM: {
visit (static_cast<AttrInputMetaItemContainer &> (
attrib.get_attr_input ()));
break;
}
case AST::AttrInput::AttrInputType::TOKEN_TREE: {
visit (static_cast<DelimTokenTree &> (attrib.get_attr_input ()));
break;
}
default:
rust_unreachable ();
switch (attrib.get_attr_input ().get_attr_input_type ())
{
case AST::AttrInput::AttrInputType::LITERAL: {
visit (
static_cast<AttrInputLiteral &> (attrib.get_attr_input ()));
break;
}
case AST::AttrInput::AttrInputType::MACRO: {
visit (
static_cast<AttrInputMacro &> (attrib.get_attr_input ()));
break;
}
case AST::AttrInput::AttrInputType::META_ITEM: {
visit (static_cast<AttrInputMetaItemContainer &> (
attrib.get_attr_input ()));
break;
}
case AST::AttrInput::AttrInputType::TOKEN_TREE: {
visit (
static_cast<DelimTokenTree &> (attrib.get_attr_input ()));
break;
}
default:
rust_unreachable ();
}
}
push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
}
push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
}

void
Expand Down
10 changes: 8 additions & 2 deletions gcc/rust/ast/rust-ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,9 @@ struct Attribute

bool inner_attribute;

// Only relevant in case of a doc attribute
bool from_comment;

// TODO: maybe a variable storing whether attr input is parsed or not

public:
Expand All @@ -644,9 +647,10 @@ struct Attribute

// Constructor has pointer AttrInput for polymorphism reasons
Attribute (SimplePath path, std::unique_ptr<AttrInput> input,
location_t locus = UNDEF_LOCATION, bool inner_attribute = false)
location_t locus = UNDEF_LOCATION, bool inner_attribute = false,
bool from_comment = false)
: path (std::move (path)), attr_input (std::move (input)), locus (locus),
inner_attribute (inner_attribute)
inner_attribute (inner_attribute), from_comment (from_comment)
{}

bool is_derive () const;
Expand Down Expand Up @@ -681,6 +685,8 @@ struct Attribute
// Returns whether the attribute is considered an "empty" attribute.
bool is_empty () const { return attr_input == nullptr && path.is_empty (); }

bool is_from_comment () { return from_comment; }

location_t get_locus () const { return locus; }

AttrInput &get_attr_input () const { return *attr_input; }
Expand Down
2 changes: 2 additions & 0 deletions gcc/rust/lex/rust-token.cc
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ Token::as_string () const
return get_str ();
else
return get_str () + get_type_hint_str ();
case DOC_STRING_LITERAL:
return escape_special_chars (*std::move (str), Context::String);
default:
return get_str ();
}
Expand Down
12 changes: 10 additions & 2 deletions gcc/rust/lex/rust-token.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,10 @@ enum PrimitiveCoreType
/* Macros */ \
RS_TOKEN (DOLLAR_SIGN, "$") \
/* Doc Comments */ \
RS_TOKEN (INNER_DOC_COMMENT, "#![doc]") \
RS_TOKEN (OUTER_DOC_COMMENT, "#[doc]") \
RS_TOKEN (INNER_DOC_COMMENT, "/**!") \
RS_TOKEN (OUTER_DOC_COMMENT, "/**") \
RS_TOKEN (DOC_COMMENT_END, "*/") \
RS_TOKEN (DOC_STRING_LITERAL, "string") \
RS_TOKEN_KEYWORD_2015 (ABSTRACT, "abstract") /* unused */ \
RS_TOKEN_KEYWORD_2015 (AS, "as") \
RS_TOKEN_KEYWORD_2018 (ASYNC, "async") /* unused */ \
Expand Down Expand Up @@ -396,6 +398,11 @@ class Token
return TokenPtr (new Token (OUTER_DOC_COMMENT, locus, std::move (str)));
}

static TokenPtr make_doc_string_literal (location_t locus, std::string &&str)
{
return TokenPtr (new Token (DOC_STRING_LITERAL, locus, std::move (str)));
}

// Makes and returns a new TokenPtr of type LIFETIME.
static TokenPtr make_lifetime (location_t locus, std::string &&str)
{
Expand Down Expand Up @@ -458,6 +465,7 @@ return *str;
case BYTE_CHAR_LITERAL:
case BYTE_STRING_LITERAL:
case RAW_STRING_LITERAL:
case DOC_STRING_LITERAL:
return true;
default:
return false;
Expand Down
6 changes: 4 additions & 2 deletions gcc/rust/parse/rust-parse-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,8 @@ Parser<ManagedTokenSource>::parse_inner_attribute ()
auto path = std::move (std::get<0> (values));
auto input = std::move (std::get<1> (values));
auto loc = std::get<2> (values);
return AST::Attribute (std::move (path), std::move (input), loc, true);
return AST::Attribute (std::move (path), std::move (input), loc, true,
true);
}

if (lexer.peek_token ()->get_id () != HASH)
Expand Down Expand Up @@ -1242,7 +1243,8 @@ Parser<ManagedTokenSource>::parse_outer_attribute ()
auto path = std::move (std::get<0> (values));
auto input = std::move (std::get<1> (values));
auto loc = std::get<2> (values);
return AST::Attribute (std::move (path), std::move (input), loc, false);
return AST::Attribute (std::move (path), std::move (input), loc, false,
true);
}

if (lexer.peek_token ()->get_id () == INNER_DOC_COMMENT)
Expand Down

0 comments on commit 91d4c03

Please sign in to comment.