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:
Itamar 2021-06-26 15:34:23 +03:00 committed by Ali Mohammad Pur
parent 10cad8a874
commit d7aa831a43
Notes: sideshowbarker 2024-07-18 11:23:22 +09:00
5 changed files with 55 additions and 29 deletions

View file

@ -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();
}
}
}

View file

@ -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())

View file

@ -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 {

View file

@ -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());

View file

@ -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);