|
38 | 38 | #include <algorithm> |
39 | 39 | #include <cstring> |
40 | 40 | #include <format> |
| 41 | +#include <iostream> |
41 | 42 | #include <ranges> |
| 43 | +#include <unordered_set> |
| 44 | + |
| 45 | +#include "cxx/source_location.h" |
| 46 | +#include "cxx/token_fwd.h" |
42 | 47 |
|
43 | 48 | namespace cxx { |
44 | 49 |
|
@@ -1503,6 +1508,14 @@ auto Parser::parse_unqualified_id(UnqualifiedIdAST*& yyast, |
1503 | 1508 | NestedNameSpecifierAST* nestedNameSpecifier, |
1504 | 1509 | bool isTemplateIntroduced, |
1505 | 1510 | bool inRequiresClause) -> bool { |
| 1511 | + if (!stopParsing_ && lookat(TokenKind::T_CODE_COMPLETION)) { |
| 1512 | + stopParsing_ = true; |
| 1513 | + |
| 1514 | + warning(std::format("requested code completion of unqualified-id")); |
| 1515 | + |
| 1516 | + consumeToken(); |
| 1517 | + } |
| 1518 | + |
1506 | 1519 | auto lookat_template_id = [&] { |
1507 | 1520 | LookaheadParser lookahead{this}; |
1508 | 1521 |
|
@@ -2434,6 +2447,14 @@ auto Parser::parse_member_expression(ExpressionAST*& yyast) -> bool { |
2434 | 2447 |
|
2435 | 2448 | ast->isTemplateIntroduced = match(TokenKind::T_TEMPLATE, ast->templateLoc); |
2436 | 2449 |
|
| 2450 | + if (!stopParsing_ && lookat(TokenKind::T_CODE_COMPLETION)) { |
| 2451 | + stopParsing_ = true; |
| 2452 | + |
| 2453 | + warning(std::format("requested code completion of member access")); |
| 2454 | + |
| 2455 | + consumeToken(); |
| 2456 | + } |
| 2457 | + |
2437 | 2458 | if (!parse_unqualified_id(ast->unqualifiedId, ast->nestedNameSpecifier, |
2438 | 2459 | ast->isTemplateIntroduced, |
2439 | 2460 | /*inRequiresClause*/ false)) |
@@ -5184,6 +5205,16 @@ auto Parser::parse_attribute_declaration(DeclarationAST*& yyast) -> bool { |
5184 | 5205 |
|
5185 | 5206 | auto Parser::parse_decl_specifier(SpecifierAST*& yyast, DeclSpecs& specs) |
5186 | 5207 | -> bool { |
| 5208 | + if (!stopParsing_ && lookat(TokenKind::T_CODE_COMPLETION)) { |
| 5209 | + stopParsing_ = true; |
| 5210 | + |
| 5211 | + warning( |
| 5212 | + std::format("requested code completion of decl specifier in scope '{}'", |
| 5213 | + to_string(scope_->owner()->name()))); |
| 5214 | + |
| 5215 | + consumeToken(); |
| 5216 | + } |
| 5217 | + |
5187 | 5218 | switch (TokenKind(LA())) { |
5188 | 5219 | case TokenKind::T_TYPEDEF: { |
5189 | 5220 | auto ast = make_node<TypedefSpecifierAST>(pool_); |
@@ -5666,6 +5697,13 @@ auto Parser::parse_named_type_specifier(SpecifierAST*& yyast, DeclSpecs& specs) |
5666 | 5697 | SourceLocation templateLoc; |
5667 | 5698 | const auto isTemplateIntroduced = match(TokenKind::T_TEMPLATE, templateLoc); |
5668 | 5699 |
|
| 5700 | + if (SourceLocation completionLoc; |
| 5701 | + match(TokenKind::T_CODE_COMPLETION, completionLoc)) { |
| 5702 | + stopParsing_ = true; |
| 5703 | + parse_warn(completionLoc, "code completion at type specifier"); |
| 5704 | + return false; |
| 5705 | + } |
| 5706 | + |
5669 | 5707 | if (!lookat(TokenKind::T_IDENTIFIER)) return false; |
5670 | 5708 |
|
5671 | 5709 | UnqualifiedIdAST* unqualifiedId = nullptr; |
|
0 commit comments