mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 13:17:35 +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
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& parent = (const MemberExpression&)(*identifier.parent());
|
||||||
auto properties = properties_of_type(document, type_of(document, *parent.m_object));
|
auto properties = properties_of_type(document, type_of(document, *parent.m_object));
|
||||||
for (auto& prop : properties) {
|
for (auto& prop : properties) {
|
||||||
if (prop.name == identifier.m_name)
|
if (prop.name == identifier.m_name && prop.type->is_named_type())
|
||||||
return prop.type->m_name->full_name();
|
return ((NamedType&)prop.type).m_name->full_name();
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -240,8 +240,8 @@ String CppComprehensionEngine::type_of_variable(const Identifier& identifier) co
|
||||||
for (auto& decl : current->declarations()) {
|
for (auto& decl : current->declarations()) {
|
||||||
if (decl.is_variable_or_parameter_declaration()) {
|
if (decl.is_variable_or_parameter_declaration()) {
|
||||||
auto& var_or_param = (VariableOrParameterDeclaration&)decl;
|
auto& var_or_param = (VariableOrParameterDeclaration&)decl;
|
||||||
if (var_or_param.m_name == identifier.m_name) {
|
if (var_or_param.m_name == identifier.m_name && var_or_param.m_type->is_named_type()) {
|
||||||
return var_or_param.m_type->m_name->full_name();
|
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());
|
outln(output, "{}", to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
String Type::to_string() const
|
String NamedType::to_string() const
|
||||||
{
|
{
|
||||||
String qualifiers_string;
|
String qualifiers_string;
|
||||||
if (!m_qualifiers.is_empty())
|
if (!m_qualifiers.is_empty())
|
||||||
|
|
|
@ -198,19 +198,35 @@ class Type : public ASTNode {
|
||||||
public:
|
public:
|
||||||
virtual ~Type() override = default;
|
virtual ~Type() override = default;
|
||||||
virtual const char* class_name() const override { return "Type"; }
|
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_type() const override { return true; }
|
||||||
virtual bool is_templatized() const { return false; }
|
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)
|
Type(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)
|
||||||
: ASTNode(parent, start, end, 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;
|
RefPtr<Name> m_name;
|
||||||
Vector<StringView> m_qualifiers;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Pointer : public Type {
|
class Pointer : public Type {
|
||||||
|
|
|
@ -229,6 +229,11 @@ NonnullRefPtr<BlockStatement> Parser::parse_block_statement(ASTNode& parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::match_type()
|
bool Parser::match_type()
|
||||||
|
{
|
||||||
|
return match_named_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Parser::match_named_type()
|
||||||
{
|
{
|
||||||
save_state();
|
save_state();
|
||||||
ScopeGuard state_guard = [this] { load_state(); };
|
ScopeGuard state_guard = [this] { load_state(); };
|
||||||
|
@ -258,7 +263,7 @@ bool Parser::match_template_arguments()
|
||||||
consume();
|
consume();
|
||||||
|
|
||||||
while (!eof() && peek().type() != Token::Type::Greater) {
|
while (!eof() && peek().type() != Token::Type::Greater) {
|
||||||
if (!match_type())
|
if (!match_named_type())
|
||||||
return false;
|
return false;
|
||||||
parse_type(get_dummy_node());
|
parse_type(get_dummy_node());
|
||||||
}
|
}
|
||||||
|
@ -1148,35 +1153,38 @@ bool Parser::match_boolean_literal()
|
||||||
|
|
||||||
NonnullRefPtr<Type> Parser::parse_type(ASTNode& parent)
|
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();
|
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();
|
auto qualifiers = parse_type_qualifiers();
|
||||||
type->m_qualifiers = move(qualifiers);
|
named_type->m_qualifiers = move(qualifiers);
|
||||||
|
|
||||||
if (match_keyword("auto")) {
|
if (match_keyword("auto")) {
|
||||||
consume(Token::Type::Keyword);
|
consume(Token::Type::Keyword);
|
||||||
type->m_is_auto = true;
|
named_type->m_is_auto = true;
|
||||||
} else {
|
named_type->set_end(position());
|
||||||
|
return named_type;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
while (!eof() && peek().type() == Token::Type::Asterisk) {
|
||||||
type->set_end(position());
|
type->set_end(position());
|
||||||
auto asterisk = consume();
|
auto asterisk = consume();
|
||||||
|
@ -1184,7 +1192,7 @@ NonnullRefPtr<Type> Parser::parse_type(ASTNode& parent)
|
||||||
type->set_parent(*ptr);
|
type->set_parent(*ptr);
|
||||||
ptr->m_pointee = type;
|
ptr->m_pointee = type;
|
||||||
ptr->set_end(position());
|
ptr->set_end(position());
|
||||||
return ptr;
|
type = ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
type->set_end(position());
|
type->set_end(position());
|
||||||
|
|
|
@ -86,6 +86,7 @@ private:
|
||||||
bool match_sizeof_expression();
|
bool match_sizeof_expression();
|
||||||
bool match_braced_init_list();
|
bool match_braced_init_list();
|
||||||
bool match_type();
|
bool match_type();
|
||||||
|
bool match_named_type();
|
||||||
bool match_access_specifier();
|
bool match_access_specifier();
|
||||||
bool match_constructor(const StringView& class_name);
|
bool match_constructor(const StringView& class_name);
|
||||||
bool match_destructor(const StringView& class_name);
|
bool match_destructor(const StringView& class_name);
|
||||||
|
@ -111,6 +112,7 @@ private:
|
||||||
NonnullRefPtr<UnaryExpression> parse_unary_expression(ASTNode& parent);
|
NonnullRefPtr<UnaryExpression> parse_unary_expression(ASTNode& parent);
|
||||||
NonnullRefPtr<BooleanLiteral> parse_boolean_literal(ASTNode& parent);
|
NonnullRefPtr<BooleanLiteral> parse_boolean_literal(ASTNode& parent);
|
||||||
NonnullRefPtr<Type> parse_type(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<BinaryExpression> parse_binary_expression(ASTNode& parent, NonnullRefPtr<Expression> lhs, BinaryOp);
|
||||||
NonnullRefPtr<AssignmentExpression> parse_assignment_expression(ASTNode& parent, NonnullRefPtr<Expression> lhs, AssignmentOp);
|
NonnullRefPtr<AssignmentExpression> parse_assignment_expression(ASTNode& parent, NonnullRefPtr<Expression> lhs, AssignmentOp);
|
||||||
NonnullRefPtr<ForStatement> parse_for_statement(ASTNode& parent);
|
NonnullRefPtr<ForStatement> parse_for_statement(ASTNode& parent);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue