blob: 1c5700f0a71a60739c8a371136476f106f299724 [file] [log] [blame]
// Copyright 2017 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.
#ifndef TOOLS_FIDL_FIDLC_INCLUDE_FIDL_RAW_AST_H_
#define TOOLS_FIDL_FIDLC_INCLUDE_FIDL_RAW_AST_H_
#include <zircon/assert.h>
#include <memory>
#include <optional>
#include <utility>
#include <variant>
#include <vector>
#include "source_span.h"
#include "token.h"
#include "types.h"
#include "utils.h"
// ASTs fresh out of the oven. This is a tree-shaped bunch of nodes
// pretty much exactly corresponding to the grammar of a single fidl
// file. File is the root of the tree, and consists of lists of
// Declarations, and so on down to individual SourceSpans.
// See
// https://fuchsia.dev/fuchsia-src/development/languages/fidl/reference/compiler#compiler_internals
// for additional context
// Each node owns its children via unique_ptr and vector. All tokens
// here, like everywhere in the fidl compiler, are backed by a string
// view whose contents are owned by a SourceManager.
// This class has a tight coupling with the TreeVisitor class. Each node has a
// corresponding method in that class. Each node type also has an Accept()
// method to help visitors visit the node. When you add a new node, or add a
// field to an existing node, you must ensure the Accept method works.
// A raw::File is produced by parsing a token stream. All of the
// Files in a library are then flattened out into a Library.
namespace fidl::raw {
// In order to be able to associate AST nodes with their original source, each
// node is a SourceElement, which contains information about the original
// source. The AST has a start token, whose previous_end field points to the
// end of the previous AST node, and an end token, which points to the end of
// this syntactic element.
//
// Note: The file may have a tail of whitespace / comment text not explicitly
// associated with any node. In order to reconstruct that text, raw::File
// contains an end token; the previous_end field of that token points to the end
// of the last interesting token.
class TreeVisitor;
class SourceElement {
public:
explicit SourceElement(SourceElement const& element)
: start_(element.start_), end_(element.end_) {}
explicit SourceElement(Token start, Token end) : start_(start), end_(end) {}
bool has_span() const {
return start_.span().valid() && end_.span().valid() &&
&start_.span().source_file() == &end_.span().source_file();
}
SourceSpan span() const {
if (!start_.span().valid() || !end_.span().valid()) {
return SourceSpan();
}
ZX_ASSERT(has_span());
const char* start_pos = start_.span().data().data();
const char* end_pos = end_.span().data().data() + end_.span().data().length();
return SourceSpan(std::string_view(start_pos, end_pos - start_pos),
start_.span().source_file());
}
std::string copy_to_str() const {
const char* start_pos = start_.span().data().data();
const char* end_pos = end_.span().data().data() + end_.span().data().length();
return std::string(start_pos, end_pos);
}
void update_span(SourceElement const& element) {
start_ = element.start_;
end_ = element.end_;
}
virtual ~SourceElement() {}
Token start_;
Token end_;
};
class SourceElementMark {
public:
SourceElementMark(TreeVisitor* tv, const SourceElement& element);
~SourceElementMark();
private:
TreeVisitor* tv_;
const SourceElement& element_;
};
class Identifier final : public SourceElement {
public:
explicit Identifier(SourceElement const& element) : SourceElement(element) {}
void Accept(TreeVisitor* visitor) const;
};
class CompoundIdentifier final : public SourceElement {
public:
CompoundIdentifier(SourceElement const& element,
std::vector<std::unique_ptr<Identifier>> components)
: SourceElement(element), components(std::move(components)) {}
void Accept(TreeVisitor* visitor) const;
std::vector<std::unique_ptr<Identifier>> components;
};
class Literal : public SourceElement {
public:
enum struct Kind {
kDocComment,
kString,
kNumeric,
kBool,
};
explicit Literal(SourceElement const& element, Kind kind) : SourceElement(element), kind(kind) {}
virtual ~Literal() {}
const Kind kind;
};
class DocCommentLiteral final : public Literal {
public:
explicit DocCommentLiteral(SourceElement const& element) : Literal(element, Kind::kDocComment) {}
void Accept(TreeVisitor* visitor) const;
std::string MakeContents() const {
if (!has_span() || span().data().empty()) {
return "";
}
return fidl::utils::strip_doc_comment_slashes(span().data());
}
};
class StringLiteral final : public Literal {
public:
explicit StringLiteral(SourceElement const& element) : Literal(element, Kind::kString) {}
void Accept(TreeVisitor* visitor) const;
std::string MakeContents() const {
if (!has_span() || span().data().empty()) {
return "";
}
return fidl::utils::strip_string_literal_quotes(span().data());
}
};
class NumericLiteral final : public Literal {
public:
NumericLiteral(SourceElement const& element) : Literal(element, Kind::kNumeric) {}
void Accept(TreeVisitor* visitor) const;
};
class Ordinal64 final : public SourceElement {
public:
Ordinal64(SourceElement const& element, uint64_t value) : SourceElement(element), value(value) {}
void Accept(TreeVisitor* visitor) const;
const uint64_t value;
};
class BoolLiteral final : public Literal {
public:
BoolLiteral(SourceElement const& element, bool value)
: Literal(element, Kind::kBool), value(value) {}
void Accept(TreeVisitor* visitor) const;
const bool value;
};
class Constant : public SourceElement {
public:
enum class Kind { kIdentifier, kLiteral, kBinaryOperator };
explicit Constant(Token token, Kind kind) : SourceElement(token, token), kind(kind) {}
explicit Constant(const SourceElement& element, Kind kind) : SourceElement(element), kind(kind) {}
virtual ~Constant() {}
const Kind kind;
};
class IdentifierConstant final : public Constant {
public:
explicit IdentifierConstant(std::unique_ptr<CompoundIdentifier> identifier)
: Constant(SourceElement(identifier->start_, identifier->end_), Kind::kIdentifier),
identifier(std::move(identifier)) {}
std::unique_ptr<CompoundIdentifier> identifier;
void Accept(TreeVisitor* visitor) const;
};
class LiteralConstant final : public Constant {
public:
explicit LiteralConstant(std::unique_ptr<Literal> literal)
: Constant(literal->start_, Kind::kLiteral), literal(std::move(literal)) {}
std::unique_ptr<Literal> literal;
void Accept(TreeVisitor* visitor) const;
};
class BinaryOperatorConstant final : public Constant {
public:
enum class Operator { kOr };
explicit BinaryOperatorConstant(std::unique_ptr<Constant> left_operand,
std::unique_ptr<Constant> right_operand, Operator op)
: Constant(SourceElement(left_operand->start_, right_operand->end_), Kind::kBinaryOperator),
left_operand(std::move(left_operand)),
right_operand(std::move(right_operand)),
op(op) {}
std::unique_ptr<Constant> left_operand;
std::unique_ptr<Constant> right_operand;
Operator op;
void Accept(TreeVisitor* visitor) const;
};
class AttributeArg final : public SourceElement {
public:
// Constructor for cases where the arg name has been explicitly defined in the text.
AttributeArg(SourceElement const& element, std::unique_ptr<Identifier> name,
std::unique_ptr<Constant> value)
: SourceElement(element), maybe_name(std::move(name)), value(std::move(value)) {}
// Constructor for cases where the arg name is inferred.
AttributeArg(SourceElement const& element, std::unique_ptr<Constant> value)
: SourceElement(element), maybe_name(nullptr), value(std::move(value)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<Identifier> maybe_name;
std::unique_ptr<Constant> value;
};
class Attribute final : public SourceElement {
public:
enum Provenance {
kDefault,
kDocComment,
};
// Constructor for cases where the name of the attribute is explicitly defined in the text.
Attribute(SourceElement const& element, std::unique_ptr<Identifier> maybe_name,
std::vector<std::unique_ptr<AttributeArg>> args)
: SourceElement(element),
provenance(kDefault),
maybe_name(std::move(maybe_name)),
args(std::move(args)) {}
// Factory for "///"-style doc comments, which have no attribute name.
static Attribute CreateDocComment(SourceElement const& element,
std::vector<std::unique_ptr<AttributeArg>> args) {
auto attr = Attribute(element, nullptr, std::move(args));
attr.provenance = kDocComment;
return attr;
}
void Accept(TreeVisitor* visitor) const;
Provenance provenance;
std::unique_ptr<Identifier> maybe_name;
std::vector<std::unique_ptr<AttributeArg>> args;
};
// In the raw AST, "no attributes" is represented by a null AttributeList*,
// because every SourceElement must have a valid span. (In the flat AST, it is
// the opposite: never null, but the vector can be empty.)
class AttributeList final : public SourceElement {
public:
AttributeList(SourceElement const& element, std::vector<std::unique_ptr<Attribute>> attributes)
: SourceElement(element), attributes(std::move(attributes)) {}
void Accept(TreeVisitor* visitor) const;
std::vector<std::unique_ptr<Attribute>> attributes;
};
class TypeConstructor;
class LayoutReference;
class LayoutParameterList;
class TypeConstraints;
// The monostate variant is used to represent a parse failure.
using ConstraintOrSubtype = std::variant<std::unique_ptr<TypeConstraints>,
std::unique_ptr<TypeConstructor>, std::monostate>;
class TypeConstructor final : public SourceElement {
public:
TypeConstructor(SourceElement const& element, std::unique_ptr<LayoutReference> layout_ref,
std::unique_ptr<LayoutParameterList> parameters,
std::unique_ptr<TypeConstraints> constraints)
: SourceElement(element),
layout_ref(std::move(layout_ref)),
parameters(std::move(parameters)),
constraints(std::move(constraints)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<LayoutReference> layout_ref;
std::unique_ptr<LayoutParameterList> parameters;
std::unique_ptr<TypeConstraints> constraints;
};
class AliasDeclaration final : public SourceElement {
public:
AliasDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
std::unique_ptr<Identifier> alias, std::unique_ptr<TypeConstructor> type_ctor)
: SourceElement(element),
attributes(std::move(attributes)),
alias(std::move(alias)),
type_ctor(std::move(type_ctor)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<AttributeList> attributes;
std::unique_ptr<Identifier> alias;
std::unique_ptr<TypeConstructor> type_ctor;
};
class LibraryDecl final : public SourceElement {
public:
LibraryDecl(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
std::unique_ptr<CompoundIdentifier> path)
: SourceElement(element), attributes(std::move(attributes)), path(std::move(path)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<AttributeList> attributes;
std::unique_ptr<CompoundIdentifier> path;
};
class Using final : public SourceElement {
public:
Using(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
std::unique_ptr<CompoundIdentifier> using_path, std::unique_ptr<Identifier> maybe_alias)
: SourceElement(element),
attributes(std::move(attributes)),
using_path(std::move(using_path)),
maybe_alias(std::move(maybe_alias)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<AttributeList> attributes;
std::unique_ptr<CompoundIdentifier> using_path;
std::unique_ptr<Identifier> maybe_alias;
};
class ConstDeclaration final : public SourceElement {
public:
ConstDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
std::unique_ptr<TypeConstructor> type_ctor,
std::unique_ptr<Identifier> identifier, std::unique_ptr<Constant> constant)
: SourceElement(element),
attributes(std::move(attributes)),
type_ctor(std::move(type_ctor)),
identifier(std::move(identifier)),
constant(std::move(constant)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<AttributeList> attributes;
std::unique_ptr<TypeConstructor> type_ctor;
std::unique_ptr<Identifier> identifier;
std::unique_ptr<Constant> constant;
};
// A single modifier applied to a layout, protocol, or method.
template <typename T>
class Modifier final {
public:
Modifier(T value, Token token) : value(value), token(token) {}
// Value of the modifier
T value;
// Token that the modifier is from.
Token token;
};
class Modifiers final : public SourceElement {
public:
// Constructor for Layouts (has resourceness and strictness, but not openness).
Modifiers(SourceElement const& element,
std::optional<Modifier<types::Resourceness>> maybe_resourceness,
std::optional<Modifier<types::Strictness>> maybe_strictness,
bool resourceness_comes_first)
: SourceElement(element),
maybe_resourceness(maybe_resourceness),
maybe_strictness(maybe_strictness),
maybe_openness(std::nullopt),
resourceness_comes_first(resourceness_comes_first) {}
// Constructor for Protocols (only has openness).
Modifiers(SourceElement const& element, std::optional<Modifier<types::Openness>> maybe_openness)
: SourceElement(element),
maybe_resourceness(std::nullopt),
maybe_strictness(std::nullopt),
maybe_openness(maybe_openness),
resourceness_comes_first(false) {}
// Constructor for Protocol methods (only has strictness).
Modifiers(SourceElement const& element,
std::optional<Modifier<types::Strictness>> maybe_strictness)
: SourceElement(element),
maybe_resourceness(std::nullopt),
maybe_strictness(maybe_strictness),
maybe_openness(std::nullopt),
resourceness_comes_first(false) {}
void Accept(TreeVisitor* visitor) const;
std::optional<Modifier<types::Resourceness>> maybe_resourceness;
std::optional<Modifier<types::Strictness>> maybe_strictness;
std::optional<Modifier<types::Openness>> maybe_openness;
// Whether the resourceness modifier for a layout was before the strictness
// modifier, used for linting.
bool resourceness_comes_first;
};
class ParameterList final : public SourceElement {
public:
ParameterList(SourceElement const& element, std::unique_ptr<TypeConstructor> type_ctor)
: SourceElement(element), type_ctor(std::move(type_ctor)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<TypeConstructor> type_ctor;
};
class ProtocolMethod : public SourceElement {
public:
ProtocolMethod(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
std::unique_ptr<Modifiers> modifiers, std::unique_ptr<Identifier> identifier,
std::unique_ptr<ParameterList> maybe_request,
std::unique_ptr<ParameterList> maybe_response,
std::unique_ptr<TypeConstructor> maybe_error_ctor)
: SourceElement(element),
attributes(std::move(attributes)),
modifiers(std::move(modifiers)),
identifier(std::move(identifier)),
maybe_request(std::move(maybe_request)),
maybe_response(std::move(maybe_response)),
maybe_error_ctor(std::move(maybe_error_ctor)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<AttributeList> attributes;
std::unique_ptr<Modifiers> modifiers;
std::unique_ptr<Identifier> identifier;
std::unique_ptr<ParameterList> maybe_request;
std::unique_ptr<ParameterList> maybe_response;
std::unique_ptr<TypeConstructor> maybe_error_ctor;
};
class ProtocolCompose final : public SourceElement {
public:
ProtocolCompose(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
std::unique_ptr<CompoundIdentifier> protocol_name)
: SourceElement(element),
attributes(std::move(attributes)),
protocol_name(std::move(protocol_name)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<AttributeList> attributes;
std::unique_ptr<CompoundIdentifier> protocol_name;
};
class ProtocolDeclaration final : public SourceElement {
public:
ProtocolDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
std::unique_ptr<Modifiers> modifiers, std::unique_ptr<Identifier> identifier,
std::vector<std::unique_ptr<ProtocolCompose>> composed_protocols,
std::vector<std::unique_ptr<ProtocolMethod>> methods)
: SourceElement(element),
attributes(std::move(attributes)),
modifiers(std::move(modifiers)),
identifier(std::move(identifier)),
composed_protocols(std::move(composed_protocols)),
methods(std::move(methods)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<AttributeList> attributes;
std::unique_ptr<Modifiers> modifiers;
std::unique_ptr<Identifier> identifier;
std::vector<std::unique_ptr<ProtocolCompose>> composed_protocols;
std::vector<std::unique_ptr<ProtocolMethod>> methods;
};
class ResourceProperty final : public SourceElement {
public:
ResourceProperty(SourceElement const& element, std::unique_ptr<TypeConstructor> type_ctor,
std::unique_ptr<Identifier> identifier,
std::unique_ptr<AttributeList> attributes)
: SourceElement(element),
type_ctor(std::move(type_ctor)),
identifier(std::move(identifier)),
attributes(std::move(attributes)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<TypeConstructor> type_ctor;
std::unique_ptr<Identifier> identifier;
std::unique_ptr<AttributeList> attributes;
};
class ResourceDeclaration final : public SourceElement {
public:
ResourceDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
std::unique_ptr<Identifier> identifier,
std::unique_ptr<TypeConstructor> maybe_type_ctor,
std::vector<std::unique_ptr<ResourceProperty>> properties)
: SourceElement(element),
attributes(std::move(attributes)),
identifier(std::move(identifier)),
maybe_type_ctor(std::move(maybe_type_ctor)),
properties(std::move(properties)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<AttributeList> attributes;
std::unique_ptr<Identifier> identifier;
std::unique_ptr<TypeConstructor> maybe_type_ctor;
std::vector<std::unique_ptr<ResourceProperty>> properties;
};
class ServiceMember final : public SourceElement {
public:
ServiceMember(SourceElement const& element, std::unique_ptr<TypeConstructor> type_ctor,
std::unique_ptr<Identifier> identifier, std::unique_ptr<AttributeList> attributes)
: SourceElement(element),
type_ctor(std::move(type_ctor)),
identifier(std::move(identifier)),
attributes(std::move(attributes)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<TypeConstructor> type_ctor;
std::unique_ptr<Identifier> identifier;
std::unique_ptr<AttributeList> attributes;
};
class ServiceDeclaration final : public SourceElement {
public:
ServiceDeclaration(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
std::unique_ptr<Identifier> identifier,
std::vector<std::unique_ptr<ServiceMember>> members)
: SourceElement(element),
attributes(std::move(attributes)),
identifier(std::move(identifier)),
members(std::move(members)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<AttributeList> attributes;
std::unique_ptr<Identifier> identifier;
std::vector<std::unique_ptr<ServiceMember>> members;
};
class LayoutMember : public SourceElement {
public:
enum Kind {
kOrdinaled,
kStruct,
kValue,
};
explicit LayoutMember(SourceElement const& element, Kind kind,
std::unique_ptr<AttributeList> attributes,
std::unique_ptr<Identifier> identifier)
: SourceElement(element),
kind(kind),
attributes(std::move(attributes)),
identifier(std::move(identifier)) {}
void Accept(TreeVisitor* visitor) const;
const Kind kind;
std::unique_ptr<AttributeList> attributes;
std::unique_ptr<Identifier> identifier;
};
class OrdinaledLayoutMember final : public LayoutMember {
public:
explicit OrdinaledLayoutMember(SourceElement const& element,
std::unique_ptr<AttributeList> attributes,
std::unique_ptr<Ordinal64> ordinal,
std::unique_ptr<Identifier> identifier,
std::unique_ptr<TypeConstructor> type_ctor)
: LayoutMember(element, Kind::kOrdinaled, std::move(attributes), std::move(identifier)),
ordinal(std::move(ordinal)),
type_ctor(std::move(type_ctor)) {}
explicit OrdinaledLayoutMember(SourceElement const& element,
std::unique_ptr<AttributeList> attributes,
std::unique_ptr<Ordinal64> ordinal)
: LayoutMember(element, Kind::kOrdinaled, std::move(attributes), nullptr),
ordinal(std::move(ordinal)),
type_ctor(nullptr),
reserved(true) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<Ordinal64> ordinal;
std::unique_ptr<TypeConstructor> type_ctor;
const bool reserved = false;
};
class ValueLayoutMember final : public LayoutMember {
public:
explicit ValueLayoutMember(SourceElement const& element,
std::unique_ptr<AttributeList> attributes,
std::unique_ptr<Identifier> identifier,
std::unique_ptr<Constant> value)
: LayoutMember(element, Kind::kValue, std::move(attributes), std::move(identifier)),
value(std::move(value)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<Constant> value;
};
class StructLayoutMember final : public LayoutMember {
public:
explicit StructLayoutMember(SourceElement const& element,
std::unique_ptr<AttributeList> attributes,
std::unique_ptr<Identifier> identifier,
std::unique_ptr<TypeConstructor> type_ctor,
std::unique_ptr<Constant> default_value)
: LayoutMember(element, Kind::kStruct, std::move(attributes), std::move(identifier)),
type_ctor(std::move(type_ctor)),
default_value(std::move(default_value)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<TypeConstructor> type_ctor;
std::unique_ptr<Constant> default_value;
};
class Layout final : public SourceElement {
public:
enum Kind {
kBits,
kEnum,
kStruct,
kTable,
kUnion,
};
Layout(SourceElement const& element, Kind kind,
std::vector<std::unique_ptr<LayoutMember>> members, std::unique_ptr<Modifiers> modifiers,
std::unique_ptr<TypeConstructor> subtype_ctor)
: SourceElement(element),
kind(kind),
members(std::move(members)),
modifiers(std::move(modifiers)),
subtype_ctor(std::move(subtype_ctor)) {}
void Accept(TreeVisitor* visitor) const;
Kind kind;
std::vector<std::unique_ptr<raw::LayoutMember>> members;
// TODO(fxbug.dev/79094): refactor this to only have a single null state.
std::unique_ptr<Modifiers> modifiers;
// TODO(fxbug.dev/77853): Eventually we'll make [Struct/Ordinaled/Value]Layout
// classes to inherit from the now-abstract Layout class, similar to what can
// currently be seen on LayoutMember and its children. When that happens
// this field will only exist on ValueLayout.
std::unique_ptr<TypeConstructor> subtype_ctor;
};
class LayoutReference : public SourceElement {
public:
enum Kind {
kInline,
kNamed,
};
LayoutReference(SourceElement const& element, Kind kind) : SourceElement(element), kind(kind) {}
void Accept(TreeVisitor* visitor) const;
const Kind kind;
};
class InlineLayoutReference final : public LayoutReference {
public:
explicit InlineLayoutReference(SourceElement const& element,
std::unique_ptr<AttributeList> attributes,
std::unique_ptr<Layout> layout)
: LayoutReference(element, Kind::kInline),
attributes(std::move(attributes)),
layout(std::move(layout)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<AttributeList> attributes;
std::unique_ptr<Layout> layout;
};
class NamedLayoutReference final : public LayoutReference {
public:
explicit NamedLayoutReference(SourceElement const& element,
std::unique_ptr<CompoundIdentifier> identifier)
: LayoutReference(element, Kind::kNamed), identifier(std::move(identifier)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<CompoundIdentifier> identifier;
};
class LayoutParameter : public SourceElement {
public:
enum Kind {
kIdentifier,
kLiteral,
kType,
};
LayoutParameter(SourceElement const& element, Kind kind) : SourceElement(element), kind(kind) {}
void Accept(TreeVisitor* visitor) const;
const Kind kind;
};
class LiteralLayoutParameter final : public LayoutParameter {
public:
explicit LiteralLayoutParameter(SourceElement const& element,
std::unique_ptr<LiteralConstant> literal)
: LayoutParameter(element, Kind::kLiteral), literal(std::move(literal)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<LiteralConstant> literal;
};
class TypeLayoutParameter final : public LayoutParameter {
public:
explicit TypeLayoutParameter(SourceElement const& element,
std::unique_ptr<TypeConstructor> type_ctor)
: LayoutParameter(element, Kind::kType), type_ctor(std::move(type_ctor)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<TypeConstructor> type_ctor;
};
class IdentifierLayoutParameter final : public LayoutParameter {
public:
explicit IdentifierLayoutParameter(SourceElement const& element,
std::unique_ptr<CompoundIdentifier> identifier)
: LayoutParameter(element, Kind::kIdentifier), identifier(std::move(identifier)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<CompoundIdentifier> identifier;
};
class LayoutParameterList final : public SourceElement {
public:
LayoutParameterList(SourceElement const& element,
std::vector<std::unique_ptr<raw::LayoutParameter>> items)
: SourceElement(element), items(std::move(items)) {}
void Accept(TreeVisitor* visitor) const;
std::vector<std::unique_ptr<raw::LayoutParameter>> items;
};
class TypeConstraints final : public SourceElement {
public:
TypeConstraints(SourceElement const& element, std::vector<std::unique_ptr<raw::Constant>> items)
: SourceElement(element), items(std::move(items)) {}
void Accept(TreeVisitor* visitor) const;
std::vector<std::unique_ptr<raw::Constant>> items;
};
class TypeDecl final : public SourceElement {
public:
TypeDecl(SourceElement const& element, std::unique_ptr<AttributeList> attributes,
std::unique_ptr<Identifier> identifier, std::unique_ptr<TypeConstructor> type_ctor)
: SourceElement(element),
attributes(std::move(attributes)),
identifier(std::move(identifier)),
type_ctor(std::move(type_ctor)) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<AttributeList> attributes;
std::unique_ptr<Identifier> identifier;
std::unique_ptr<TypeConstructor> type_ctor;
};
class File final : public SourceElement {
public:
File(SourceElement const& element, Token end, std::unique_ptr<LibraryDecl> library_decl,
std::vector<std::unique_ptr<AliasDeclaration>> alias_list,
std::vector<std::unique_ptr<Using>> using_list,
std::vector<std::unique_ptr<ConstDeclaration>> const_declaration_list,
std::vector<std::unique_ptr<ProtocolDeclaration>> protocol_declaration_list,
std::vector<std::unique_ptr<ResourceDeclaration>> resource_declaration_list,
std::vector<std::unique_ptr<ServiceDeclaration>> service_declaration_list,
std::vector<std::unique_ptr<TypeDecl>> type_decls,
std::vector<std::unique_ptr<Token>> tokens)
: SourceElement(element),
library_decl(std::move(library_decl)),
alias_list(std::move(alias_list)),
using_list(std::move(using_list)),
const_declaration_list(std::move(const_declaration_list)),
protocol_declaration_list(std::move(protocol_declaration_list)),
resource_declaration_list(std::move(resource_declaration_list)),
service_declaration_list(std::move(service_declaration_list)),
type_decls(std::move(type_decls)),
tokens(std::move(tokens)),
end_(end) {}
void Accept(TreeVisitor* visitor) const;
std::unique_ptr<LibraryDecl> library_decl;
std::vector<std::unique_ptr<AliasDeclaration>> alias_list;
std::vector<std::unique_ptr<Using>> using_list;
std::vector<std::unique_ptr<ConstDeclaration>> const_declaration_list;
std::vector<std::unique_ptr<ProtocolDeclaration>> protocol_declaration_list;
std::vector<std::unique_ptr<ResourceDeclaration>> resource_declaration_list;
std::vector<std::unique_ptr<ServiceDeclaration>> service_declaration_list;
std::vector<std::unique_ptr<TypeDecl>> type_decls;
// An ordered list of all tokens (including comments) in the source file.
std::vector<std::unique_ptr<Token>> tokens;
Token end_;
};
} // namespace fidl::raw
#endif // TOOLS_FIDL_FIDLC_INCLUDE_FIDL_RAW_AST_H_