blob: c7433c9556baa0269508c1edd43ad3e59ef1ad9f [file] [log] [blame]
// 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.
#include "tools/fidl/fidlc/src/raw_ast.h"
#ifndef TOOLS_FIDL_FIDLC_SRC_TREE_VISITOR_H_
#define TOOLS_FIDL_FIDLC_SRC_TREE_VISITOR_H_
namespace fidlc {
// A TreeVisitor is an API that walks a FIDL AST. The default implementation
// does nothing but walk the AST. To make it interesting, subclass TreeVisitor
// and override behaviors with the ones you want.
class TreeVisitor {
public:
virtual ~TreeVisitor() = default;
virtual void OnSourceElementStart(const SourceElement& element) {}
virtual void OnSourceElementEnd(const SourceElement& element) {}
virtual void OnIdentifier(const std::unique_ptr<RawIdentifier>& element) {
element->Accept(this);
}
virtual void OnCompoundIdentifier(const std::unique_ptr<RawCompoundIdentifier>& element) {
element->Accept(this);
}
virtual void OnLiteral(const std::unique_ptr<RawLiteral>& element) {
switch (element->kind) {
case RawLiteral::Kind::kDocComment:
OnDocCommentLiteral(*static_cast<RawDocCommentLiteral*>(element.get()));
break;
case RawLiteral::Kind::kString:
OnStringLiteral(*static_cast<RawStringLiteral*>(element.get()));
break;
case RawLiteral::Kind::kNumeric:
OnNumericLiteral(*static_cast<RawNumericLiteral*>(element.get()));
break;
case RawLiteral::Kind::kBool:
OnBoolLiteral(*static_cast<RawBoolLiteral*>(element.get()));
break;
}
}
virtual void OnDocCommentLiteral(RawDocCommentLiteral& element) { element.Accept(this); }
virtual void OnStringLiteral(RawStringLiteral& element) { element.Accept(this); }
virtual void OnNumericLiteral(RawNumericLiteral& element) { element.Accept(this); }
virtual void OnBoolLiteral(RawBoolLiteral& element) { element.Accept(this); }
virtual void OnOrdinal64(RawOrdinal64& element) { element.Accept(this); }
#ifdef DISPATCH_TO
#error "Cannot define macro DISPATCH_TO: already defined"
#endif
#define DISPATCH_TO(TYPE, SUPERTYPE, ELEMENT) \
do { \
std::unique_ptr<SUPERTYPE>& unconst_element = \
const_cast<std::unique_ptr<SUPERTYPE>&>(element); \
Raw##TYPE* ptr = static_cast<Raw##TYPE*>(unconst_element.get()); \
std::unique_ptr<Raw##TYPE> uptr(ptr); \
On##TYPE(uptr); \
static_cast<void>(uptr.release()); \
} while (0)
virtual void OnConstant(const std::unique_ptr<RawConstant>& element) {
RawConstant::Kind kind = element->kind;
switch (kind) {
case RawConstant::Kind::kIdentifier: {
DISPATCH_TO(IdentifierConstant, RawConstant, element);
break;
}
case RawConstant::Kind::kLiteral: {
DISPATCH_TO(LiteralConstant, RawConstant, element);
break;
}
case RawConstant::Kind::kBinaryOperator: {
DISPATCH_TO(BinaryOperatorConstant, RawConstant, element);
break;
}
}
}
virtual void OnIdentifierConstant(const std::unique_ptr<RawIdentifierConstant>& element) {
element->Accept(this);
}
virtual void OnLiteralConstant(const std::unique_ptr<RawLiteralConstant>& element) {
element->Accept(this);
}
virtual void OnBinaryOperatorConstant(const std::unique_ptr<RawBinaryOperatorConstant>& element) {
element->Accept(this);
}
virtual void OnAttributeArg(const std::unique_ptr<RawAttributeArg>& element) {
element->Accept(this);
}
virtual void OnAttribute(const std::unique_ptr<RawAttribute>& element) { element->Accept(this); }
virtual void OnAttributeList(const std::unique_ptr<RawAttributeList>& element) {
element->Accept(this);
}
virtual void OnModifier(const std::unique_ptr<RawModifier>& element) { element->Accept(this); }
virtual void OnModifierList(const std::unique_ptr<RawModifierList>& element) {
element->Accept(this);
}
virtual void OnAliasDeclaration(const std::unique_ptr<RawAliasDeclaration>& element) {
element->Accept(this);
}
virtual void OnLibraryDeclaration(const std::unique_ptr<RawLibraryDeclaration>& element) {
element->Accept(this);
}
virtual void OnUsing(const std::unique_ptr<RawUsing>& element) { element->Accept(this); }
virtual void OnConstDeclaration(const std::unique_ptr<RawConstDeclaration>& element) {
element->Accept(this);
}
virtual void OnParameterList(const std::unique_ptr<RawParameterList>& element) {
element->Accept(this);
}
virtual void OnProtocolMethod(const std::unique_ptr<RawProtocolMethod>& element) {
element->Accept(this);
}
virtual void OnProtocolCompose(const std::unique_ptr<RawProtocolCompose>& element) {
element->Accept(this);
}
virtual void OnProtocolDeclaration(const std::unique_ptr<RawProtocolDeclaration>& element) {
element->Accept(this);
}
virtual void OnResourceProperty(const std::unique_ptr<RawResourceProperty>& element) {
element->Accept(this);
}
virtual void OnResourceDeclaration(const std::unique_ptr<RawResourceDeclaration>& element) {
element->Accept(this);
}
virtual void OnServiceMember(const std::unique_ptr<RawServiceMember>& element) {
element->Accept(this);
}
virtual void OnServiceDeclaration(const std::unique_ptr<RawServiceDeclaration>& element) {
element->Accept(this);
}
virtual void OnLayoutParameter(const std::unique_ptr<RawLayoutParameter>& element) {
RawLayoutParameter::Kind kind = element->kind;
switch (kind) {
case RawLayoutParameter::Kind::kIdentifier: {
DISPATCH_TO(IdentifierLayoutParameter, RawLayoutParameter, element);
break;
}
case RawLayoutParameter::Kind::kLiteral: {
DISPATCH_TO(LiteralLayoutParameter, RawLayoutParameter, element);
break;
}
case RawLayoutParameter::Kind::kType: {
DISPATCH_TO(TypeLayoutParameter, RawLayoutParameter, element);
break;
}
}
}
virtual void OnLayoutParameterList(const std::unique_ptr<RawLayoutParameterList>& element) {
element->Accept(this);
}
virtual void OnIdentifierLayoutParameter(
const std::unique_ptr<RawIdentifierLayoutParameter>& element) {
element->Accept(this);
}
virtual void OnLiteralLayoutParameter(const std::unique_ptr<RawLiteralLayoutParameter>& element) {
element->Accept(this);
}
virtual void OnTypeLayoutParameter(const std::unique_ptr<RawTypeLayoutParameter>& element) {
element->Accept(this);
}
virtual void OnLayoutMember(const std::unique_ptr<RawLayoutMember>& element) {
RawLayoutMember::Kind kind = element->kind;
switch (kind) {
case RawLayoutMember::Kind::kOrdinaled: {
DISPATCH_TO(OrdinaledLayoutMember, RawLayoutMember, element);
break;
}
case RawLayoutMember::Kind::kStruct: {
DISPATCH_TO(StructLayoutMember, RawLayoutMember, element);
break;
}
case RawLayoutMember::Kind::kValue: {
DISPATCH_TO(ValueLayoutMember, RawLayoutMember, element);
break;
}
}
}
virtual void OnOrdinaledLayoutMember(const std::unique_ptr<RawOrdinaledLayoutMember>& element) {
element->Accept(this);
}
virtual void OnStructLayoutMember(const std::unique_ptr<RawStructLayoutMember>& element) {
element->Accept(this);
}
virtual void OnValueLayoutMember(const std::unique_ptr<RawValueLayoutMember>& element) {
element->Accept(this);
}
virtual void OnLayout(const std::unique_ptr<RawLayout>& element) { element->Accept(this); }
virtual void OnLayoutReference(const std::unique_ptr<RawLayoutReference>& element) {
RawLayoutReference::Kind kind = element->kind;
switch (kind) {
case RawLayoutReference::Kind::kInline: {
DISPATCH_TO(InlineLayoutReference, RawLayoutReference, element);
break;
}
case RawLayoutReference::Kind::kNamed: {
DISPATCH_TO(NamedLayoutReference, RawLayoutReference, element);
break;
}
}
}
virtual void OnInlineLayoutReference(const std::unique_ptr<RawInlineLayoutReference>& element) {
element->Accept(this);
}
virtual void OnNamedLayoutReference(const std::unique_ptr<RawNamedLayoutReference>& element) {
element->Accept(this);
}
virtual void OnTypeConstraints(const std::unique_ptr<RawTypeConstraints>& element) {
element->Accept(this);
}
virtual void OnTypeConstructor(const std::unique_ptr<RawTypeConstructor>& element) {
element->Accept(this);
}
virtual void OnTypeDeclaration(const std::unique_ptr<RawTypeDeclaration>& element) {
element->Accept(this);
}
virtual void OnFile(const std::unique_ptr<File>& element) { element->Accept(this); }
};
#undef DISPATCH_TO
// AST node contents are not stored in declaration order in the tree, so we
// have a special visitor for code that needs to visit in declaration order.
class DeclarationOrderTreeVisitor : public TreeVisitor {
public:
void OnFile(const std::unique_ptr<File>& element) override;
void OnProtocolDeclaration(const std::unique_ptr<RawProtocolDeclaration>& element) override;
};
} // namespace fidlc
#endif // TOOLS_FIDL_FIDLC_SRC_TREE_VISITOR_H_