diff --git a/.github/workflows/update-cpp-parser.yml b/.github/workflows/update-cpp-parser.yml index 402a710..93e8b01 100644 --- a/.github/workflows/update-cpp-parser.yml +++ b/.github/workflows/update-cpp-parser.yml @@ -25,7 +25,7 @@ jobs: git submodule init git submodule update cd tree-sitter-cpp && git checkout origin/master && cd .. - cp tree-sitter-cpp/corpus/* test/corpus + cp tree-sitter-cpp/test/corpus/* test/corpus npm test - name: Create Pull Request uses: peter-evans/create-pull-request@v3 diff --git a/examples/marker-index.mqh b/examples/marker-index.mqh new file mode 100644 index 0000000..f7423db --- /dev/null +++ b/examples/marker-index.mqh @@ -0,0 +1,147 @@ +#ifndef MARKER_INDEX_H_ +#define MARKER_INDEX_H_ + +#include "flat_set.h" +#include "point.h" +#include "range.h" +#include +#include + +class MarkerIndex { +public: + using MarkerId = unsigned; + using MarkerIdSet = flat_set; + + struct SpliceResult { + flat_set touch; + flat_set inside; + flat_set overlap; + flat_set surround; + }; + + struct Boundary { + Point position; + flat_set starting; + flat_set ending; + }; + + struct BoundaryQueryResult { + std::vector containing_start; + std::vector boundaries; + }; + + MarkerIndex(unsigned seed = 0u); + ~MarkerIndex(); + int generate_random_number(); + void insert(MarkerId id, Point start, Point end); + void set_exclusive(MarkerId id, bool exclusive); + void remove(MarkerId id); + bool has(MarkerId id); + SpliceResult splice(Point start, Point old_extent, Point new_extent); + Point get_start(MarkerId id) const; + Point get_end(MarkerId id) const; + Range get_range(MarkerId id) const; + + int compare(MarkerId id1, MarkerId id2) const; + flat_set find_intersecting(Point start, Point end); + flat_set find_containing(Point start, Point end); + flat_set find_contained_in(Point start, Point end); + flat_set find_starting_in(Point start, Point end); + flat_set find_starting_at(Point position); + flat_set find_ending_in(Point start, Point end); + flat_set find_ending_at(Point position); + BoundaryQueryResult find_boundaries_after(Point start, size_t max_count); + + std::unordered_map dump(); + +private: + friend class Iterator; + + struct Node { + Node *parent; + Node *left; + Node *right; + Point left_extent; + flat_set left_marker_ids; + flat_set right_marker_ids; + flat_set start_marker_ids; + flat_set end_marker_ids; + int priority; + + Node(Node *parent, Point left_extent); + bool is_marker_endpoint(); + }; + + class Iterator { + public: + Iterator(MarkerIndex *marker_index); + void reset(); + Node *insert_marker_start(const MarkerId &id, const Point &start_position, + const Point &end_position); + Node *insert_marker_end(const MarkerId &id, const Point &start_position, + const Point &end_position); + Node *insert_splice_boundary(const Point &position, bool is_insertion_end); + void find_intersecting(const Point &start, const Point &end, + flat_set *result); + void find_contained_in(const Point &start, const Point &end, + flat_set *result); + void find_starting_in(const Point &start, const Point &end, + flat_set *result); + void find_ending_in(const Point &start, const Point &end, + flat_set *result); + void find_boundaries_after(Point start, size_t max_count, + BoundaryQueryResult *result); + std::unordered_map dump(); + + private: + void ascend(); + void descend_left(); + void descend_right(); + void move_to_successor(); + void seek_to_first_node_greater_than_or_equal_to(const Point &position); + void mark_right(const MarkerId &id, const Point &start_position, + const Point &end_position); + void mark_left(const MarkerId &id, const Point &start_position, + const Point &end_position); + Node *insert_left_child(const Point &position); + Node *insert_right_child(const Point &position); + void check_intersection(const Point &start, const Point &end, + flat_set *results); + void cache_node_position() const; + + MarkerIndex *marker_index; + Node *current_node; + Point current_node_position; + Point left_ancestor_position; + Point right_ancestor_position; + std::vector left_ancestor_position_stack; + std::vector right_ancestor_position_stack; + }; + + Point get_node_position(const Node *node) const; + void delete_node(Node *node); + void delete_subtree(Node *node); + void bubble_node_up(Node *node); + void bubble_node_down(Node *node); + void rotate_node_left(Node *pivot); + void rotate_node_right(Node *pivot); + void + get_starting_and_ending_markers_within_subtree(const Node *node, + flat_set *starting, + flat_set *ending); + void populate_splice_invalidation_sets( + SpliceResult *invalidated, const Node *start_node, const Node *end_node, + const flat_set &starting_inside_splice, + const flat_set &ending_inside_splice); + + std::default_random_engine random_engine; + std::uniform_int_distribution random_distribution; + Node *root; + std::unordered_map start_nodes_by_id; + std::unordered_map end_nodes_by_id; + Iterator iterator; + flat_set exclusive_marker_ids; + mutable std::unordered_map node_position_cache; +}; + +#endif // MARKER_INDEX_H_ diff --git a/examples/rule.mq5 b/examples/rule.mq5 new file mode 100644 index 0000000..d90fbbf --- /dev/null +++ b/examples/rule.mq5 @@ -0,0 +1,311 @@ +#include "compiler/rule.h" +#include "compiler/util/hash_combine.h" + +namespace tree_sitter { +namespace rules { + +using std::move; +using std::vector; +using util::hash_combine; + +Rule::Rule(const Rule &other) : blank_(Blank{}), type(BlankType) { + *this = other; +} + +Rule::Rule(Rule &&other) noexcept : blank_(Blank{}), type(BlankType) { + *this = move(other); +} + +static void destroy_value(Rule *rule) { + switch (rule->type) { + case Rule::BlankType: + return rule->blank_.~Blank(); + case Rule::CharacterSetType: + return rule->character_set_.~CharacterSet(); + case Rule::StringType: + return rule->string_.~String(); + case Rule::PatternType: + return rule->pattern_.~Pattern(); + case Rule::NamedSymbolType: + return rule->named_symbol_.~NamedSymbol(); + case Rule::SymbolType: + return rule->symbol_.~Symbol(); + case Rule::ChoiceType: + return rule->choice_.~Choice(); + case Rule::MetadataType: + return rule->metadata_.~Metadata(); + case Rule::RepeatType: + return rule->repeat_.~Repeat(); + case Rule::SeqType: + return rule->seq_.~Seq(); + } +} + +Rule &Rule::operator=(const Rule &other) { + destroy_value(this); + type = other.type; + switch (type) { + case BlankType: + new (&blank_) Blank(other.blank_); + break; + case CharacterSetType: + new (&character_set_) CharacterSet(other.character_set_); + break; + case StringType: + new (&string_) String(other.string_); + break; + case PatternType: + new (&pattern_) Pattern(other.pattern_); + break; + case NamedSymbolType: + new (&named_symbol_) NamedSymbol(other.named_symbol_); + break; + case SymbolType: + new (&symbol_) Symbol(other.symbol_); + break; + case ChoiceType: + new (&choice_) Choice(other.choice_); + break; + case MetadataType: + new (&metadata_) Metadata(other.metadata_); + break; + case RepeatType: + new (&repeat_) Repeat(other.repeat_); + break; + case SeqType: + new (&seq_) Seq(other.seq_); + break; + } + return *this; +} + +Rule &Rule::operator=(Rule &&other) noexcept { + destroy_value(this); + type = other.type; + switch (type) { + case BlankType: + new (&blank_) Blank(move(other.blank_)); + break; + case CharacterSetType: + new (&character_set_) CharacterSet(move(other.character_set_)); + break; + case StringType: + new (&string_) String(move(other.string_)); + break; + case PatternType: + new (&pattern_) Pattern(move(other.pattern_)); + break; + case NamedSymbolType: + new (&named_symbol_) NamedSymbol(move(other.named_symbol_)); + break; + case SymbolType: + new (&symbol_) Symbol(move(other.symbol_)); + break; + case ChoiceType: + new (&choice_) Choice(move(other.choice_)); + break; + case MetadataType: + new (&metadata_) Metadata(move(other.metadata_)); + break; + case RepeatType: + new (&repeat_) Repeat(move(other.repeat_)); + break; + case SeqType: + new (&seq_) Seq(move(other.seq_)); + break; + } + other.type = BlankType; + other.blank_ = Blank{}; + return *this; +} + +Rule::~Rule() noexcept { destroy_value(this); } + +bool Rule::operator==(const Rule &other) const { + if (type != other.type) + return false; + switch (type) { + case Rule::CharacterSetType: + return character_set_ == other.character_set_; + case Rule::StringType: + return string_ == other.string_; + case Rule::PatternType: + return pattern_ == other.pattern_; + case Rule::NamedSymbolType: + return named_symbol_ == other.named_symbol_; + case Rule::SymbolType: + return symbol_ == other.symbol_; + case Rule::ChoiceType: + return choice_ == other.choice_; + case Rule::MetadataType: + return metadata_ == other.metadata_; + case Rule::RepeatType: + return repeat_ == other.repeat_; + case Rule::SeqType: + return seq_ == other.seq_; + default: + return blank_ == other.blank_; + } +} + +template <> bool Rule::is() const { return type == BlankType; } + +template <> bool Rule::is() const { return type == SymbolType; } + +template <> bool Rule::is() const { return type == RepeatType; } + +template <> const Symbol &Rule::get_unchecked() const { + return symbol_; +} + +static inline void add_choice_element(std::vector *elements, + const Rule &new_rule) { + new_rule.match( + [elements](Choice choice) { + for (auto &element : choice.elements) { + add_choice_element(elements, element); + } + }, + + [elements](auto rule) { + for (auto &element : *elements) { + if (element == rule) + return; + } + elements->push_back(rule); + }); +} + +Rule Rule::choice(const vector &rules) { + vector elements; + for (auto &element : rules) { + add_choice_element(&elements, element); + } + return (elements.size() == 1) ? elements.front() : Choice{elements}; +} + +Rule Rule::repeat(const Rule &rule) { + return rule.is() ? rule : Repeat{rule}; +} + +Rule Rule::seq(const vector &rules) { + Rule result; + for (const auto &rule : rules) { + rule.match([](Blank) {}, + [&](Metadata metadata) { + if (!metadata.rule->is()) { + result = Seq{result, rule}; + } + }, + [&](auto) { + if (result.is()) { + result = rule; + } else { + result = Seq{result, rule}; + } + }); + } + return result; +} + +} // namespace rules +} // namespace tree_sitter + +namespace std { + +size_t hash::operator()(const Symbol &symbol) const { + auto result = hash()(symbol.index); + hash_combine(&result, hash()(symbol.type)); + return result; +} + +size_t hash::operator()(const NamedSymbol &symbol) const { + return hash()(symbol.value); +} + +size_t hash::operator()(const Pattern &symbol) const { + return hash()(symbol.value); +} + +size_t hash::operator()(const String &symbol) const { + return hash()(symbol.value); +} + +size_t hash::operator()(const CharacterSet &character_set) const { + size_t result = 0; + hash_combine(&result, character_set.includes_all); + hash_combine(&result, character_set.included_chars.size()); + for (uint32_t c : character_set.included_chars) { + hash_combine(&result, c); + } + hash_combine(&result, character_set.excluded_chars.size()); + for (uint32_t c : character_set.excluded_chars) { + hash_combine(&result, c); + } + return result; +} + +size_t hash::operator()(const Blank &blank) const { return 0; } + +size_t hash::operator()(const Choice &choice) const { + size_t result = 0; + for (const auto &element : choice.elements) { + symmetric_hash_combine(&result, element); + } + return result; +} + +size_t hash::operator()(const Repeat &repeat) const { + size_t result = 0; + hash_combine(&result, *repeat.rule); + return result; +} + +size_t hash::operator()(const Seq &seq) const { + size_t result = 0; + hash_combine(&result, *seq.left); + hash_combine(&result, *seq.right); + return result; +} + +size_t hash::operator()(const Metadata &metadata) const { + size_t result = 0; + hash_combine(&result, *metadata.rule); + hash_combine(&result, metadata.params.precedence); + hash_combine(&result, metadata.params.associativity); + hash_combine(&result, metadata.params.has_precedence); + hash_combine(&result, metadata.params.has_associativity); + hash_combine(&result, metadata.params.is_token); + hash_combine(&result, metadata.params.is_string); + hash_combine(&result, metadata.params.is_active); + hash_combine(&result, metadata.params.is_main_token); + return result; +} + +size_t hash::operator()(const Rule &rule) const { + size_t result = hash()(rule.type); + switch (rule.type) { + case Rule::CharacterSetType: + return result ^ hash()(rule.character_set_); + case Rule::StringType: + return result ^ hash()(rule.string_); + case Rule::PatternType: + return result ^ hash()(rule.pattern_); + case Rule::NamedSymbolType: + return result ^ hash()(rule.named_symbol_); + case Rule::SymbolType: + return result ^ hash()(rule.symbol_); + case Rule::ChoiceType: + return result ^ hash()(rule.choice_); + case Rule::MetadataType: + return result ^ hash()(rule.metadata_); + case Rule::RepeatType: + return result ^ hash()(rule.repeat_); + case Rule::SeqType: + return result ^ hash()(rule.seq_); + default: + return result ^ hash()(rule.blank_); + } +} + +} // namespace std diff --git a/package.json b/package.json index 62b9e33..1d3d117 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ { "scope": "source.mql5", "file-types": [ - "mql5", + "mq5", "mqh" ], "highlights": [ diff --git a/test/corpus/ambiguities.txt b/test/corpus/ambiguities.txt new file mode 100644 index 0000000..6e92536 --- /dev/null +++ b/test/corpus/ambiguities.txt @@ -0,0 +1,102 @@ +================================================ +template functions vs relational expressions +================================================ + +T1 a = b < c > d; +T2 e = f(g); +int a = std::get<0>(t); + +--- + +(translation_unit + (declaration + (type_identifier) + (init_declarator + (identifier) + (binary_expression + (binary_expression (identifier) (identifier)) + (identifier)))) + (declaration + (type_identifier) + (init_declarator + (identifier) + (call_expression + (template_function (identifier) (template_argument_list + (type_descriptor (type_identifier)))) + (argument_list (identifier))))) + (declaration + (primitive_type) + (init_declarator + (identifier) + (call_expression + (qualified_identifier + (namespace_identifier) + (template_function + (identifier) + (template_argument_list (number_literal)))) + (argument_list (identifier)))))) + +================================================= +function declarations vs variable initializations +================================================= + +// Function declarations +T1 a(T2 *b); +T3 c(T4 &d, T5 &&e); + +// Variable declarations with initializers +T7 f(g.h); +T6 i{j}; + +--- + +(translation_unit + (comment) + (declaration + (type_identifier) + (function_declarator + (identifier) + (parameter_list (parameter_declaration (type_identifier) (pointer_declarator (identifier)))))) + (declaration + (type_identifier) + (function_declarator + (identifier) + (parameter_list + (parameter_declaration (type_identifier) (reference_declarator (identifier))) + (parameter_declaration (type_identifier) (reference_declarator (identifier)))))) + + (comment) + (declaration + (type_identifier) + (init_declarator + (identifier) + (argument_list (field_expression (identifier) (field_identifier))))) + (declaration + (type_identifier) + (init_declarator + (identifier) + (initializer_list (identifier))))) + +================================================ +template classes vs relational expressions +================================================ + +int main() { + T1 v1; + T1 v2 = v3; +} + +--- + +(translation_unit (function_definition + (primitive_type) + (function_declarator (identifier) (parameter_list)) + (compound_statement + (declaration + (template_type (type_identifier) + (template_argument_list (type_descriptor (type_identifier)))) + (identifier)) + (declaration + (template_type (type_identifier) + (template_argument_list (type_descriptor (type_identifier)))) + (init_declarator (identifier) (identifier)))))) diff --git a/test/corpus/concepts.txt b/test/corpus/concepts.txt new file mode 100644 index 0000000..2ecd15b --- /dev/null +++ b/test/corpus/concepts.txt @@ -0,0 +1,607 @@ +================================================================================ +Concept definition +================================================================================ + +template +concept Derived = std::is_base_of::value; +-------------------------------------------------------------------------------- + +(translation_unit + (template_declaration + (template_parameter_list + (type_parameter_declaration + (type_identifier)) + (type_parameter_declaration + (type_identifier))) + (concept_definition + (identifier) + (qualified_identifier + (namespace_identifier) + (qualified_identifier + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (type_identifier)) + (type_descriptor + (type_identifier)))) + (identifier)))))) + +================================================================================ +Concept definition with requires expression +================================================================================ + +template +concept Hashable = requires(T a) { + { std::hash{}(a) } -> std::convertible_to; +}; +-------------------------------------------------------------------------------- + +(translation_unit + (template_declaration + (template_parameter_list + (type_parameter_declaration + (type_identifier))) + (concept_definition + (identifier) + (requires_expression + (parameter_list + (parameter_declaration + (type_identifier) + (identifier))) + (requirement_seq + (compound_requirement + (call_expression + (compound_literal_expression + (qualified_identifier + (namespace_identifier) + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (type_identifier))))) + (initializer_list)) + (argument_list + (identifier))) + (trailing_return_type + (type_descriptor + (qualified_identifier + (namespace_identifier) + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (qualified_identifier + (namespace_identifier) + (type_identifier)))))))))))))) + +================================================================================ +Requires clauses and expressions +================================================================================ + +template +void f(T&&) requires Eq; // can appear as the last element of a function declarator + +template requires Addable // or right after a template parameter list +T add(T a, T b) { return a + b; } + +template +concept Addable = requires (T x) { x + x; }; // requires-expression + +template + requires requires (T x) { x + x; } // ad-hoc constraint, note keyword used twice +T add(T a, T b) { return a + b; } + +template + requires (!std::is_same_v) // parenthesized expressions are allowed +void f(T); + +template requires Addable && Subtractable // conjunctions +T f(T); + +template requires Addable || Subtractable // disjunctions +T f(T); + +template requires false || true // boolean literals +T f(T); + +template requires (... && Addable) // fold expressions +T f(T); + +-------------------------------------------------------------------------------- + +(translation_unit + (template_declaration + (template_parameter_list + (type_parameter_declaration + (type_identifier))) + (declaration + (primitive_type) + (function_declarator + (identifier) + (parameter_list + (parameter_declaration + (type_identifier) + (abstract_reference_declarator))) + (requires_clause + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (type_identifier)))))))) + (comment) + (template_declaration + (template_parameter_list + (type_parameter_declaration + (type_identifier))) + (requires_clause + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (type_identifier))))) + (comment) + (function_definition + (type_identifier) + (function_declarator + (identifier) + (parameter_list + (parameter_declaration + (type_identifier) + (identifier)) + (parameter_declaration + (type_identifier) + (identifier)))) + (compound_statement + (return_statement + (binary_expression + (identifier) + (identifier)))))) + (template_declaration + (template_parameter_list + (type_parameter_declaration + (type_identifier))) + (concept_definition + (identifier) + (requires_expression + (parameter_list + (parameter_declaration + (type_identifier) + (identifier))) + (requirement_seq + (simple_requirement + (binary_expression + (identifier) + (identifier))))))) + (comment) + (template_declaration + (template_parameter_list + (type_parameter_declaration + (type_identifier))) + (requires_clause + (requires_expression + (parameter_list + (parameter_declaration + (type_identifier) + (identifier))) + (requirement_seq + (simple_requirement + (binary_expression + (identifier) + (identifier)))))) + (comment) + (function_definition + (type_identifier) + (function_declarator + (identifier) + (parameter_list + (parameter_declaration + (type_identifier) + (identifier)) + (parameter_declaration + (type_identifier) + (identifier)))) + (compound_statement + (return_statement + (binary_expression + (identifier) + (identifier)))))) + (template_declaration + (template_parameter_list + (type_parameter_declaration + (type_identifier))) + (requires_clause + (unary_expression + (qualified_identifier + (namespace_identifier) + (template_function + (identifier) + (template_argument_list + (type_descriptor + (type_identifier)) + (type_descriptor + (primitive_type))))))) + (comment) + (declaration + (primitive_type) + (function_declarator + (identifier) + (parameter_list + (parameter_declaration + (type_identifier)))))) + (template_declaration + (template_parameter_list + (type_parameter_declaration + (type_identifier))) + (requires_clause + (constraint_conjunction + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (type_identifier)))) + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (type_identifier)))))) + (comment) + (declaration + (type_identifier) + (function_declarator + (identifier) + (parameter_list + (parameter_declaration + (type_identifier)))))) + (template_declaration + (template_parameter_list + (type_parameter_declaration + (type_identifier))) + (requires_clause + (constraint_disjunction + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (type_identifier)))) + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (type_identifier)))))) + (comment) + (declaration + (type_identifier) + (function_declarator + (identifier) + (parameter_list + (parameter_declaration + (type_identifier)))))) + (template_declaration + (template_parameter_list + (type_parameter_declaration + (type_identifier))) + (requires_clause + (constraint_disjunction + (false) + (true))) + (comment) + (declaration + (type_identifier) + (function_declarator + (identifier) + (parameter_list + (parameter_declaration + (type_identifier)))))) + (template_declaration + (template_parameter_list + (variadic_type_parameter_declaration + (type_identifier))) + (requires_clause + (fold_expression + (template_function + (identifier) + (template_argument_list + (type_descriptor + (type_identifier)))))) + (comment) + (declaration + (type_identifier) + (function_declarator + (identifier) + (parameter_list + (parameter_declaration + (type_identifier))))))) + +================================================================================ +Compound requirements +================================================================================ + +template concept C2 = +requires(T x) { + {*x} -> std::convertible_to; // the expression *x must be valid + // AND the type T::inner must be valid + // AND the result of *x must be convertible to T::inner + {x + 1} -> std::same_as; // the expression x + 1 must be valid + // AND std::same_as must be satisfied + // i.e., (x + 1) must be a prvalue of type int + {x * 1} -> std::convertible_to; // the expression x * 1 must be valid + // AND its result must be convertible to T +}; + +-------------------------------------------------------------------------------- + +(translation_unit + (template_declaration + (template_parameter_list + (type_parameter_declaration + (type_identifier))) + (concept_definition + (identifier) + (requires_expression + (parameter_list + (parameter_declaration + (type_identifier) + (identifier))) + (requirement_seq + (compound_requirement + (pointer_expression + (identifier)) + (trailing_return_type + (type_descriptor + (qualified_identifier + (namespace_identifier) + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (dependent_type + (qualified_identifier + (namespace_identifier) + (type_identifier)))))))))) + (comment) + (comment) + (comment) + (compound_requirement + (binary_expression + (identifier) + (number_literal)) + (trailing_return_type + (type_descriptor + (qualified_identifier + (namespace_identifier) + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (primitive_type)))))))) + (comment) + (comment) + (comment) + (compound_requirement + (binary_expression + (identifier) + (number_literal)) + (trailing_return_type + (type_descriptor + (qualified_identifier + (namespace_identifier) + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (type_identifier)))))))) + (comment) + (comment)))))) + +================================================================================ +Nested requirements +================================================================================ + +template +concept Semiregular = DefaultConstructible && + CopyConstructible && Destructible && CopyAssignable && +requires(T a, size_t n) { + requires Same; // nested: "Same<...> evaluates to true" + { a.~T() } noexcept; // compound: "a.~T()" is a valid expression that doesn't throw + requires Same; // nested: "Same<...> evaluates to true" + requires Same; // nested + { delete new T }; // compound + { delete new T[n] }; // compound +}; +-------------------------------------------------------------------------------- + +(translation_unit + (template_declaration + (template_parameter_list + (type_parameter_declaration + (type_identifier))) + (concept_definition + (identifier) + (binary_expression + (binary_expression + (binary_expression + (binary_expression + (template_function + (identifier) + (template_argument_list + (type_descriptor + (type_identifier)))) + (template_function + (identifier) + (template_argument_list + (type_descriptor + (type_identifier))))) + (template_function + (identifier) + (template_argument_list + (type_descriptor + (type_identifier))))) + (template_function + (identifier) + (template_argument_list + (type_descriptor + (type_identifier))))) + (requires_expression + (parameter_list + (parameter_declaration + (type_identifier) + (identifier)) + (parameter_declaration + (primitive_type) + (identifier))) + (requirement_seq + (simple_requirement + (requires_clause + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (type_identifier) + (abstract_pointer_declarator)) + (type_descriptor + (decltype + (pointer_expression + (identifier)))))))) + (comment) + (compound_requirement + (call_expression + (field_expression + (identifier) + (destructor_name + (identifier))) + (argument_list))) + (comment) + (simple_requirement + (requires_clause + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (type_identifier) + (abstract_pointer_declarator)) + (type_descriptor + (decltype + (new_expression + (type_identifier)))))))) + (comment) + (simple_requirement + (requires_clause + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (type_identifier) + (abstract_pointer_declarator)) + (type_descriptor + (decltype + (new_expression + (type_identifier) + (new_declarator + (identifier))))))))) + (comment) + (compound_requirement + (delete_expression + (new_expression + (type_identifier)))) + (comment) + (compound_requirement + (delete_expression + (new_expression + (type_identifier) + (new_declarator + (identifier))))) + (comment))))))) + +================================================================================ +Constraints +================================================================================ + +template +void f(const T&); // constrained function template declaration + +void f(const EqualityComparable auto&); // constrained function template declaration + +Sortable auto foo = f(); +Sortable auto bar = g(); +NS::Concept auto baz = h(); + +Sortable decltype(auto) foo = i(); + +--- + +(translation_unit + (template_declaration + (template_parameter_list + (parameter_declaration + (type_identifier) + (identifier))) + (declaration + (primitive_type) + (function_declarator + (identifier) + (parameter_list + (parameter_declaration + (type_qualifier) + (type_identifier) + (abstract_reference_declarator)))))) + (comment) + (declaration + (primitive_type) + (function_declarator + (identifier) + (parameter_list + (parameter_declaration + (type_qualifier) + (placeholder_type_specifier + (type_identifier) + (auto)) + (abstract_reference_declarator))))) + (comment) + (declaration + (placeholder_type_specifier + (type_identifier) + (auto)) + (init_declarator + (identifier) + (call_expression + (identifier) + (argument_list)))) + (declaration + (placeholder_type_specifier + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (type_identifier)))) + (auto)) + (init_declarator + (identifier) + (call_expression + (identifier) + (argument_list)))) + (declaration + (placeholder_type_specifier + (qualified_identifier + (namespace_identifier) + (template_type + (type_identifier) + (template_argument_list + (type_descriptor + (type_identifier))))) + (auto)) + (init_declarator + (identifier) + (call_expression + (identifier) + (argument_list)))) + (declaration + (placeholder_type_specifier + (type_identifier) + (decltype + (auto))) + (init_declarator + (identifier) + (call_expression + (identifier) + (argument_list))))) diff --git a/test/corpus/declarations.txt b/test/corpus/declarations.txt new file mode 100644 index 0000000..ad12ec1 --- /dev/null +++ b/test/corpus/declarations.txt @@ -0,0 +1,1466 @@ +========================================= +Namespace definitions +========================================= + +namespace std { + +int x; + +} // namespace std + +namespace A::B { } +namespace A::B::inline C::D { } + +--- + +(translation_unit + (namespace_definition + name: (identifier) + body: (declaration_list + (declaration + type: (primitive_type) + declarator: (identifier)))) + (comment) + (namespace_definition + name: (namespace_definition_name (identifier) (identifier)) + body: (declaration_list)) + (namespace_definition + name: (namespace_definition_name + (namespace_definition_name + (namespace_definition_name (identifier) (identifier)) + (identifier)) + (identifier)) + body: (declaration_list))) + +========================================= +Namespace alias definitions +========================================= + +namespace A = B; +namespace C = ::D; +namespace fs = std::filesystem; +namespace bfs = ::boost::filesystem; +namespace literals = std::chono::literals; + +--- + +(translation_unit + (namespace_alias_definition + name: (identifier) + (identifier)) + (namespace_alias_definition + name: (identifier) + (qualified_identifier + name: (identifier))) + (namespace_alias_definition + name: (identifier) + (qualified_identifier + scope: (namespace_identifier) + name: (identifier))) + (namespace_alias_definition + name: (identifier) + (qualified_identifier + name: (qualified_identifier + scope: (namespace_identifier) + name: (identifier)))) + (namespace_alias_definition + name: (identifier) + (qualified_identifier + scope: (namespace_identifier) + name: (qualified_identifier + scope: (namespace_identifier) + name: (identifier))))) + +========================================= +Using declarations +========================================= + +using a; +using ::b; +using c::d; +using ::e::f::g; +using h = i::j; +using namespace std; +using enum Foo; + +template +using a = typename b::c; + +--- + +(translation_unit + (using_declaration (identifier)) + (using_declaration (qualified_identifier (identifier))) + (using_declaration (qualified_identifier (namespace_identifier) (identifier))) + (using_declaration + (qualified_identifier + (qualified_identifier + (namespace_identifier) + (qualified_identifier + (namespace_identifier) + (identifier))))) + (alias_declaration + (type_identifier) + (type_descriptor (qualified_identifier (namespace_identifier) (type_identifier)))) + (using_declaration (identifier)) + (using_declaration (identifier)) + (template_declaration + (template_parameter_list + (type_parameter_declaration (type_identifier))) + (alias_declaration + (type_identifier) + (type_descriptor + (dependent_type + (qualified_identifier + (template_type (type_identifier) (template_argument_list (type_descriptor (type_identifier)))) + (type_identifier))))))) + +========================================= +Reference declarations +========================================= + +int main() { + T &x = y(); +} + +--- + +(translation_unit + (function_definition + (primitive_type) + (function_declarator (identifier) (parameter_list)) + (compound_statement + (declaration + (type_identifier) + (init_declarator + (reference_declarator (identifier)) + (call_expression + (template_function + (identifier) + (template_argument_list + (type_descriptor (type_identifier) (abstract_reference_declarator)))) + (argument_list))))))) + +========================================= +R-value reference declarations +========================================= + +int main(T &&); + +int main(T &&t) { + const U &&u = v; +} + +--- + +(translation_unit + (declaration + (primitive_type) + (function_declarator + (identifier) + (parameter_list (parameter_declaration (type_identifier) (abstract_reference_declarator))))) + (function_definition + (primitive_type) + (function_declarator + (identifier) + (parameter_list (parameter_declaration (type_identifier) (reference_declarator (identifier))))) + (compound_statement + (declaration + (type_qualifier) + (type_identifier) + (init_declarator (reference_declarator (identifier)) (identifier)))))) + +========================================= +Inline method definitions +========================================= + +struct S { + int f; + + S() : f(0) {} + + private: + int getF1() const { return f; } + int getF2() const try { throw 1; } catch (...) { return f; } +}; + +--- + +(translation_unit + (struct_specifier (type_identifier) (field_declaration_list + (field_declaration (primitive_type) (field_identifier)) + (function_definition + (function_declarator (identifier) (parameter_list)) + (field_initializer_list (field_initializer (field_identifier) (argument_list (number_literal)))) + (compound_statement)) + (access_specifier) + (function_definition + (primitive_type) + (function_declarator (field_identifier) (parameter_list) (type_qualifier)) + (compound_statement (return_statement (identifier)))) + (function_definition + (primitive_type) + (function_declarator (field_identifier) (parameter_list) (type_qualifier)) + (try_statement + (compound_statement (throw_statement (number_literal))) + (catch_clause (parameter_list) + (compound_statement (return_statement (identifier))))))))) + +========================================= +Inline method definitions with overrides +========================================= + +struct B : A { + int foo() override { return 2; } + int pho() final { return 3; } + int bar() const override { return 4; } + int baz() const final { return 5; } + int bag() const final override { return 6; } + int bah() const override final { return 7; } +}; + +--- + +(translation_unit + (struct_specifier (type_identifier) (base_class_clause (type_identifier)) (field_declaration_list + (function_definition + (primitive_type) + (function_declarator (field_identifier) (parameter_list) (virtual_specifier)) + (compound_statement (return_statement (number_literal)))) + (function_definition + (primitive_type) + (function_declarator (field_identifier) (parameter_list) (virtual_specifier)) + (compound_statement (return_statement (number_literal)))) + (function_definition + (primitive_type) + (function_declarator (field_identifier) (parameter_list) (type_qualifier) (virtual_specifier)) + (compound_statement (return_statement (number_literal)))) + (function_definition + (primitive_type) + (function_declarator (field_identifier) (parameter_list) (type_qualifier) (virtual_specifier)) + (compound_statement (return_statement (number_literal)))) + (function_definition + (primitive_type) + (function_declarator (field_identifier) (parameter_list) (type_qualifier) (virtual_specifier) (virtual_specifier)) + (compound_statement (return_statement (number_literal)))) + (function_definition + (primitive_type) + (function_declarator (field_identifier) (parameter_list) (type_qualifier) (virtual_specifier) (virtual_specifier)) + (compound_statement (return_statement (number_literal))))))) + +===================================== +Virtual method declarations +=============================== + +class A { + virtual ~Point(); + void b(); + virtual void foo() {} + virtual void bar(); + inline virtual void foo() override; + virtual inline void foo() final; +}; + +--- + +(translation_unit + (class_specifier + (type_identifier) + (field_declaration_list + (declaration + (virtual_function_specifier) + (function_declarator (destructor_name (identifier)) (parameter_list))) + (field_declaration + (primitive_type) + (function_declarator (field_identifier) (parameter_list))) + (function_definition + (virtual_function_specifier) + (primitive_type) + (function_declarator + (field_identifier) + (parameter_list)) + (compound_statement)) + (field_declaration + (virtual_function_specifier) + (primitive_type) + (function_declarator + (field_identifier) + (parameter_list))) + (field_declaration + (storage_class_specifier) + (virtual_function_specifier) + (primitive_type) + (function_declarator (field_identifier) (parameter_list) (virtual_specifier))) + (field_declaration + (virtual_function_specifier) + (storage_class_specifier) + (primitive_type) + (function_declarator (field_identifier) (parameter_list) (virtual_specifier)))))) + +========================================= +Constructor and destructor declarations +========================================= + +class C { + void *data_; + + public: + C(); + C(int, float); + inline C(); + explicit inline C(); + [[deprecated]] C(); + template + C(T t); + C() : NS::Base() {} + ~C(); +}; + +--- + +(translation_unit + (class_specifier (type_identifier) (field_declaration_list + (field_declaration (primitive_type) (pointer_declarator (field_identifier))) + (access_specifier) + (declaration (function_declarator (identifier) (parameter_list))) + (declaration (function_declarator (identifier) (parameter_list + (parameter_declaration (primitive_type)) + (parameter_declaration (primitive_type))))) + (declaration (storage_class_specifier) (function_declarator (identifier) (parameter_list))) + (declaration (explicit_function_specifier) (storage_class_specifier) (function_declarator (identifier) (parameter_list))) + (declaration (attribute_declaration (attribute (identifier))) + (function_declarator (identifier) (parameter_list))) + (template_declaration (template_parameter_list (type_parameter_declaration (type_identifier))) + (declaration (function_declarator (identifier) (parameter_list (parameter_declaration (type_identifier) (identifier)))))) + (function_definition (function_declarator (identifier) (parameter_list)) + (field_initializer_list + (field_initializer + (qualified_identifier + (namespace_identifier) + (template_method + (field_identifier) + (template_argument_list (type_descriptor (type_identifier))))) + (argument_list))) + (compound_statement)) + (declaration (function_declarator (destructor_name (identifier)) (parameter_list)))))) + +========================================= +Classes with inheritance +========================================= + +class A : public B { +}; + +class C : C::D, public E { +}; + +--- + +(translation_unit + (class_specifier + (type_identifier) + (base_class_clause (type_identifier)) + (field_declaration_list)) + (class_specifier + (type_identifier) + (base_class_clause + (qualified_identifier (namespace_identifier) (type_identifier)) + (type_identifier)) + (field_declaration_list))) + +========================================= +Classes with final virt specifier +========================================= + +class A final : public B { +}; + +class C final {}; + +struct D final {}; + +--- + +(translation_unit + (class_specifier + (type_identifier) + (virtual_specifier) + (base_class_clause (type_identifier)) + (field_declaration_list)) + (class_specifier + (type_identifier) + (virtual_specifier) + (field_declaration_list)) + (struct_specifier + (type_identifier) + (virtual_specifier) + (field_declaration_list))) + +========================================= +Nested classes +======================================== + +class A { + private: + class B : private C, public D { + }; + + B e, f; +}; + +--- + +(translation_unit + (class_specifier (type_identifier) (field_declaration_list + (access_specifier) + (field_declaration + (class_specifier (type_identifier) (base_class_clause (type_identifier) (type_identifier)) (field_declaration_list))) + (field_declaration + (type_identifier) (field_identifier) (field_identifier))))) + +========================================= +Friend declarations +========================================= + +struct C { + friend class D; + friend D; + friend int f(C &); +}; + +--- + +(translation_unit + (struct_specifier (type_identifier) (field_declaration_list + (friend_declaration (type_identifier)) + (friend_declaration (type_identifier)) + (friend_declaration (declaration (primitive_type) (function_declarator + (identifier) + (parameter_list (parameter_declaration (type_identifier) (abstract_reference_declarator))))))))) + +============================================= +Default member initializers +============================================= + +struct A { + bool a = 1; + vector b = {c, d, e}; + F g {h}; +}; + +--- + +(translation_unit + (struct_specifier (type_identifier) (field_declaration_list + (field_declaration + (primitive_type) + (field_identifier) + (number_literal)) + (field_declaration + (template_type (type_identifier) (template_argument_list (type_descriptor (primitive_type)))) + (field_identifier) + (initializer_list (identifier) (identifier) (identifier))) + (field_declaration + (type_identifier) + (field_identifier) + (initializer_list (identifier)))))) + +========================================= +Function parameters with default values +========================================= + +int foo(bool x = 5) {} + +--- + +(translation_unit + (function_definition + (primitive_type) + (function_declarator + (identifier) + (parameter_list + (optional_parameter_declaration (primitive_type) (identifier) (number_literal)))) + (compound_statement))) + +========================================= +Attributes +========================================= + +int f([[a::b(c), d]] int x) {} + +[[gnu::always_inline]] [[gnu::hot]] [[gnu::const]] [[nodiscard]] +inline int g(); + +[[aaa]] +int f() { } + +class [[gnu::visibility("default")]] A {}; +struct [[gnu::visibility("default")]] A {}; +union [[gnu::visibility("default")]] A {}; + +--- + +(translation_unit + (function_definition + (primitive_type) + (function_declarator + (identifier) + (parameter_list + (parameter_declaration + (attribute_declaration + (attribute (identifier) (identifier) (argument_list (identifier))) + (attribute (identifier))) + (primitive_type) + (identifier)))) + (compound_statement)) + (declaration + (attribute_declaration (attribute (identifier) (identifier))) + (attribute_declaration (attribute (identifier) (identifier))) + (attribute_declaration (attribute (identifier) (identifier))) + (attribute_declaration (attribute (identifier))) + (storage_class_specifier) + (primitive_type) + (function_declarator (identifier) (parameter_list))) + (function_definition + (attribute_declaration (attribute (identifier))) + (primitive_type) (function_declarator (identifier) (parameter_list)) (compound_statement)) + (class_specifier + (attribute_declaration (attribute (identifier) (identifier) (argument_list (string_literal)))) + (type_identifier) + (field_declaration_list)) + (struct_specifier + (attribute_declaration (attribute (identifier) (identifier) (argument_list (string_literal)))) + (type_identifier) + (field_declaration_list)) + (union_specifier + (attribute_declaration (attribute (identifier) (identifier) (argument_list (string_literal)))) + (type_identifier) + (field_declaration_list))) + +========================================= +Operator overload declarations +========================================= + +ostream &operator<<(ostream &, const A &a); +Foo operator "" _foo(const char* s); +std::string_view operator ""s_v(const char* s); +bool A::operator!=(const A &other) const; + +bool A::operator ==(const A &other) const; + +void * A::operator new(size_t s); + +void * A::operator delete [](void * p); + +--- + +(translation_unit + (declaration + (type_identifier) + (reference_declarator + (function_declarator + (operator_name) + (parameter_list + (parameter_declaration (type_identifier) (abstract_reference_declarator)) + (parameter_declaration (type_qualifier) (type_identifier) (reference_declarator (identifier))))))) + (declaration + (type_identifier) + (function_declarator + (operator_name (identifier)) + (parameter_list + (parameter_declaration (type_qualifier) (primitive_type) (pointer_declarator (identifier)))))) + (declaration + (qualified_identifier (namespace_identifier) (type_identifier)) + (function_declarator + (operator_name (identifier)) + (parameter_list + (parameter_declaration (type_qualifier) (primitive_type) (pointer_declarator (identifier)))))) + (declaration + (primitive_type) + (function_declarator + (qualified_identifier (namespace_identifier) (operator_name)) + (parameter_list + (parameter_declaration (type_qualifier) (type_identifier) (reference_declarator (identifier)))) + (type_qualifier))) + (declaration + (primitive_type) + (function_declarator + (qualified_identifier (namespace_identifier) (operator_name)) + (parameter_list + (parameter_declaration (type_qualifier) (type_identifier) (reference_declarator (identifier)))) + (type_qualifier))) + (declaration + (primitive_type) + (pointer_declarator + (function_declarator + (qualified_identifier (namespace_identifier) (operator_name)) + (parameter_list (parameter_declaration (primitive_type) (identifier)))))) + (declaration + (primitive_type) + (pointer_declarator + (function_declarator + (qualified_identifier (namespace_identifier) (operator_name)) + (parameter_list (parameter_declaration (primitive_type) (pointer_declarator (identifier)))))))) + +========================================= +Template declarations +========================================= + +template +void foo(T &t); + +template +int bar(T &t) { return u; } + +template +class Foo {}; + +template +Foo::Foo(int mem) : mem_(mem) {} + +template +template +void A::foo(U&) {} + +--- + +(translation_unit + (template_declaration + (template_parameter_list + (type_parameter_declaration (type_identifier))) + (declaration + (primitive_type) + (function_declarator + (identifier) + (parameter_list + (parameter_declaration (type_identifier) (reference_declarator (identifier))))))) + (template_declaration + (template_parameter_list + (type_parameter_declaration (type_identifier)) + (parameter_declaration (primitive_type) (identifier))) + (function_definition + (primitive_type) + (function_declarator + (identifier) + (parameter_list (parameter_declaration (type_identifier) (reference_declarator (identifier))))) + (compound_statement (return_statement (identifier))))) + (template_declaration + (template_parameter_list + (type_parameter_declaration (type_identifier))) + (class_specifier (type_identifier) (field_declaration_list))) + (template_declaration + (template_parameter_list + (type_parameter_declaration (type_identifier))) + (function_definition + (function_declarator + (qualified_identifier + (template_type + (type_identifier) + (template_argument_list (type_descriptor (type_identifier)))) + (identifier)) + (parameter_list + (parameter_declaration (primitive_type) (identifier)))) + (field_initializer_list + (field_initializer + (field_identifier) + (argument_list (identifier)))) + (compound_statement))) + (template_declaration + (template_parameter_list + (type_parameter_declaration (type_identifier))) + (template_declaration + (template_parameter_list + (type_parameter_declaration (type_identifier))) + (function_definition + (primitive_type) + (function_declarator + (qualified_identifier + (template_type + (type_identifier) + (template_argument_list (type_descriptor (type_identifier)))) + (identifier)) + (parameter_list + (parameter_declaration + (type_identifier) + (abstract_reference_declarator)))) + (compound_statement))))) + +========================================= +Template template declarations +========================================= + +template