LibCpp: Make the fields of AST node types private

Previously almost all fields were public and were directly accessed by
the Parser and CppComprehensionEngine.

This commit makes all fields of AST node types private. They are now
accessed via getters & setters.
This commit is contained in:
Itamar 2021-07-06 22:44:20 +03:00 committed by Andreas Kling
parent d60bd42972
commit 34fc6c7e1c
Notes: sideshowbarker 2024-07-18 09:23:13 +09:00
4 changed files with 265 additions and 119 deletions

View File

@ -117,7 +117,7 @@ Optional<Vector<GUI::AutocompleteProvider::Entry>> CppComprehensionEngine::try_a
auto partial_text = String::empty(); auto partial_text = String::empty();
if (containing_token.value().type() != Token::Type::Dot) { if (containing_token.value().type() != Token::Type::Dot) {
if (&node != parent.m_property) if (&node != parent.property())
return {}; return {};
partial_text = containing_token.value().text(); partial_text = containing_token.value().text();
} }
@ -191,15 +191,16 @@ Vector<StringView> CppComprehensionEngine::scope_of_reference_to_symbol(const AS
VERIFY(name->is_name()); VERIFY(name->is_name());
Vector<StringView> scope_parts; Vector<StringView> scope_parts;
for (auto& scope_part : name->m_scope) { for (auto& scope_part : name->scope()) {
scope_parts.append(scope_part.m_name); scope_parts.append(scope_part.name());
} }
return scope_parts; return scope_parts;
} }
Vector<GUI::AutocompleteProvider::Entry> CppComprehensionEngine::autocomplete_property(const DocumentData& document, const MemberExpression& parent, const String partial_text) const Vector<GUI::AutocompleteProvider::Entry> CppComprehensionEngine::autocomplete_property(const DocumentData& document, const MemberExpression& parent, const String partial_text) const
{ {
auto type = type_of(document, *parent.m_object); VERIFY(parent.object());
auto type = type_of(document, *parent.object());
if (type.is_null()) { if (type.is_null()) {
dbgln_if(CPP_LANGUAGE_SERVER_DEBUG, "Could not infer type of object"); dbgln_if(CPP_LANGUAGE_SERVER_DEBUG, "Could not infer type of object");
return {}; return {};
@ -220,26 +221,28 @@ bool CppComprehensionEngine::is_property(const ASTNode& node) const
return false; return false;
auto& parent = (MemberExpression&)(*node.parent()); auto& parent = (MemberExpression&)(*node.parent());
return parent.m_property.ptr() == &node; return parent.property() == &node;
} }
String CppComprehensionEngine::type_of_property(const DocumentData& document, const Identifier& identifier) const String CppComprehensionEngine::type_of_property(const DocumentData& document, const Identifier& identifier) const
{ {
auto& parent = (const MemberExpression&)(*identifier.parent()); auto& parent = (const MemberExpression&)(*identifier.parent());
auto properties = properties_of_type(document, type_of(document, *parent.m_object)); VERIFY(parent.object());
auto properties = properties_of_type(document, type_of(document, *parent.object()));
for (auto& prop : properties) { for (auto& prop : properties) {
if (prop.name.name != identifier.m_name) if (prop.name.name != identifier.name())
continue; continue;
Type* type { nullptr }; const Type* type { nullptr };
if (prop.declaration->is_variable_declaration()) { if (prop.declaration->is_variable_declaration()) {
type = ((VariableDeclaration&)*prop.declaration).m_type.ptr(); type = ((VariableDeclaration&)*prop.declaration).type();
} }
if (!type) if (!type)
continue; continue;
if (!type->is_named_type()) if (!type->is_named_type())
continue; continue;
return ((NamedType&)*type).m_name->full_name(); VERIFY(((NamedType const&)*type).name());
return ((NamedType const&)*type).name()->full_name();
} }
return {}; return {};
} }
@ -251,8 +254,9 @@ 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 && var_or_param.m_type->is_named_type()) { if (var_or_param.name() == identifier.name() && var_or_param.type()->is_named_type()) {
return ((NamedType&)(*var_or_param.m_type)).m_name->full_name(); VERIFY(((NamedType const&)(*var_or_param.type())).name());
return ((NamedType const&)(*var_or_param.type())).name()->full_name();
} }
} }
} }
@ -265,14 +269,15 @@ String CppComprehensionEngine::type_of(const DocumentData& document, const Expre
{ {
if (expression.is_member_expression()) { if (expression.is_member_expression()) {
auto& member_expression = (const MemberExpression&)expression; auto& member_expression = (const MemberExpression&)expression;
if (member_expression.m_property->is_identifier()) VERIFY(member_expression.property());
return type_of_property(document, static_cast<const Identifier&>(*member_expression.m_property)); if (member_expression.property()->is_identifier())
return type_of_property(document, static_cast<const Identifier&>(*member_expression.property()));
return {}; return {};
} }
const Identifier* identifier { nullptr }; const Identifier* identifier { nullptr };
if (expression.is_name()) { if (expression.is_name()) {
identifier = static_cast<const Name&>(expression).m_name.ptr(); identifier = static_cast<const Name&>(expression).name();
} else if (expression.is_identifier()) { } else if (expression.is_identifier()) {
identifier = &static_cast<const Identifier&>(expression); identifier = &static_cast<const Identifier&>(expression);
} else { } else {
@ -304,11 +309,11 @@ Vector<CppComprehensionEngine::Symbol> CppComprehensionEngine::properties_of_typ
VERIFY(struct_or_class.name() == type_symbol.name); VERIFY(struct_or_class.name() == type_symbol.name);
Vector<Symbol> properties; Vector<Symbol> properties;
for (auto& member : struct_or_class.m_members) { for (auto& member : struct_or_class.members()) {
Vector<StringView> scope(type_symbol.scope); Vector<StringView> scope(type_symbol.scope);
scope.append(type_symbol.name); scope.append(type_symbol.name);
// FIXME: We don't have to create the Symbol here, it should already exist in the 'm_symbol' table of some DocumentData we already parsed. // FIXME: We don't have to create the Symbol here, it should already exist in the 'm_symbol' table of some DocumentData we already parsed.
properties.append(Symbol::create(member.m_name, scope, member, Symbol::IsLocal::No)); properties.append(Symbol::create(member.name(), scope, member, Symbol::IsLocal::No));
} }
return properties; return properties;
} }
@ -435,7 +440,7 @@ static Optional<TargetDeclaration> get_target_declaration(const ASTNode& node)
return {}; return {};
} }
String name = static_cast<const Identifier&>(node).m_name; String name = static_cast<const Identifier&>(node).name();
if ((node.parent() && node.parent()->is_function_call()) || (node.parent()->is_name() && node.parent()->parent() && node.parent()->parent()->is_function_call())) { if ((node.parent() && node.parent()->is_function_call()) || (node.parent()->is_name() && node.parent()->parent() && node.parent()->parent()->is_function_call())) {
return TargetDeclaration { TargetDeclaration::Type::Function, name }; return TargetDeclaration { TargetDeclaration::Type::Function, name };
@ -614,7 +619,7 @@ Vector<StringView> CppComprehensionEngine::scope_of_node(const ASTNode& node) co
StringView containing_scope; StringView containing_scope;
if (parent_decl.is_namespace()) if (parent_decl.is_namespace())
containing_scope = static_cast<NamespaceDeclaration&>(parent_decl).m_name; containing_scope = static_cast<NamespaceDeclaration&>(parent_decl).name();
if (parent_decl.is_struct_or_class()) if (parent_decl.is_struct_or_class())
containing_scope = static_cast<StructOrClassDeclaration&>(parent_decl).name(); containing_scope = static_cast<StructOrClassDeclaration&>(parent_decl).name();
if (parent_decl.is_function()) if (parent_decl.is_function())
@ -753,7 +758,7 @@ Optional<CodeComprehensionEngine::FunctionParamsHint> CppComprehensionEngine::ge
// If we're in a function call with 0 arguments // If we're in a function call with 0 arguments
if (token.has_value() && (token->type() == Token::Type::LeftParen || token->type() == Token::Type::RightParen)) { if (token.has_value() && (token->type() == Token::Type::LeftParen || token->type() == Token::Type::RightParen)) {
return get_function_params_hint(document, *call_node, call_node->m_arguments.is_empty() ? 0 : call_node->m_arguments.size() - 1); return get_function_params_hint(document, *call_node, call_node->arguments().is_empty() ? 0 : call_node->arguments().size() - 1);
} }
} }
@ -773,15 +778,15 @@ Optional<CodeComprehensionEngine::FunctionParamsHint> CppComprehensionEngine::ge
} }
Optional<size_t> invoked_arg_index; Optional<size_t> invoked_arg_index;
for (size_t arg_index = 0; arg_index < call_node->m_arguments.size(); ++arg_index) { for (size_t arg_index = 0; arg_index < call_node->arguments().size(); ++arg_index) {
if (&call_node->m_arguments[arg_index] == node.ptr()) { if (&call_node->arguments()[arg_index] == node.ptr()) {
invoked_arg_index = arg_index; invoked_arg_index = arg_index;
break; break;
} }
} }
if (!invoked_arg_index.has_value()) { if (!invoked_arg_index.has_value()) {
dbgln_if(CPP_LANGUAGE_SERVER_DEBUG, "could not find argument index, defaulting to the last argument"); dbgln_if(CPP_LANGUAGE_SERVER_DEBUG, "could not find argument index, defaulting to the last argument");
invoked_arg_index = call_node->m_arguments.is_empty() ? 0 : call_node->m_arguments.size() - 1; invoked_arg_index = call_node->arguments().is_empty() ? 0 : call_node->arguments().size() - 1;
} }
dbgln_if(CPP_LANGUAGE_SERVER_DEBUG, "arg index: {}", invoked_arg_index.value()); dbgln_if(CPP_LANGUAGE_SERVER_DEBUG, "arg index: {}", invoked_arg_index.value());
@ -793,20 +798,22 @@ Optional<CppComprehensionEngine::FunctionParamsHint> CppComprehensionEngine::get
FunctionCall& call_node, FunctionCall& call_node,
size_t argument_index) size_t argument_index)
{ {
Identifier* callee = nullptr; const Identifier* callee = nullptr;
if (call_node.m_callee->is_identifier()) { VERIFY(call_node.callee());
callee = (Identifier*)call_node.m_callee.ptr(); if (call_node.callee()->is_identifier()) {
} else if (call_node.m_callee->is_name()) { callee = (const Identifier*)call_node.callee();
callee = ((Name&)*call_node.m_callee).m_name.ptr(); } else if (call_node.callee()->is_name()) {
} else if (call_node.m_callee->is_member_expression()) { callee = ((Name const&)*call_node.callee()).name();
auto& member_exp = ((MemberExpression&)*call_node.m_callee); } else if (call_node.callee()->is_member_expression()) {
if (member_exp.m_property->is_identifier()) { auto& member_exp = ((MemberExpression const&)*call_node.callee());
callee = (Identifier*)member_exp.m_property.ptr(); VERIFY(member_exp.property());
if (member_exp.property()->is_identifier()) {
callee = (const Identifier*)member_exp.property();
} }
} }
if (!callee) { if (!callee) {
dbgln("unexpected node type for function call: {}", call_node.m_callee->class_name()); dbgln("unexpected node type for function call: {}", call_node.callee()->class_name());
return {}; return {};
} }
VERIFY(callee); VERIFY(callee);
@ -826,7 +833,7 @@ Optional<CppComprehensionEngine::FunctionParamsHint> CppComprehensionEngine::get
FunctionParamsHint hint {}; FunctionParamsHint hint {};
hint.current_index = argument_index; hint.current_index = argument_index;
for (auto& arg : func_decl.m_parameters) { for (auto& arg : func_decl.parameters()) {
Vector<StringView> tokens_text; Vector<StringView> tokens_text;
for (auto token : document_of_declaration->parser().tokens_in_range(arg.start(), arg.end())) { for (auto token : document_of_declaration->parser().tokens_in_range(arg.start(), arg.end())) {
tokens_text.append(token.text()); tokens_text.append(token.text());

View File

@ -78,11 +78,11 @@ void Type::dump(FILE* output, size_t indent) const
String NamedType::to_string() const String NamedType::to_string() const
{ {
String qualifiers_string; String qualifiers_string;
if (!m_qualifiers.is_empty()) if (!qualifiers().is_empty())
qualifiers_string = String::formatted("[{}] ", String::join(" ", m_qualifiers)); qualifiers_string = String::formatted("[{}] ", String::join(" ", qualifiers()));
String name; String name;
if (m_is_auto) if (is_auto())
name = "auto"; name = "auto";
else else
name = m_name.is_null() ? "" : m_name->full_name(); name = m_name.is_null() ? "" : m_name->full_name();
@ -473,10 +473,10 @@ String Name::full_name() const
StringBuilder builder; StringBuilder builder;
if (!m_scope.is_empty()) { if (!m_scope.is_empty()) {
for (auto& scope : m_scope) { for (auto& scope : m_scope) {
builder.appendff("{}::", scope.m_name); builder.appendff("{}::", scope.name());
} }
} }
return String::formatted("{}{}", builder.to_string(), m_name.is_null() ? "" : m_name->m_name); return String::formatted("{}{}", builder.to_string(), m_name.is_null() ? "" : m_name->name());
} }
String TemplatizedName::full_name() const String TemplatizedName::full_name() const
@ -539,13 +539,13 @@ void Constructor::dump(FILE* output, size_t indent) const
outln(output, "C'tor"); outln(output, "C'tor");
print_indent(output, indent + 1); print_indent(output, indent + 1);
outln(output, "("); outln(output, "(");
for (const auto& arg : m_parameters) { for (const auto& arg : parameters()) {
arg.dump(output, indent + 1); arg.dump(output, indent + 1);
} }
print_indent(output, indent + 1); print_indent(output, indent + 1);
outln(output, ")"); outln(output, ")");
if (!m_definition.is_null()) { if (definition()) {
m_definition->dump(output, indent + 1); definition()->dump(output, indent + 1);
} }
} }
@ -555,13 +555,13 @@ void Destructor::dump(FILE* output, size_t indent) const
outln(output, "D'tor"); outln(output, "D'tor");
print_indent(output, indent + 1); print_indent(output, indent + 1);
outln(output, "("); outln(output, "(");
for (const auto& arg : m_parameters) { for (const auto& arg : parameters()) {
arg.dump(output, indent + 1); arg.dump(output, indent + 1);
} }
print_indent(output, indent + 1); print_indent(output, indent + 1);
outln(output, ")"); outln(output, ")");
if (!m_definition.is_null()) { if (definition()) {
m_definition->dump(output, indent + 1); definition()->dump(output, indent + 1);
} }
} }

View File

@ -89,6 +89,9 @@ public:
{ {
} }
void set_declarations(NonnullRefPtrVector<Declaration>&& declarations) { m_declarations = move(declarations); }
private:
NonnullRefPtrVector<Declaration> m_declarations; NonnullRefPtrVector<Declaration> m_declarations;
}; };
@ -119,14 +122,15 @@ public:
virtual bool is_namespace() const { return false; } virtual bool is_namespace() const { return false; }
virtual bool is_member() const { return false; } virtual bool is_member() const { return false; }
const StringView& name() const { return m_name; } const StringView& name() const { return m_name; }
void set_name(const StringView& name) { m_name = move(name); }
StringView m_name;
protected: protected:
Declaration(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename) Declaration(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)
: Statement(parent, start, end, filename) : Statement(parent, start, end, filename)
{ {
} }
StringView m_name;
}; };
class InvalidDeclaration : public Declaration { class InvalidDeclaration : public Declaration {
@ -156,7 +160,16 @@ public:
} }
virtual NonnullRefPtrVector<Declaration> declarations() const override; virtual NonnullRefPtrVector<Declaration> declarations() const override;
const Vector<StringView>& qualifiers() const { return m_qualifiers; }
void set_qualifiers(const Vector<StringView>& qualifiers) { m_qualifiers = qualifiers; }
const Type* return_type() const { return m_return_type.ptr(); }
void set_return_type(const RefPtr<Type>& return_type) { m_return_type = return_type; }
const NonnullRefPtrVector<Parameter>& parameters() const { return m_parameters; }
void set_parameters(const NonnullRefPtrVector<Parameter>& parameters) { m_parameters = parameters; }
const FunctionDefinition* definition() const { return m_definition.ptr(); }
void set_definition(RefPtr<FunctionDefinition>&& definition) { m_definition = move(definition); }
private:
Vector<StringView> m_qualifiers; Vector<StringView> m_qualifiers;
RefPtr<Type> m_return_type; RefPtr<Type> m_return_type;
NonnullRefPtrVector<Parameter> m_parameters; NonnullRefPtrVector<Parameter> m_parameters;
@ -168,13 +181,16 @@ public:
virtual ~VariableOrParameterDeclaration() override = default; virtual ~VariableOrParameterDeclaration() override = default;
virtual bool is_variable_or_parameter_declaration() const override { return true; } virtual bool is_variable_or_parameter_declaration() const override { return true; }
RefPtr<Type> m_type; void set_type(RefPtr<Type>&& type) { m_type = move(type); }
const Type* type() const { return m_type.ptr(); }
protected: protected:
VariableOrParameterDeclaration(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename) VariableOrParameterDeclaration(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)
: Declaration(parent, start, end, filename) : Declaration(parent, start, end, filename)
{ {
} }
RefPtr<Type> m_type;
}; };
class Parameter : public VariableOrParameterDeclaration { class Parameter : public VariableOrParameterDeclaration {
@ -190,6 +206,10 @@ public:
m_name = name; m_name = name;
} }
bool is_ellipsis() const { return m_is_ellipsis; }
void set_ellipsis(bool is_ellipsis) { m_is_ellipsis = is_ellipsis; }
private:
bool m_is_ellipsis { false }; bool m_is_ellipsis { false };
}; };
@ -203,14 +223,20 @@ public:
virtual String to_string() const = 0; virtual String to_string() const = 0;
virtual void dump(FILE* = stdout, size_t indent = 0) const override; virtual void dump(FILE* = stdout, size_t indent = 0) const override;
bool m_is_auto { false }; bool is_auto() const { return m_is_auto; }
Vector<StringView> m_qualifiers; void set_auto(bool is_auto) { m_is_auto = is_auto; }
Vector<StringView> const& qualifiers() const { return m_qualifiers; }
void set_qualifiers(Vector<StringView>&& qualifiers) { m_qualifiers = move(qualifiers); }
protected: 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)
{ {
} }
private:
bool m_is_auto { false };
Vector<StringView> m_qualifiers;
}; };
class NamedType : public Type { class NamedType : public Type {
@ -225,6 +251,10 @@ public:
{ {
} }
const Name* name() const { return m_name.ptr(); }
void set_name(RefPtr<Name>&& name) { m_name = move(name); }
private:
RefPtr<Name> m_name; RefPtr<Name> m_name;
}; };
@ -240,6 +270,10 @@ public:
{ {
} }
const Type* pointee() const { return m_pointee.ptr(); }
void set_pointee(RefPtr<Type>&& pointee) { m_pointee = move(pointee); }
private:
RefPtr<Type> m_pointee; RefPtr<Type> m_pointee;
}; };
@ -247,7 +281,6 @@ class FunctionDefinition : public ASTNode {
public: public:
virtual ~FunctionDefinition() override = default; virtual ~FunctionDefinition() override = default;
virtual const char* class_name() const override { return "FunctionDefinition"; } virtual const char* class_name() const override { return "FunctionDefinition"; }
NonnullRefPtrVector<Statement>& statements() { return m_statements; }
virtual void dump(FILE* = stdout, size_t indent = 0) const override; virtual void dump(FILE* = stdout, size_t indent = 0) const override;
FunctionDefinition(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename) FunctionDefinition(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)
@ -256,7 +289,10 @@ public:
} }
virtual NonnullRefPtrVector<Declaration> declarations() const override; virtual NonnullRefPtrVector<Declaration> declarations() const override;
NonnullRefPtrVector<Statement> const& statements() { return m_statements; }
void add_statement(NonnullRefPtr<Statement>&& statement) { m_statements.append(move(statement)); }
private:
NonnullRefPtrVector<Statement> m_statements; NonnullRefPtrVector<Statement> m_statements;
}; };
@ -305,6 +341,10 @@ public:
virtual bool is_variable_declaration() const override { return true; } virtual bool is_variable_declaration() const override { return true; }
const Expression* initial_value() const { return m_initial_value; }
void set_initial_value(RefPtr<Expression>&& initial_value) { m_initial_value = move(initial_value); }
private:
RefPtr<Expression> m_initial_value; RefPtr<Expression> m_initial_value;
}; };
@ -326,6 +366,10 @@ public:
virtual bool is_identifier() const override { return true; } virtual bool is_identifier() const override { return true; }
StringView const& name() const { return m_name; }
void set_name(StringView&& name) { m_name = move(name); }
private:
StringView m_name; StringView m_name;
}; };
@ -343,6 +387,13 @@ public:
} }
virtual String full_name() const; virtual String full_name() const;
const Identifier* name() const { return m_name.ptr(); }
void set_name(RefPtr<Identifier>&& name) { m_name = move(name); }
NonnullRefPtrVector<Identifier> const& scope() const { return m_scope; }
void set_scope(NonnullRefPtrVector<Identifier> scope) { m_scope = move(scope); }
void add_to_scope(NonnullRefPtr<Identifier>&& part) { m_scope.append(move(part)); }
private:
RefPtr<Identifier> m_name; RefPtr<Identifier> m_name;
NonnullRefPtrVector<Identifier> m_scope; NonnullRefPtrVector<Identifier> m_scope;
}; };
@ -359,6 +410,9 @@ public:
{ {
} }
void add_template_argument(NonnullRefPtr<Type>&& type) { m_template_arguments.append(move(type)); }
private:
NonnullRefPtrVector<Type> m_template_arguments; NonnullRefPtrVector<Type> m_template_arguments;
}; };
@ -374,6 +428,7 @@ public:
{ {
} }
private:
StringView m_value; StringView m_value;
}; };
@ -401,6 +456,7 @@ public:
{ {
} }
private:
bool m_value; bool m_value;
}; };
@ -437,6 +493,14 @@ public:
virtual const char* class_name() const override { return "BinaryExpression"; } virtual const char* class_name() const override { return "BinaryExpression"; }
virtual void dump(FILE* = stdout, size_t indent = 0) const override; virtual void dump(FILE* = stdout, size_t indent = 0) const override;
BinaryOp op() const { return m_op; }
void set_op(BinaryOp op) { m_op = op; }
Expression const* lhs() const { return m_lhs.ptr(); }
void set_lhs(RefPtr<Expression>&& e) { m_lhs = move(e); }
Expression const* rhs() const { return m_rhs.ptr(); }
void set_rhs(RefPtr<Expression>&& e) { m_rhs = move(e); }
private:
BinaryOp m_op; BinaryOp m_op;
RefPtr<Expression> m_lhs; RefPtr<Expression> m_lhs;
RefPtr<Expression> m_rhs; RefPtr<Expression> m_rhs;
@ -459,7 +523,15 @@ public:
virtual const char* class_name() const override { return "AssignmentExpression"; } virtual const char* class_name() const override { return "AssignmentExpression"; }
virtual void dump(FILE* = stdout, size_t indent = 0) const override; virtual void dump(FILE* = stdout, size_t indent = 0) const override;
AssignmentOp m_op; AssignmentOp op() const { return m_op; }
void set_op(AssignmentOp op) { m_op = op; }
const Expression* lhs() const { return m_lhs; }
void set_lhs(RefPtr<Expression>&& e) { m_lhs = move(e); }
const Expression* rhs() const { return m_rhs; }
void set_rhs(RefPtr<Expression>&& e) { m_rhs = move(e); }
private:
AssignmentOp m_op {};
RefPtr<Expression> m_lhs; RefPtr<Expression> m_lhs;
RefPtr<Expression> m_rhs; RefPtr<Expression> m_rhs;
}; };
@ -477,6 +549,13 @@ public:
virtual bool is_function_call() const override { return true; } virtual bool is_function_call() const override { return true; }
virtual bool is_templatized() const { return false; } virtual bool is_templatized() const { return false; }
const Expression* callee() const { return m_callee.ptr(); }
void set_callee(RefPtr<Expression>&& callee) { m_callee = move(callee); }
void add_argument(NonnullRefPtr<Expression>&& arg) { m_arguments.append(move(arg)); }
NonnullRefPtrVector<Expression> const& arguments() const { return m_arguments; }
private:
RefPtr<Expression> m_callee; RefPtr<Expression> m_callee;
NonnullRefPtrVector<Expression> m_arguments; NonnullRefPtrVector<Expression> m_arguments;
}; };
@ -492,6 +571,10 @@ public:
virtual const char* class_name() const override { return "StringLiteral"; } virtual const char* class_name() const override { return "StringLiteral"; }
virtual void dump(FILE* = stdout, size_t indent = 0) const override; virtual void dump(FILE* = stdout, size_t indent = 0) const override;
String const& value() const { return m_value; }
void set_value(String value) { m_value = move(value); }
private:
String m_value; String m_value;
}; };
@ -506,6 +589,10 @@ public:
} }
virtual void dump(FILE* = stdout, size_t indent = 0) const override; virtual void dump(FILE* = stdout, size_t indent = 0) const override;
const Expression* value() const { return m_value.ptr(); }
void set_value(RefPtr<Expression>&& value) { m_value = move(value); }
private:
RefPtr<Expression> m_value; RefPtr<Expression> m_value;
}; };
@ -525,7 +612,11 @@ public:
EnumClass EnumClass
}; };
Type type { Type::RegularEnum }; void set_type(Type type) { m_type = type; }
void add_entry(StringView entry) { m_entries.append(move(entry)); }
private:
Type m_type { Type::RegularEnum };
Vector<StringView> m_entries; Vector<StringView> m_entries;
}; };
@ -550,6 +641,10 @@ public:
{ {
} }
NonnullRefPtrVector<Declaration> const& members() const { return m_members; }
void set_members(NonnullRefPtrVector<Declaration>&& members) { m_members = move(members); }
private:
StructOrClassDeclaration::Type m_type; StructOrClassDeclaration::Type m_type;
NonnullRefPtrVector<Declaration> m_members; NonnullRefPtrVector<Declaration> m_members;
}; };
@ -575,6 +670,10 @@ public:
virtual const char* class_name() const override { return "UnaryExpression"; } virtual const char* class_name() const override { return "UnaryExpression"; }
virtual void dump(FILE* = stdout, size_t indent = 0) const override; virtual void dump(FILE* = stdout, size_t indent = 0) const override;
void set_op(UnaryOp op) { m_op = op; }
void set_lhs(RefPtr<Expression>&& e) { m_lhs = move(e); }
private:
UnaryOp m_op; UnaryOp m_op;
RefPtr<Expression> m_lhs; RefPtr<Expression> m_lhs;
}; };
@ -591,6 +690,12 @@ public:
virtual void dump(FILE* = stdout, size_t indent = 0) const override; virtual void dump(FILE* = stdout, size_t indent = 0) const override;
virtual bool is_member_expression() const override { return true; } virtual bool is_member_expression() const override { return true; }
const Expression* object() const { return m_object.ptr(); }
void set_object(RefPtr<Expression>&& object) { m_object = move(object); }
const Expression* property() const { return m_property.ptr(); }
void set_property(RefPtr<Expression>&& property) { m_property = move(property); }
private:
RefPtr<Expression> m_object; RefPtr<Expression> m_object;
RefPtr<Expression> m_property; RefPtr<Expression> m_property;
}; };
@ -608,6 +713,13 @@ public:
virtual NonnullRefPtrVector<Declaration> declarations() const override; virtual NonnullRefPtrVector<Declaration> declarations() const override;
void set_init(RefPtr<VariableDeclaration>&& init) { m_init = move(init); }
void set_test(RefPtr<Expression>&& test) { m_test = move(test); }
void set_update(RefPtr<Expression>&& update) { m_update = move(update); }
void set_body(RefPtr<Statement>&& body) { m_body = move(body); }
const Statement* body() const { return m_body.ptr(); }
private:
RefPtr<VariableDeclaration> m_init; RefPtr<VariableDeclaration> m_init;
RefPtr<Expression> m_test; RefPtr<Expression> m_test;
RefPtr<Expression> m_update; RefPtr<Expression> m_update;
@ -627,6 +739,9 @@ public:
virtual NonnullRefPtrVector<Declaration> declarations() const override; virtual NonnullRefPtrVector<Declaration> declarations() const override;
void add_statement(NonnullRefPtr<Statement>&& statement) { m_statements.append(move(statement)); }
private:
NonnullRefPtrVector<Statement> m_statements; NonnullRefPtrVector<Statement> m_statements;
}; };
@ -653,6 +768,14 @@ public:
virtual void dump(FILE* = stdout, size_t indent = 0) const override; virtual void dump(FILE* = stdout, size_t indent = 0) const override;
virtual NonnullRefPtrVector<Declaration> declarations() const override; virtual NonnullRefPtrVector<Declaration> declarations() const override;
void set_predicate(RefPtr<Expression>&& predicate) { m_predicate = move(predicate); }
void set_then_statement(RefPtr<Statement>&& then) { m_then = move(then); }
void set_else_statement(RefPtr<Statement>&& _else) { m_else = move(_else); }
const Statement* then_statement() const { return m_then.ptr(); }
const Statement* else_statement() const { return m_else.ptr(); }
private:
RefPtr<Expression> m_predicate; RefPtr<Expression> m_predicate;
RefPtr<Statement> m_then; RefPtr<Statement> m_then;
RefPtr<Statement> m_else; RefPtr<Statement> m_else;
@ -671,7 +794,9 @@ public:
} }
virtual NonnullRefPtrVector<Declaration> declarations() const override { return m_declarations; } virtual NonnullRefPtrVector<Declaration> declarations() const override { return m_declarations; }
void add_declaration(NonnullRefPtr<Declaration>&& declaration) { m_declarations.append(move(declaration)); }
private:
NonnullRefPtrVector<Declaration> m_declarations; NonnullRefPtrVector<Declaration> m_declarations;
}; };
@ -686,6 +811,11 @@ public:
virtual const char* class_name() const override { return "CppCastExpression"; } virtual const char* class_name() const override { return "CppCastExpression"; }
virtual void dump(FILE* = stdout, size_t indent = 0) const override; virtual void dump(FILE* = stdout, size_t indent = 0) const override;
void set_cast_type(StringView cast_type) { m_cast_type = move(cast_type); }
void set_type(NonnullRefPtr<Type>&& type) { m_type = move(type); }
void set_expression(NonnullRefPtr<Expression>&& e) { m_expression = move(e); }
private:
StringView m_cast_type; StringView m_cast_type;
RefPtr<Type> m_type; RefPtr<Type> m_type;
RefPtr<Expression> m_expression; RefPtr<Expression> m_expression;
@ -702,6 +832,10 @@ public:
virtual const char* class_name() const override { return "CStyleCastExpression"; } virtual const char* class_name() const override { return "CStyleCastExpression"; }
virtual void dump(FILE* = stdout, size_t indent = 0) const override; virtual void dump(FILE* = stdout, size_t indent = 0) const override;
void set_type(NonnullRefPtr<Type>&& type) { m_type = move(type); }
void set_expression(NonnullRefPtr<Expression>&& e) { m_expression = move(e); }
private:
RefPtr<Type> m_type; RefPtr<Type> m_type;
RefPtr<Expression> m_expression; RefPtr<Expression> m_expression;
}; };
@ -717,6 +851,9 @@ public:
virtual const char* class_name() const override { return "SizeofExpression"; } virtual const char* class_name() const override { return "SizeofExpression"; }
virtual void dump(FILE* = stdout, size_t indent = 0) const override; virtual void dump(FILE* = stdout, size_t indent = 0) const override;
void set_type(RefPtr<Type>&& type) { m_type = move(type); }
private:
RefPtr<Type> m_type; RefPtr<Type> m_type;
}; };
@ -731,6 +868,9 @@ public:
virtual const char* class_name() const override { return "BracedInitList"; } virtual const char* class_name() const override { return "BracedInitList"; }
virtual void dump(FILE* = stdout, size_t indent = 0) const override; virtual void dump(FILE* = stdout, size_t indent = 0) const override;
void add_expression(NonnullRefPtr<Expression>&& exp) { m_expressions.append(move(exp)); }
private:
NonnullRefPtrVector<Expression> m_expressions; NonnullRefPtrVector<Expression> m_expressions;
}; };

View File

@ -51,7 +51,7 @@ NonnullRefPtr<TranslationUnit> Parser::parse()
if (m_tokens.is_empty()) if (m_tokens.is_empty())
return create_root_ast_node({}, {}); return create_root_ast_node({}, {});
auto unit = create_root_ast_node(m_tokens.first().start(), m_tokens.last().end()); auto unit = create_root_ast_node(m_tokens.first().start(), m_tokens.last().end());
unit->m_declarations = parse_declarations_in_translation_unit(*unit); unit->set_declarations(parse_declarations_in_translation_unit(*unit));
return unit; return unit;
} }
@ -119,16 +119,16 @@ NonnullRefPtr<FunctionDeclaration> Parser::parse_function_declaration(ASTNode& p
{ {
auto func = create_ast_node<FunctionDeclaration>(parent, position(), {}); auto func = create_ast_node<FunctionDeclaration>(parent, position(), {});
func->m_qualifiers = parse_function_qualifiers(); func->set_qualifiers(parse_function_qualifiers());
func->m_return_type = parse_type(*func); func->set_return_type(parse_type(*func));
auto function_name = consume(Token::Type::Identifier); auto function_name = consume(Token::Type::Identifier);
func->m_name = text_of_token(function_name); func->set_name(text_of_token(function_name));
consume(Token::Type::LeftParen); consume(Token::Type::LeftParen);
auto parameters = parse_parameter_list(*func); auto parameters = parse_parameter_list(*func);
if (parameters.has_value()) if (parameters.has_value())
func->m_parameters = move(parameters.value()); func->set_parameters(parameters.value());
consume(Token::Type::RightParen); consume(Token::Type::RightParen);
@ -144,7 +144,7 @@ NonnullRefPtr<FunctionDeclaration> Parser::parse_function_declaration(ASTNode& p
consume(Token::Type::Semicolon); consume(Token::Type::Semicolon);
} }
func->m_definition = move(body); func->set_definition(move(body));
func->set_end(func_end); func->set_end(func_end);
return func; return func;
} }
@ -155,7 +155,7 @@ NonnullRefPtr<FunctionDefinition> Parser::parse_function_definition(ASTNode& par
auto func = create_ast_node<FunctionDefinition>(parent, position(), {}); auto func = create_ast_node<FunctionDefinition>(parent, position(), {});
consume(Token::Type::LeftCurly); consume(Token::Type::LeftCurly);
while (!eof() && peek().type() != Token::Type::RightCurly) { while (!eof() && peek().type() != Token::Type::RightCurly) {
func->statements().append(parse_statement(func)); func->add_statement(parse_statement(func));
} }
func->set_end(position()); func->set_end(position());
if (!eof()) if (!eof())
@ -221,7 +221,7 @@ NonnullRefPtr<BlockStatement> Parser::parse_block_statement(ASTNode& parent)
auto block_statement = create_ast_node<BlockStatement>(parent, position(), {}); auto block_statement = create_ast_node<BlockStatement>(parent, position(), {});
consume(Token::Type::LeftCurly); consume(Token::Type::LeftCurly);
while (!eof() && peek().type() != Token::Type::RightCurly) { while (!eof() && peek().type() != Token::Type::RightCurly) {
block_statement->m_statements.append(parse_statement(*block_statement)); block_statement->add_statement(parse_statement(*block_statement));
} }
consume(Token::Type::RightCurly); consume(Token::Type::RightCurly);
block_statement->set_end(position()); block_statement->set_end(position());
@ -330,7 +330,7 @@ NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration(ASTNode& p
var->set_end(position()); var->set_end(position());
return var; return var;
} }
var->m_type = parse_type(var); var->set_type(parse_type(var));
auto identifier_token = consume(Token::Type::Identifier); auto identifier_token = consume(Token::Type::Identifier);
RefPtr<Expression> initial_value; RefPtr<Expression> initial_value;
@ -347,8 +347,8 @@ NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration(ASTNode& p
consume(Token::Type::Semicolon); consume(Token::Type::Semicolon);
var->set_end(position()); var->set_end(position());
var->m_name = text_of_token(identifier_token); var->set_name(text_of_token(identifier_token));
var->m_initial_value = move(initial_value); var->set_initial_value(move(initial_value));
return var; return var;
} }
@ -510,9 +510,9 @@ NonnullRefPtr<UnaryExpression> Parser::parse_unary_expression(ASTNode& parent)
default: default:
break; break;
} }
unary_exp->m_op = op; unary_exp->set_op(op);
auto lhs = parse_expression(*unary_exp); auto lhs = parse_expression(*unary_exp);
unary_exp->m_lhs = lhs; unary_exp->set_lhs(lhs);
unary_exp->set_end(lhs->end()); unary_exp->set_end(lhs->end());
return unary_exp; return unary_exp;
} }
@ -573,9 +573,9 @@ NonnullRefPtr<Expression> Parser::parse_secondary_expression(ASTNode& parent, No
consume(); consume();
auto exp = create_ast_node<MemberExpression>(parent, lhs->start(), {}); auto exp = create_ast_node<MemberExpression>(parent, lhs->start(), {});
lhs->set_parent(*exp); lhs->set_parent(*exp);
exp->m_object = move(lhs); exp->set_object(move(lhs));
auto identifier_token = consume(Token::Type::Identifier); auto identifier_token = consume(Token::Type::Identifier);
exp->m_property = create_ast_node<Identifier>(*exp, identifier_token.start(), identifier_token.end(), identifier_token.text()); exp->set_property(create_ast_node<Identifier>(*exp, identifier_token.start(), identifier_token.end(), identifier_token.text()));
exp->set_end(position()); exp->set_end(position());
return exp; return exp;
} }
@ -583,9 +583,9 @@ NonnullRefPtr<Expression> Parser::parse_secondary_expression(ASTNode& parent, No
consume(); consume();
auto func = create_ast_node<FunctionCall>(parent, lhs->start(), {}); auto func = create_ast_node<FunctionCall>(parent, lhs->start(), {});
lhs->set_parent(*func); lhs->set_parent(*func);
func->m_callee = lhs; func->set_callee(move(lhs));
while (peek().type() != Token::Type::RightParen && !eof()) { while (peek().type() != Token::Type::RightParen && !eof()) {
func->m_arguments.append(parse_expression(*func)); func->add_argument(parse_expression(*func));
if (peek().type() == Token::Type::Comma) if (peek().type() == Token::Type::Comma)
consume(Token::Type::Comma); consume(Token::Type::Comma);
} }
@ -606,11 +606,11 @@ NonnullRefPtr<BinaryExpression> Parser::parse_binary_expression(ASTNode& parent,
consume(); // Operator consume(); // Operator
auto exp = create_ast_node<BinaryExpression>(parent, lhs->start(), {}); auto exp = create_ast_node<BinaryExpression>(parent, lhs->start(), {});
lhs->set_parent(*exp); lhs->set_parent(*exp);
exp->m_op = op; exp->set_op(op);
exp->m_lhs = move(lhs); exp->set_lhs(move(lhs));
auto rhs = parse_expression(exp); auto rhs = parse_expression(exp);
exp->set_end(rhs->end()); exp->set_end(rhs->end());
exp->m_rhs = move(rhs); exp->set_rhs(move(rhs));
return exp; return exp;
} }
@ -619,11 +619,11 @@ NonnullRefPtr<AssignmentExpression> Parser::parse_assignment_expression(ASTNode&
consume(); // Operator consume(); // Operator
auto exp = create_ast_node<AssignmentExpression>(parent, lhs->start(), {}); auto exp = create_ast_node<AssignmentExpression>(parent, lhs->start(), {});
lhs->set_parent(*exp); lhs->set_parent(*exp);
exp->m_op = op; exp->set_op(op);
exp->m_lhs = move(lhs); exp->set_lhs(move(lhs));
auto rhs = parse_expression(exp); auto rhs = parse_expression(exp);
exp->set_end(rhs->end()); exp->set_end(rhs->end());
exp->m_rhs = move(rhs); exp->set_rhs(move(rhs));
return exp; return exp;
} }
@ -747,7 +747,7 @@ Optional<NonnullRefPtrVector<Parameter>> Parser::parse_parameter_list(ASTNode& p
consume(Token::Type::Dot); consume(Token::Type::Dot);
consume(Token::Type::Dot); consume(Token::Type::Dot);
auto last_dot = consume(Token::Type::Dot); auto last_dot = consume(Token::Type::Dot);
param->m_is_ellipsis = true; param->set_ellipsis(true);
param->set_end(last_dot.end()); param->set_end(last_dot.end());
parameters.append(move(param)); parameters.append(move(param));
} else { } else {
@ -763,7 +763,7 @@ Optional<NonnullRefPtrVector<Parameter>> Parser::parse_parameter_list(ASTNode& p
auto param = create_ast_node<Parameter>(parent, type->start(), name_identifier.has_value() ? name_identifier.value().end() : type->end(), name); auto param = create_ast_node<Parameter>(parent, type->start(), name_identifier.has_value() ? name_identifier.value().end() : type->end(), name);
param->m_type = move(type); param->set_type(move(type));
parameters.append(move(param)); parameters.append(move(param));
} }
@ -1042,7 +1042,7 @@ NonnullRefPtr<StringLiteral> Parser::parse_string_literal(ASTNode& parent)
auto text = text_in_range(start_token.start(), end_token.end()); auto text = text_in_range(start_token.start(), end_token.end());
auto string_literal = create_ast_node<StringLiteral>(parent, start_token.start(), end_token.end()); auto string_literal = create_ast_node<StringLiteral>(parent, start_token.start(), end_token.end());
string_literal->m_value = text; string_literal->set_value(move(text));
return string_literal; return string_literal;
} }
@ -1052,8 +1052,7 @@ NonnullRefPtr<ReturnStatement> Parser::parse_return_statement(ASTNode& parent)
auto return_statement = create_ast_node<ReturnStatement>(parent, position(), {}); auto return_statement = create_ast_node<ReturnStatement>(parent, position(), {});
consume(Token::Type::Keyword); consume(Token::Type::Keyword);
if (!peek(Token::Type::Semicolon).has_value()) { if (!peek(Token::Type::Semicolon).has_value()) {
auto expression = parse_expression(*return_statement); return_statement->set_value(parse_expression(*return_statement));
return_statement->m_value = expression;
} }
return_statement->set_end(position()); return_statement->set_end(position());
return return_statement; return return_statement;
@ -1067,16 +1066,16 @@ NonnullRefPtr<EnumDeclaration> Parser::parse_enum_declaration(ASTNode& parent)
if (match_keyword("class")) { if (match_keyword("class")) {
consume(Token::Type::Keyword); consume(Token::Type::Keyword);
enum_decl->type = EnumDeclaration::Type::EnumClass; enum_decl->set_type(EnumDeclaration::Type::EnumClass);
} else { } else {
enum_decl->type = EnumDeclaration::Type::RegularEnum; enum_decl->set_type(EnumDeclaration::Type::RegularEnum);
} }
auto name_token = consume(Token::Type::Identifier); auto name_token = consume(Token::Type::Identifier);
enum_decl->m_name = text_of_token(name_token); enum_decl->set_name(text_of_token(name_token));
consume(Token::Type::LeftCurly); consume(Token::Type::LeftCurly);
while (!eof() && peek().type() != Token::Type::RightCurly) { while (!eof() && peek().type() != Token::Type::RightCurly) {
enum_decl->m_entries.append(text_of_token(consume(Token::Type::Identifier))); enum_decl->add_entry(text_of_token(consume(Token::Type::Identifier)));
if (peek().type() != Token::Type::Comma) { if (peek().type() != Token::Type::Comma) {
break; break;
} }
@ -1129,12 +1128,12 @@ NonnullRefPtr<StructOrClassDeclaration> Parser::parse_class_declaration(ASTNode&
auto decl = create_ast_node<StructOrClassDeclaration>(parent, position(), {}, type); auto decl = create_ast_node<StructOrClassDeclaration>(parent, position(), {}, type);
auto name_token = consume(Token::Type::Identifier); auto name_token = consume(Token::Type::Identifier);
decl->m_name = text_of_token(name_token); decl->set_name(text_of_token(name_token));
consume(Token::Type::LeftCurly); consume(Token::Type::LeftCurly);
while (!eof() && peek().type() != Token::Type::RightCurly) { while (!eof() && peek().type() != Token::Type::RightCurly) {
decl->m_members = parse_class_members(*decl); decl->set_members(parse_class_members(*decl));
} }
consume(Token::Type::RightCurly); consume(Token::Type::RightCurly);
@ -1175,11 +1174,11 @@ NonnullRefPtr<Type> Parser::parse_type(ASTNode& parent)
auto named_type = create_ast_node<NamedType>(parent, position(), {}); auto named_type = create_ast_node<NamedType>(parent, position(), {});
auto qualifiers = parse_type_qualifiers(); auto qualifiers = parse_type_qualifiers();
named_type->m_qualifiers = move(qualifiers); named_type->set_qualifiers(move(qualifiers));
if (match_keyword("auto")) { if (match_keyword("auto")) {
consume(Token::Type::Keyword); consume(Token::Type::Keyword);
named_type->m_is_auto = true; named_type->set_auto(true);
named_type->set_end(position()); named_type->set_end(position());
return named_type; return named_type;
} }
@ -1193,7 +1192,7 @@ NonnullRefPtr<Type> Parser::parse_type(ASTNode& parent)
error(String::formatted("expected name instead of: {}", peek().text())); error(String::formatted("expected name instead of: {}", peek().text()));
return named_type; return named_type;
} }
named_type->m_name = parse_name(*named_type); named_type->set_name(parse_name(*named_type));
NonnullRefPtr<Type> type = named_type; NonnullRefPtr<Type> type = named_type;
while (!eof() && peek().type() == Token::Type::Asterisk) { while (!eof() && peek().type() == Token::Type::Asterisk) {
@ -1201,7 +1200,7 @@ NonnullRefPtr<Type> Parser::parse_type(ASTNode& parent)
auto asterisk = consume(); auto asterisk = consume();
auto ptr = create_ast_node<Pointer>(parent, type->start(), asterisk.end()); auto ptr = create_ast_node<Pointer>(parent, type->start(), asterisk.end());
type->set_parent(*ptr); type->set_parent(*ptr);
ptr->m_pointee = type; ptr->set_pointee(type);
ptr->set_end(position()); ptr->set_end(position());
type = ptr; type = ptr;
} }
@ -1217,20 +1216,20 @@ NonnullRefPtr<ForStatement> Parser::parse_for_statement(ASTNode& parent)
consume(Token::Type::Keyword); consume(Token::Type::Keyword);
consume(Token::Type::LeftParen); consume(Token::Type::LeftParen);
if (peek().type() != Token::Type::Semicolon) if (peek().type() != Token::Type::Semicolon)
for_statement->m_init = parse_variable_declaration(*for_statement, false); for_statement->set_init(parse_variable_declaration(*for_statement, false));
consume(Token::Type::Semicolon); consume(Token::Type::Semicolon);
if (peek().type() != Token::Type::Semicolon) if (peek().type() != Token::Type::Semicolon)
for_statement->m_test = parse_expression(*for_statement); for_statement->set_test(parse_expression(*for_statement));
consume(Token::Type::Semicolon); consume(Token::Type::Semicolon);
if (peek().type() != Token::Type::RightParen) if (peek().type() != Token::Type::RightParen)
for_statement->m_update = parse_expression(*for_statement); for_statement->set_update(parse_expression(*for_statement));
consume(Token::Type::RightParen); consume(Token::Type::RightParen);
for_statement->m_body = parse_statement(*for_statement); for_statement->set_body(parse_statement(*for_statement));
for_statement->set_end(for_statement->m_body->end()); for_statement->set_end(for_statement->body()->end());
return for_statement; return for_statement;
} }
@ -1240,15 +1239,15 @@ NonnullRefPtr<IfStatement> Parser::parse_if_statement(ASTNode& parent)
auto if_statement = create_ast_node<IfStatement>(parent, position(), {}); auto if_statement = create_ast_node<IfStatement>(parent, position(), {});
consume(Token::Type::Keyword); consume(Token::Type::Keyword);
consume(Token::Type::LeftParen); consume(Token::Type::LeftParen);
if_statement->m_predicate = parse_expression(*if_statement); if_statement->set_predicate(parse_expression(*if_statement));
consume(Token::Type::RightParen); consume(Token::Type::RightParen);
if_statement->m_then = parse_statement(*if_statement); if_statement->set_then_statement(parse_statement(*if_statement));
if (match_keyword("else")) { if (match_keyword("else")) {
consume(Token::Type::Keyword); consume(Token::Type::Keyword);
if_statement->m_else = parse_statement(*if_statement); if_statement->set_else_statement(parse_statement(*if_statement));
if_statement->set_end(if_statement->m_else->end()); if_statement->set_end(if_statement->else_statement()->end());
} else { } else {
if_statement->set_end(if_statement->m_then->end()); if_statement->set_end(if_statement->then_statement()->end());
} }
return if_statement; return if_statement;
} }
@ -1340,11 +1339,11 @@ NonnullRefPtr<NamespaceDeclaration> Parser::parse_namespace_declaration(ASTNode&
consume(Token::Type::Keyword); consume(Token::Type::Keyword);
auto name_token = consume(Token::Type::Identifier); auto name_token = consume(Token::Type::Identifier);
namespace_decl->m_name = name_token.text(); namespace_decl->set_name(name_token.text());
if (peek().type() == Token::Type::ColonColon) { if (peek().type() == Token::Type::ColonColon) {
consume(Token::Type::ColonColon); consume(Token::Type::ColonColon);
namespace_decl->m_declarations.append(parse_namespace_declaration(*namespace_decl, true)); namespace_decl->add_declaration(parse_namespace_declaration(*namespace_decl, true));
namespace_decl->set_end(position()); namespace_decl->set_end(position());
return namespace_decl; return namespace_decl;
} }
@ -1353,7 +1352,7 @@ NonnullRefPtr<NamespaceDeclaration> Parser::parse_namespace_declaration(ASTNode&
while (!eof() && peek().type() != Token::Type::RightCurly) { while (!eof() && peek().type() != Token::Type::RightCurly) {
auto declaration = parse_single_declaration_in_translation_unit(*namespace_decl); auto declaration = parse_single_declaration_in_translation_unit(*namespace_decl);
if (declaration) { if (declaration) {
namespace_decl->m_declarations.append(declaration.release_nonnull()); namespace_decl->add_declaration(declaration.release_nonnull());
} else { } else {
error("unexpected token"); error("unexpected token");
consume(); consume();
@ -1376,13 +1375,13 @@ NonnullRefPtr<Name> Parser::parse_name(ASTNode& parent)
NonnullRefPtr<Name> name_node = create_ast_node<Name>(parent, position(), {}); NonnullRefPtr<Name> name_node = create_ast_node<Name>(parent, position(), {});
while (!eof() && (peek().type() == Token::Type::Identifier || peek().type() == Token::Type::KnownType) && peek(1).type() == Token::Type::ColonColon) { while (!eof() && (peek().type() == Token::Type::Identifier || peek().type() == Token::Type::KnownType) && peek(1).type() == Token::Type::ColonColon) {
auto token = consume(); auto token = consume();
name_node->m_scope.append(create_ast_node<Identifier>(*name_node, token.start(), token.end(), token.text())); name_node->add_to_scope(create_ast_node<Identifier>(*name_node, token.start(), token.end(), token.text()));
consume(Token::Type::ColonColon); consume(Token::Type::ColonColon);
} }
if (peek().type() == Token::Type::Identifier || peek().type() == Token::Type::KnownType) { if (peek().type() == Token::Type::Identifier || peek().type() == Token::Type::KnownType) {
auto token = consume(); auto token = consume();
name_node->m_name = create_ast_node<Identifier>(*name_node, token.start(), token.end(), token.text()); name_node->set_name(create_ast_node<Identifier>(*name_node, token.start(), token.end(), token.text()));
} else { } else {
name_node->set_end(position()); name_node->set_end(position());
return name_node; return name_node;
@ -1391,12 +1390,12 @@ NonnullRefPtr<Name> Parser::parse_name(ASTNode& parent)
if (match_template_arguments()) { if (match_template_arguments()) {
consume(Token::Type::Less); consume(Token::Type::Less);
NonnullRefPtr<TemplatizedName> templatized_name = create_ast_node<TemplatizedName>(parent, name_node->start(), {}); NonnullRefPtr<TemplatizedName> templatized_name = create_ast_node<TemplatizedName>(parent, name_node->start(), {});
templatized_name->m_name = move(name_node->m_name); templatized_name->set_name(name_node->name());
templatized_name->m_scope = move(name_node->m_scope); templatized_name->set_scope(name_node->scope());
name_node->set_end(position()); name_node->set_end(position());
name_node = templatized_name; name_node = templatized_name;
while (peek().type() != Token::Type::Greater && !eof()) { while (peek().type() != Token::Type::Greater && !eof()) {
templatized_name->m_template_arguments.append(parse_type(*templatized_name)); templatized_name->add_template_argument(parse_type(*templatized_name));
if (peek().type() == Token::Type::Comma) if (peek().type() == Token::Type::Comma)
consume(Token::Type::Comma); consume(Token::Type::Comma);
} }
@ -1448,9 +1447,9 @@ NonnullRefPtr<CStyleCastExpression> Parser::parse_c_style_cast_expression(ASTNod
auto parse_exp = create_ast_node<CStyleCastExpression>(parent, position(), {}); auto parse_exp = create_ast_node<CStyleCastExpression>(parent, position(), {});
consume(Token::Type::LeftParen); consume(Token::Type::LeftParen);
parse_exp->m_type = parse_type(*parse_exp); parse_exp->set_type(parse_type(*parse_exp));
consume(Token::Type::RightParen); consume(Token::Type::RightParen);
parse_exp->m_expression = parse_expression(*parse_exp); parse_exp->set_expression(parse_expression(*parse_exp));
parse_exp->set_end(position()); parse_exp->set_end(position());
return parse_exp; return parse_exp;
@ -1460,14 +1459,14 @@ NonnullRefPtr<CppCastExpression> Parser::parse_cpp_cast_expression(ASTNode& pare
{ {
auto cast_expression = create_ast_node<CppCastExpression>(parent, position(), {}); auto cast_expression = create_ast_node<CppCastExpression>(parent, position(), {});
cast_expression->m_cast_type = consume(Token::Type::Keyword).text(); cast_expression->set_cast_type(consume(Token::Type::Keyword).text());
consume(Token::Type::Less); consume(Token::Type::Less);
cast_expression->m_type = parse_type(*cast_expression); cast_expression->set_type(parse_type(*cast_expression));
consume(Token::Type::Greater); consume(Token::Type::Greater);
consume(Token::Type::LeftParen); consume(Token::Type::LeftParen);
cast_expression->m_expression = parse_expression(*cast_expression); cast_expression->set_expression(parse_expression(*cast_expression));
consume(Token::Type::RightParen); consume(Token::Type::RightParen);
cast_expression->set_end(position()); cast_expression->set_end(position());
@ -1485,7 +1484,7 @@ NonnullRefPtr<SizeofExpression> Parser::parse_sizeof_expression(ASTNode& parent)
auto exp = create_ast_node<SizeofExpression>(parent, position(), {}); auto exp = create_ast_node<SizeofExpression>(parent, position(), {});
consume(Token::Type::Keyword); consume(Token::Type::Keyword);
consume(Token::Type::LeftParen); consume(Token::Type::LeftParen);
exp->m_type = parse_type(parent); exp->set_type(parse_type(parent));
consume(Token::Type::RightParen); consume(Token::Type::RightParen);
exp->set_end(position()); exp->set_end(position());
return exp; return exp;
@ -1502,7 +1501,7 @@ NonnullRefPtr<BracedInitList> Parser::parse_braced_init_list(ASTNode& parent)
consume(Token::Type::LeftCurly); consume(Token::Type::LeftCurly);
while (!eof() && peek().type() != Token::Type::RightCurly) { while (!eof() && peek().type() != Token::Type::RightCurly) {
init_list->m_expressions.append(parse_expression(*init_list)); init_list->add_expression(parse_expression(*init_list));
} }
consume(Token::Type::RightCurly); consume(Token::Type::RightCurly);
init_list->set_end(position()); init_list->set_end(position());
@ -1592,7 +1591,7 @@ void Parser::parse_constructor_or_destructor_impl(FunctionDeclaration& func, Cto
if (name_token.type() != Token::Type::Identifier && name_token.type() != Token::Type::KnownType) { if (name_token.type() != Token::Type::Identifier && name_token.type() != Token::Type::KnownType) {
error("Unexpected constructor name"); error("Unexpected constructor name");
} }
func.m_name = name_token.text(); func.set_name(name_token.text());
consume(Token::Type::LeftParen); consume(Token::Type::LeftParen);
auto parameters = parse_parameter_list(func); auto parameters = parse_parameter_list(func);
@ -1600,7 +1599,7 @@ void Parser::parse_constructor_or_destructor_impl(FunctionDeclaration& func, Cto
if (type == CtorOrDtor::Dtor && !parameters->is_empty()) if (type == CtorOrDtor::Dtor && !parameters->is_empty())
error("Destructor declaration that takes parameters"); error("Destructor declaration that takes parameters");
else else
func.m_parameters = move(parameters.value()); func.set_parameters(parameters.value());
} }
consume(Token::Type::RightParen); consume(Token::Type::RightParen);
@ -1619,7 +1618,7 @@ void Parser::parse_constructor_or_destructor_impl(FunctionDeclaration& func, Cto
consume(Token::Type::Semicolon); consume(Token::Type::Semicolon);
} }
func.m_definition = move(body); func.set_definition(move(body));
func.set_end(ctor_end); func.set_end(ctor_end);
} }