mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 05:20:30 +00:00
LibCpp: Differentiate between Type and NamedType
This adds a new ASTNode type called 'NamedType' which inherits from the Type node. Previously every Type node had a name field, but it was not logically accurate. For example, pointer types do not have a name (the pointed-to type may have one).
This commit is contained in:
parent
10cad8a874
commit
d7aa831a43
Notes:
sideshowbarker
2024-07-18 11:23:22 +09:00
Author: https://github.com/itamar8910 Commit: https://github.com/SerenityOS/serenity/commit/d7aa831a430 Pull-request: https://github.com/SerenityOS/serenity/pull/8260 Reviewed-by: https://github.com/alimpfard
5 changed files with 55 additions and 29 deletions
|
@ -227,8 +227,8 @@ String CppComprehensionEngine::type_of_property(const DocumentData& document, co
|
|||
auto& parent = (const MemberExpression&)(*identifier.parent());
|
||||
auto properties = properties_of_type(document, type_of(document, *parent.m_object));
|
||||
for (auto& prop : properties) {
|
||||
if (prop.name == identifier.m_name)
|
||||
return prop.type->m_name->full_name();
|
||||
if (prop.name == identifier.m_name && prop.type->is_named_type())
|
||||
return ((NamedType&)prop.type).m_name->full_name();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -240,8 +240,8 @@ String CppComprehensionEngine::type_of_variable(const Identifier& identifier) co
|
|||
for (auto& decl : current->declarations()) {
|
||||
if (decl.is_variable_or_parameter_declaration()) {
|
||||
auto& var_or_param = (VariableOrParameterDeclaration&)decl;
|
||||
if (var_or_param.m_name == identifier.m_name) {
|
||||
return var_or_param.m_type->m_name->full_name();
|
||||
if (var_or_param.m_name == identifier.m_name && var_or_param.m_type->is_named_type()) {
|
||||
return ((NamedType&)(*var_or_param.m_type)).m_name->full_name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ void Type::dump(FILE* output, size_t indent) const
|
|||
outln(output, "{}", to_string());
|
||||
}
|
||||
|
||||
String Type::to_string() const
|
||||
String NamedType::to_string() const
|
||||
{
|
||||
String qualifiers_string;
|
||||
if (!m_qualifiers.is_empty())
|
||||
|
|
|
@ -198,19 +198,35 @@ class Type : public ASTNode {
|
|||
public:
|
||||
virtual ~Type() override = default;
|
||||
virtual const char* class_name() const override { return "Type"; }
|
||||
virtual void dump(FILE* = stdout, size_t indent = 0) const override;
|
||||
virtual bool is_type() const override { return true; }
|
||||
virtual bool is_templatized() const { return false; }
|
||||
virtual String to_string() const;
|
||||
virtual bool is_named_type() const { return false; }
|
||||
virtual String to_string() const = 0;
|
||||
virtual void dump(FILE* = stdout, size_t indent = 0) const override;
|
||||
|
||||
bool m_is_auto { false };
|
||||
Vector<StringView> m_qualifiers;
|
||||
|
||||
protected:
|
||||
Type(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)
|
||||
: ASTNode(parent, start, end, filename)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class NamedType : public Type {
|
||||
public:
|
||||
virtual ~NamedType() override = default;
|
||||
virtual const char* class_name() const override { return "NamedType"; }
|
||||
virtual String to_string() const override;
|
||||
virtual bool is_named_type() const override { return true; }
|
||||
|
||||
NamedType(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)
|
||||
: Type(parent, start, end, filename)
|
||||
{
|
||||
}
|
||||
|
||||
bool m_is_auto { false };
|
||||
RefPtr<Name> m_name;
|
||||
Vector<StringView> m_qualifiers;
|
||||
};
|
||||
|
||||
class Pointer : public Type {
|
||||
|
|
|
@ -229,6 +229,11 @@ NonnullRefPtr<BlockStatement> Parser::parse_block_statement(ASTNode& parent)
|
|||
}
|
||||
|
||||
bool Parser::match_type()
|
||||
{
|
||||
return match_named_type();
|
||||
}
|
||||
|
||||
bool Parser::match_named_type()
|
||||
{
|
||||
save_state();
|
||||
ScopeGuard state_guard = [this] { load_state(); };
|
||||
|
@ -258,7 +263,7 @@ bool Parser::match_template_arguments()
|
|||
consume();
|
||||
|
||||
while (!eof() && peek().type() != Token::Type::Greater) {
|
||||
if (!match_type())
|
||||
if (!match_named_type())
|
||||
return false;
|
||||
parse_type(get_dummy_node());
|
||||
}
|
||||
|
@ -1148,35 +1153,38 @@ bool Parser::match_boolean_literal()
|
|||
|
||||
NonnullRefPtr<Type> Parser::parse_type(ASTNode& parent)
|
||||
{
|
||||
ScopeLogger<CPP_DEBUG> logger;
|
||||
LOG_SCOPE();
|
||||
|
||||
if (!match_type()) {
|
||||
if (!match_named_type()) {
|
||||
error("expected named named_type");
|
||||
auto token = consume();
|
||||
return create_ast_node<Type>(parent, token.start(), token.end());
|
||||
return create_ast_node<NamedType>(parent, token.start(), token.end());
|
||||
}
|
||||
|
||||
auto type = create_ast_node<Type>(parent, position(), {});
|
||||
auto named_type = create_ast_node<NamedType>(parent, position(), {});
|
||||
|
||||
auto qualifiers = parse_type_qualifiers();
|
||||
type->m_qualifiers = move(qualifiers);
|
||||
named_type->m_qualifiers = move(qualifiers);
|
||||
|
||||
if (match_keyword("auto")) {
|
||||
consume(Token::Type::Keyword);
|
||||
type->m_is_auto = true;
|
||||
} else {
|
||||
|
||||
if (match_keyword("struct")) {
|
||||
consume(Token::Type::Keyword); // Consume struct prefix
|
||||
}
|
||||
|
||||
if (!match_name()) {
|
||||
type->set_end(position());
|
||||
error(String::formatted("expected name instead of: {}", peek().text()));
|
||||
return type;
|
||||
}
|
||||
type->m_name = parse_name(*type);
|
||||
named_type->m_is_auto = true;
|
||||
named_type->set_end(position());
|
||||
return named_type;
|
||||
}
|
||||
|
||||
if (match_keyword("struct")) {
|
||||
consume(Token::Type::Keyword); // Consume struct prefix
|
||||
}
|
||||
|
||||
if (!match_name()) {
|
||||
named_type->set_end(position());
|
||||
error(String::formatted("expected name instead of: {}", peek().text()));
|
||||
return named_type;
|
||||
}
|
||||
named_type->m_name = parse_name(*named_type);
|
||||
|
||||
NonnullRefPtr<Type> type = named_type;
|
||||
while (!eof() && peek().type() == Token::Type::Asterisk) {
|
||||
type->set_end(position());
|
||||
auto asterisk = consume();
|
||||
|
@ -1184,7 +1192,7 @@ NonnullRefPtr<Type> Parser::parse_type(ASTNode& parent)
|
|||
type->set_parent(*ptr);
|
||||
ptr->m_pointee = type;
|
||||
ptr->set_end(position());
|
||||
return ptr;
|
||||
type = ptr;
|
||||
}
|
||||
|
||||
type->set_end(position());
|
||||
|
|
|
@ -86,6 +86,7 @@ private:
|
|||
bool match_sizeof_expression();
|
||||
bool match_braced_init_list();
|
||||
bool match_type();
|
||||
bool match_named_type();
|
||||
bool match_access_specifier();
|
||||
bool match_constructor(const StringView& class_name);
|
||||
bool match_destructor(const StringView& class_name);
|
||||
|
@ -111,6 +112,7 @@ private:
|
|||
NonnullRefPtr<UnaryExpression> parse_unary_expression(ASTNode& parent);
|
||||
NonnullRefPtr<BooleanLiteral> parse_boolean_literal(ASTNode& parent);
|
||||
NonnullRefPtr<Type> parse_type(ASTNode& parent);
|
||||
NonnullRefPtr<NamedType> parse_named_type(ASTNode& parent);
|
||||
NonnullRefPtr<BinaryExpression> parse_binary_expression(ASTNode& parent, NonnullRefPtr<Expression> lhs, BinaryOp);
|
||||
NonnullRefPtr<AssignmentExpression> parse_assignment_expression(ASTNode& parent, NonnullRefPtr<Expression> lhs, AssignmentOp);
|
||||
NonnullRefPtr<ForStatement> parse_for_statement(ASTNode& parent);
|
||||
|
|
Loading…
Reference in a new issue