blob: 2917485d7ceb062bb2f3cf53ce0e323588424852 [file] [log] [blame] [edit]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file contains the implementations of the Accept methods for the AST
// nodes. Generally, all they do is invoke the appropriate TreeVisitor method
// for each field of the node.
#include "fidl/raw_ast.h"
#include <map>
#include "fidl/tree_visitor.h"
namespace fidl {
namespace raw {
bool IsAttributeListDefined(const raw::AttributeList& attributes) {
return std::visit(
fidl::utils::matchers{
[](const std::unique_ptr<raw::AttributeListOld>& e) -> bool { return e != nullptr; },
[](const std::unique_ptr<raw::AttributeListNew>& e) -> bool { return e != nullptr; },
},
attributes);
}
bool IsAttributeListNotEmpty(const raw::AttributeList& attributes) {
return std::visit(fidl::utils::matchers{
[](const std::unique_ptr<raw::AttributeListOld>& e) -> bool {
return e && !e->attributes.empty();
},
[](const std::unique_ptr<raw::AttributeListNew>& e) -> bool {
return e && !e->attributes.empty();
},
},
attributes);
}
bool IsTypeConstructorDefined(const raw::TypeConstructor& maybe_type_ctor) {
return std::visit(
fidl::utils::matchers{
[](const std::unique_ptr<raw::TypeConstructorOld>& e) -> bool { return e != nullptr; },
[](const std::unique_ptr<raw::TypeConstructorNew>& e) -> bool { return e != nullptr; },
},
maybe_type_ctor);
}
bool IsParameterListDefined(const raw::ParameterList& maybe_parameter_list) {
return std::visit([](const auto& e) -> bool { return e != nullptr; }, maybe_parameter_list);
}
SourceSpan GetSpan(const raw::ParameterList& parameter_list) {
return std::visit([](const auto& e) -> SourceSpan { return e->span(); }, parameter_list);
}
SourceElementMark::SourceElementMark(TreeVisitor* tv, const SourceElement& element)
: tv_(tv), element_(element) {
tv_->OnSourceElementStart(element_);
}
SourceElementMark::~SourceElementMark() { tv_->OnSourceElementEnd(element_); }
void Identifier::Accept(TreeVisitor* visitor) const { SourceElementMark sem(visitor, *this); }
void CompoundIdentifier::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
for (auto& i : components) {
visitor->OnIdentifier(i);
}
}
void DocCommentLiteral::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
}
void StringLiteral::Accept(TreeVisitor* visitor) const { SourceElementMark sem(visitor, *this); }
void NumericLiteral::Accept(TreeVisitor* visitor) const { SourceElementMark sem(visitor, *this); }
void TrueLiteral::Accept(TreeVisitor* visitor) const { SourceElementMark sem(visitor, *this); }
void FalseLiteral::Accept(TreeVisitor* visitor) const { SourceElementMark sem(visitor, *this); }
void IdentifierConstant::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
visitor->OnCompoundIdentifier(identifier);
}
void LiteralConstant::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
visitor->OnLiteral(literal);
}
void BinaryOperatorConstant::Accept(TreeVisitor* visitor) const {
// TODO(fxbug.dev/43758): Visit the operator as well.
SourceElementMark sem(visitor, *this);
visitor->OnConstant(left_operand);
visitor->OnConstant(right_operand);
}
void Ordinal64::Accept(TreeVisitor* visitor) const { SourceElementMark sem(visitor, *this); }
void AttributeArg::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (value) {
visitor->OnLiteral(value);
}
}
void AttributeOld::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (value) {
visitor->OnLiteral(value);
}
}
void AttributeNew::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
for (auto& i : args) {
visitor->OnAttributeArg(i);
}
}
void AttributeListOld::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
for (auto& i : attributes) {
visitor->OnAttributeOld(i);
}
}
void AttributeListNew::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
for (auto& i : attributes) {
visitor->OnAttributeNew(i);
}
}
void TypeConstructorOld::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
visitor->OnCompoundIdentifier(identifier);
if (maybe_arg_type_ctor != nullptr)
visitor->OnTypeConstructorOld(maybe_arg_type_ctor);
if (handle_subtype_identifier)
visitor->OnIdentifier(handle_subtype_identifier);
if (handle_rights != nullptr)
visitor->OnConstant(handle_rights);
if (maybe_size != nullptr)
visitor->OnConstant(maybe_size);
visitor->OnNullability(nullability);
}
void LibraryDecl::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (IsAttributeListDefined(attributes)) {
visitor->OnAttributeList(attributes);
}
visitor->OnCompoundIdentifier(path);
}
void Using::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (IsAttributeListDefined(attributes)) {
visitor->OnAttributeList(attributes);
}
visitor->OnCompoundIdentifier(using_path);
if (maybe_alias != nullptr) {
visitor->OnIdentifier(maybe_alias);
}
}
void AliasDeclaration::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (IsAttributeListDefined(attributes)) {
visitor->OnAttributeList(attributes);
}
visitor->OnIdentifier(alias);
visitor->OnTypeConstructor(type_ctor);
}
void BitsMember::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (attributes != nullptr) {
visitor->OnAttributeListOld(attributes);
}
visitor->OnIdentifier(identifier);
visitor->OnConstant(value);
}
void BitsDeclaration::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (attributes != nullptr) {
visitor->OnAttributeListOld(attributes);
}
visitor->OnIdentifier(identifier);
if (maybe_type_ctor != nullptr) {
visitor->OnTypeConstructorOld(maybe_type_ctor);
}
for (auto member = members.begin(); member != members.end(); ++member) {
visitor->OnBitsMember(*member);
}
}
void ConstDeclaration::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (IsAttributeListDefined(attributes)) {
visitor->OnAttributeList(attributes);
}
visitor->OnTypeConstructor(type_ctor);
visitor->OnIdentifier(identifier);
visitor->OnConstant(constant);
}
void EnumMember::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (attributes != nullptr) {
visitor->OnAttributeListOld(attributes);
}
visitor->OnIdentifier(identifier);
visitor->OnConstant(value);
}
void EnumDeclaration::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (attributes != nullptr) {
visitor->OnAttributeListOld(attributes);
}
visitor->OnIdentifier(identifier);
if (maybe_type_ctor != nullptr) {
visitor->OnTypeConstructorOld(maybe_type_ctor);
}
for (auto member = members.begin(); member != members.end(); ++member) {
visitor->OnEnumMember(*member);
}
}
void Parameter::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (IsAttributeListDefined(attributes)) {
visitor->OnAttributeList(attributes);
}
visitor->OnTypeConstructor(type_ctor);
visitor->OnIdentifier(identifier);
}
void ParameterListOld::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
for (auto parameter = parameter_list.begin(); parameter != parameter_list.end(); ++parameter) {
visitor->OnParameter(*parameter);
}
}
void ParameterListNew::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (type_ctor) {
visitor->OnTypeConstructorNew(type_ctor);
}
}
void ProtocolMethod::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (IsAttributeListDefined(attributes)) {
visitor->OnAttributeList(attributes);
}
visitor->OnIdentifier(identifier);
if (raw::IsParameterListDefined(maybe_request)) {
visitor->OnParameterList(maybe_request);
}
if (raw::IsParameterListDefined(maybe_response)) {
visitor->OnParameterList(maybe_response);
}
if (raw::IsTypeConstructorDefined(maybe_error_ctor)) {
visitor->OnTypeConstructor(maybe_error_ctor);
}
}
void ComposeProtocol::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
visitor->OnCompoundIdentifier(protocol_name);
}
void ProtocolDeclaration::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (IsAttributeListDefined(attributes)) {
visitor->OnAttributeList(attributes);
}
visitor->OnIdentifier(identifier);
for (auto composed_protocol = composed_protocols.begin();
composed_protocol != composed_protocols.end(); ++composed_protocol) {
visitor->OnComposeProtocol(*composed_protocol);
}
for (auto method = methods.begin(); method != methods.end(); ++method) {
visitor->OnProtocolMethod(*method);
}
}
void ResourceProperty::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (IsAttributeListDefined(attributes)) {
visitor->OnAttributeList(attributes);
}
visitor->OnTypeConstructor(type_ctor);
visitor->OnIdentifier(identifier);
}
void ResourceDeclaration::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (IsAttributeListDefined(attributes)) {
visitor->OnAttributeList(attributes);
}
visitor->OnIdentifier(identifier);
if (IsTypeConstructorDefined(maybe_type_ctor)) {
visitor->OnTypeConstructor(maybe_type_ctor);
}
for (auto property = properties.begin(); property != properties.end(); ++property) {
visitor->OnResourceProperty(*property);
}
}
void ServiceMember::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (IsAttributeListDefined(attributes)) {
visitor->OnAttributeList(attributes);
}
visitor->OnTypeConstructor(type_ctor);
visitor->OnIdentifier(identifier);
}
void ServiceDeclaration::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (IsAttributeListDefined(attributes)) {
visitor->OnAttributeList(attributes);
}
visitor->OnIdentifier(identifier);
for (auto member = members.begin(); member != members.end(); ++member) {
visitor->OnServiceMember(*member);
}
}
void StructMember::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (attributes != nullptr) {
visitor->OnAttributeListOld(attributes);
}
visitor->OnTypeConstructorOld(type_ctor);
visitor->OnIdentifier(identifier);
if (maybe_default_value != nullptr) {
visitor->OnConstant(maybe_default_value);
}
}
void StructDeclaration::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (attributes != nullptr) {
visitor->OnAttributeListOld(attributes);
}
visitor->OnIdentifier(identifier);
for (auto member = members.begin(); member != members.end(); ++member) {
visitor->OnStructMember(*member);
}
}
void TableMember::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (maybe_used != nullptr) {
if (maybe_used->attributes != nullptr) {
visitor->OnAttributeListOld(maybe_used->attributes);
}
}
visitor->OnOrdinal64(*ordinal);
if (maybe_used != nullptr) {
visitor->OnTypeConstructorOld(maybe_used->type_ctor);
visitor->OnIdentifier(maybe_used->identifier);
if (maybe_used->maybe_default_value != nullptr) {
visitor->OnConstant(maybe_used->maybe_default_value);
}
}
}
void TableDeclaration::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (attributes != nullptr) {
visitor->OnAttributeListOld(attributes);
}
visitor->OnIdentifier(identifier);
for (auto member = members.begin(); member != members.end(); ++member) {
visitor->OnTableMember(*member);
}
}
void UnionMember::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (maybe_used != nullptr) {
if (maybe_used->attributes != nullptr) {
visitor->OnAttributeListOld(maybe_used->attributes);
}
}
visitor->OnOrdinal64(*ordinal);
if (maybe_used != nullptr) {
visitor->OnTypeConstructorOld(maybe_used->type_ctor);
visitor->OnIdentifier(maybe_used->identifier);
if (maybe_used->maybe_default_value != nullptr) {
visitor->OnConstant(maybe_used->maybe_default_value);
}
}
}
void UnionDeclaration::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (attributes != nullptr) {
visitor->OnAttributeListOld(attributes);
}
visitor->OnIdentifier(identifier);
for (auto member = members.begin(); member != members.end(); ++member) {
visitor->OnUnionMember(*member);
}
}
// TODO(fxbug.dev/70247): Remove these guards and old syntax visitors.
// --- start new syntax ---
void IdentifierLayoutParameter::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
visitor->OnCompoundIdentifier(identifier);
}
void LiteralLayoutParameter::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
visitor->OnLiteralConstant(literal);
}
void TypeLayoutParameter::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
visitor->OnTypeConstructorNew(type_ctor);
}
void LayoutParameterList::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
for (auto& item : items) {
visitor->OnLayoutParameter(item);
}
}
void OrdinaledLayoutMember::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (attributes != nullptr) {
visitor->OnAttributeListNew(attributes);
}
visitor->OnOrdinal64(*ordinal);
if (type_ctor != nullptr) {
visitor->OnTypeConstructorNew(type_ctor);
}
}
void StructLayoutMember::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (attributes != nullptr) {
visitor->OnAttributeListNew(attributes);
}
visitor->OnTypeConstructorNew(type_ctor);
if (default_value != nullptr) {
visitor->OnConstant(default_value);
}
}
void ValueLayoutMember::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
if (attributes != nullptr) {
visitor->OnAttributeListNew(attributes);
}
visitor->OnConstant(value);
}
void Layout::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
// TODO(fxbug.dev/68792): Parse attributes. Interestingly, we'll only want to
// do that in cases where the layout is defined inline on a layout member.
if (subtype_ctor != nullptr) {
visitor->OnTypeConstructorNew(subtype_ctor);
}
for (auto& member : members) {
visitor->OnLayoutMember(member);
}
}
void InlineLayoutReference::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
visitor->OnLayout(layout);
}
void NamedLayoutReference::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
visitor->OnCompoundIdentifier(identifier);
}
void TypeConstraints::Accept(TreeVisitor* visitor) const {
for (auto& item : items) {
visitor->OnConstant(item);
}
}
void TypeConstructorNew::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
visitor->OnLayoutReference(layout_ref);
if (parameters != nullptr) {
visitor->OnLayoutParameterList(parameters);
}
if (constraints != nullptr) {
visitor->OnTypeConstraints(constraints);
}
}
void TypeDecl::Accept(TreeVisitor* visitor) const {
if (attributes != nullptr) {
visitor->OnAttributeListNew(attributes);
}
visitor->OnIdentifier(identifier);
visitor->OnTypeConstructorNew(type_ctor);
}
// --- end new syntax ---
void File::Accept(TreeVisitor* visitor) const {
SourceElementMark sem(visitor, *this);
visitor->OnLibraryDecl(library_decl);
for (auto& i : using_list) {
visitor->OnUsing(i);
}
for (auto& i : bits_declaration_list) {
visitor->OnBitsDeclaration(i);
}
for (auto& i : const_declaration_list) {
visitor->OnConstDeclaration(i);
}
for (auto& i : enum_declaration_list) {
visitor->OnEnumDeclaration(i);
}
for (auto& i : protocol_declaration_list) {
visitor->OnProtocolDeclaration(i);
}
for (auto& i : resource_declaration_list) {
visitor->OnResourceDeclaration(i);
}
for (auto& i : service_declaration_list) {
visitor->OnServiceDeclaration(i);
}
for (auto& i : struct_declaration_list) {
visitor->OnStructDeclaration(i);
}
for (auto& i : table_declaration_list) {
visitor->OnTableDeclaration(i);
}
for (auto& i : type_decls) {
visitor->OnTypeDecl(i);
}
for (auto& i : union_declaration_list) {
visitor->OnUnionDeclaration(i);
}
}
} // namespace raw
} // namespace fidl