@@ -2473,8 +2473,9 @@ Parser::parseMacroRoleAttribute(
2473
2473
// / \returns \c None if an error was diagnosed; \c Identifier() if the argument list was permissibly
2474
2474
// / omitted; the identifier written by the user otherwise.
2475
2475
static std::optional<Identifier> parseSingleAttrOptionImpl (
2476
- Parser &P, SourceLoc Loc, SourceRange &AttrRange, StringRef AttrName,
2477
- DeclAttrKind DK, bool allowOmitted, DiagRef nonIdentifierDiagnostic) {
2476
+ Parser &P, SourceLoc Loc, SourceRange &AttrRange, StringRef AttrName, DeclAttrKind DK,
2477
+ ParserStatus &Status, bool allowOmitted, DiagRef nonIdentifierDiagnostic,
2478
+ llvm::function_ref<void ()> codeCompletionCallback = {}) {
2478
2479
SWIFT_DEFER {
2479
2480
AttrRange = SourceRange (Loc, P.PreviousLoc );
2480
2481
};
@@ -2484,19 +2485,32 @@ static std::optional<Identifier> parseSingleAttrOptionImpl(
2484
2485
if (allowOmitted)
2485
2486
return Identifier ();
2486
2487
2488
+ Status.setIsParseError ();
2487
2489
P.diagnose (Loc, diag::attr_expected_lparen, AttrName, isDeclModifier);
2488
2490
return std::nullopt;
2489
2491
}
2490
2492
2491
2493
P.consumeAttributeLParen ();
2494
+
2495
+ if (P.Tok .is (tok::code_complete)) {
2496
+ Status.setHasCodeCompletion ();
2497
+ codeCompletionCallback ();
2498
+ }
2492
2499
2493
2500
StringRef parsedName = P.Tok .getText ();
2494
2501
if (!P.consumeIf (tok::identifier)) {
2502
+ Status.setIsParseError ();
2495
2503
P.diagnose (Loc, nonIdentifierDiagnostic);
2496
2504
return std::nullopt;
2497
2505
}
2498
2506
2507
+ if (P.Tok .is (tok::code_complete)) {
2508
+ Status.setHasCodeCompletion ();
2509
+ codeCompletionCallback ();
2510
+ }
2511
+
2499
2512
if (!P.consumeIf (tok::r_paren)) {
2513
+ Status.setIsParseError ();
2500
2514
P.diagnose (Loc, diag::attr_expected_rparen, AttrName, isDeclModifier);
2501
2515
return std::nullopt;
2502
2516
}
@@ -2590,11 +2604,11 @@ ParserResult<LifetimeAttr> Parser::parseLifetimeAttribute(SourceLoc atLoc,
2590
2604
// / \returns \c None if an error was diagnosed; \c Identifier() if the argument list was permissibly
2591
2605
// / omitted; the identifier written by the user otherwise.
2592
2606
static std::optional<Identifier>
2593
- parseSingleAttrOptionIdentifier (Parser &P, SourceLoc Loc,
2607
+ parseSingleAttrOptionIdentifier (Parser &P, SourceLoc Loc, ParserStatus &Status,
2594
2608
SourceRange &AttrRange, StringRef AttrName,
2595
2609
DeclAttrKind DK, bool allowOmitted = false ) {
2596
2610
return parseSingleAttrOptionImpl (
2597
- P, Loc, AttrRange, AttrName, DK, allowOmitted,
2611
+ P, Loc, AttrRange, AttrName, DK, Status, allowOmitted,
2598
2612
{diag::attr_expected_option_identifier, {AttrName}});
2599
2613
}
2600
2614
@@ -2616,13 +2630,17 @@ template <typename R>
2616
2630
static std::optional<R>
2617
2631
parseSingleAttrOption (Parser &P, SourceLoc Loc, SourceRange &AttrRange,
2618
2632
StringRef AttrName, DeclAttrKind DK,
2633
+ ParserStatus& Status,
2619
2634
ArrayRef<std::pair<Identifier, R>> options,
2620
- std::optional<R> valueIfOmitted = std::nullopt) {
2635
+ std::optional<R> valueIfOmitted = std::nullopt,
2636
+ llvm::function_ref<void ()> codeCompletionCallback = {}) {
2621
2637
auto parsedIdentifier = parseSingleAttrOptionImpl (
2622
- P, Loc, AttrRange,AttrName, DK,
2638
+ P, Loc, AttrRange, AttrName, DK, Status ,
2623
2639
/* allowOmitted=*/ valueIfOmitted.has_value (),
2624
2640
{diag::attr_expected_option_such_as,
2625
- {AttrName, options.front ().first .str ()}});
2641
+ {AttrName, options.front ().first .str ()}},
2642
+ codeCompletionCallback);
2643
+
2626
2644
if (!parsedIdentifier)
2627
2645
return std::nullopt;
2628
2646
@@ -2755,8 +2773,9 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
2755
2773
}
2756
2774
2757
2775
case DeclAttrKind::Inline: {
2776
+ ParserStatus optionStatus;
2758
2777
auto kind = parseSingleAttrOption<InlineKind>(
2759
- *this , Loc, AttrRange, AttrName, DK, {
2778
+ *this , Loc, AttrRange, AttrName, DK, optionStatus, {
2760
2779
{ Context.Id_never , InlineKind::Never },
2761
2780
{ Context.Id__always , InlineKind::Always }
2762
2781
});
@@ -2770,8 +2789,9 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
2770
2789
}
2771
2790
2772
2791
case DeclAttrKind::Optimize: {
2792
+ ParserStatus optionStatus;
2773
2793
auto optMode = parseSingleAttrOption<OptimizationMode>(
2774
- *this , Loc, AttrRange, AttrName, DK, {
2794
+ *this , Loc, AttrRange, AttrName, DK, optionStatus, {
2775
2795
{ Context.Id_speed , OptimizationMode::ForSpeed },
2776
2796
{ Context.Id_size , OptimizationMode::ForSize },
2777
2797
{ Context.Id_none , OptimizationMode::NoOptimization }
@@ -2786,8 +2806,9 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
2786
2806
}
2787
2807
2788
2808
case DeclAttrKind::Exclusivity: {
2809
+ ParserStatus optionStatus;
2789
2810
auto mode = parseSingleAttrOption<ExclusivityAttr::Mode>(
2790
- *this , Loc, AttrRange, AttrName, DK, {
2811
+ *this , Loc, AttrRange, AttrName, DK, optionStatus, {
2791
2812
{ Context.Id_checked , ExclusivityAttr::Mode::Checked },
2792
2813
{ Context.Id_unchecked , ExclusivityAttr::Mode::Unchecked }
2793
2814
});
@@ -2807,11 +2828,19 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
2807
2828
2808
2829
if (Kind == ReferenceOwnership::Unowned) {
2809
2830
// Parse an optional specifier after unowned.
2831
+ ParserStatus optionStatus;
2810
2832
Kind = parseSingleAttrOption<ReferenceOwnership>(
2811
- *this , Loc, AttrRange, AttrName, DK, {
2833
+ *this , Loc, AttrRange, AttrName, DK, optionStatus, {
2812
2834
{ Context.Id_unsafe , ReferenceOwnership::Unmanaged },
2813
2835
{ Context.Id_safe , ReferenceOwnership::Unowned }
2814
- }, ReferenceOwnership::Unowned)
2836
+ }, ReferenceOwnership::Unowned,
2837
+ [&] () {
2838
+ if (CodeCompletionCallbacks) {
2839
+ CodeCompletionCallbacks->completeDeclAttrParam (
2840
+ ParameterizedDeclAttributeKind::Unowned, 0 , false );
2841
+ consumeToken (tok::code_complete);
2842
+ }
2843
+ })
2815
2844
// Recover from errors by going back to Unowned.
2816
2845
.value_or (ReferenceOwnership::Unowned);
2817
2846
}
@@ -2827,8 +2856,9 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
2827
2856
}
2828
2857
2829
2858
case DeclAttrKind::NonSendable: {
2859
+ ParserStatus optionStatus;
2830
2860
auto kind = parseSingleAttrOption<NonSendableKind>(
2831
- *this , Loc, AttrRange, AttrName, DK, {
2861
+ *this , Loc, AttrRange, AttrName, DK, optionStatus, {
2832
2862
{ Context.Id_assumed , NonSendableKind::Assumed }
2833
2863
}, NonSendableKind::Specific);
2834
2864
if (!kind)
@@ -2882,11 +2912,34 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
2882
2912
2883
2913
consumeAttributeLParen ();
2884
2914
2915
+ if (Tok.is (tok::code_complete) && CodeCompletionCallbacks) {
2916
+ CodeCompletionCallbacks->completeDeclAttrParam (
2917
+ ParameterizedDeclAttributeKind::AccessControl, 0 , false );
2918
+ consumeToken (tok::code_complete);
2919
+ }
2920
+
2885
2921
// Parse the subject.
2886
2922
if (Tok.isContextualKeyword (" set" )) {
2887
2923
consumeToken ();
2888
2924
} else {
2889
2925
diagnose (Loc, diag::attr_access_expected_set, AttrName);
2926
+
2927
+ const Token &Tok2 = peekToken ();
2928
+
2929
+ if (CodeCompletionCallbacks) {
2930
+ if (Tok.is (tok::code_complete)) {
2931
+ CodeCompletionCallbacks->completeDeclAttrParam (
2932
+ ParameterizedDeclAttributeKind::AccessControl, 0 , false );
2933
+ consumeToken (tok::code_complete);
2934
+ } else if (Tok2.is (tok::code_complete) && Tok.is (tok::identifier) &&
2935
+ !Tok.isContextualDeclKeyword ()) {
2936
+ consumeToken (tok::identifier);
2937
+ CodeCompletionCallbacks->completeDeclAttrParam (
2938
+ ParameterizedDeclAttributeKind::AccessControl, 0 , false );
2939
+ consumeToken (tok::code_complete);
2940
+ }
2941
+ }
2942
+
2890
2943
// Minimal recovery: if there's a single token and then an r_paren,
2891
2944
// consume them both. If there's just an r_paren, consume that.
2892
2945
if (!consumeIf (tok::r_paren)) {
@@ -3155,8 +3208,9 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
3155
3208
3156
3209
case DeclAttrKind::SwiftNativeObjCRuntimeBase: {
3157
3210
SourceRange range;
3158
- auto name = parseSingleAttrOptionIdentifier (*this , Loc, range, AttrName,
3159
- DK);
3211
+ ParserStatus optionStatus;
3212
+ auto name = parseSingleAttrOptionIdentifier (*this , Loc, optionStatus, range,
3213
+ AttrName, DK);
3160
3214
if (!name)
3161
3215
return makeParserSuccess ();
3162
3216
@@ -3448,7 +3502,8 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
3448
3502
}
3449
3503
case DeclAttrKind::ObjCImplementation: {
3450
3504
SourceRange range;
3451
- auto name = parseSingleAttrOptionIdentifier (*this , Loc, range, AttrName, DK,
3505
+ ParserStatus optionStatus;
3506
+ auto name = parseSingleAttrOptionIdentifier (*this , Loc, optionStatus, range, AttrName, DK,
3452
3507
/* allowOmitted=*/ true );
3453
3508
if (!name)
3454
3509
return makeParserSuccess ();
@@ -3460,8 +3515,9 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
3460
3515
}
3461
3516
case DeclAttrKind::ObjCRuntimeName: {
3462
3517
SourceRange range;
3518
+ ParserStatus optionStatus;
3463
3519
auto name =
3464
- parseSingleAttrOptionIdentifier (*this , Loc, range, AttrName, DK);
3520
+ parseSingleAttrOptionIdentifier (*this , Loc, optionStatus, range, AttrName, DK);
3465
3521
if (!name)
3466
3522
return makeParserSuccess ();
3467
3523
@@ -3618,8 +3674,9 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
3618
3674
3619
3675
case DeclAttrKind::ProjectedValueProperty: {
3620
3676
SourceRange range;
3677
+ ParserStatus optionStatus;
3621
3678
auto name =
3622
- parseSingleAttrOptionIdentifier (*this , Loc, range, AttrName, DK);
3679
+ parseSingleAttrOptionIdentifier (*this , Loc, optionStatus, range, AttrName, DK);
3623
3680
if (!name)
3624
3681
return makeParserSuccess ();
3625
3682
@@ -3719,9 +3776,17 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
3719
3776
case DeclAttrKind::Nonisolated: {
3720
3777
std::optional<bool > isUnsafe (false );
3721
3778
if (EnableParameterizedNonisolated) {
3779
+ ParserStatus optionStatus;
3722
3780
isUnsafe =
3723
3781
parseSingleAttrOption<bool >(*this , Loc, AttrRange, AttrName, DK,
3724
- {{Context.Id_unsafe , true }}, *isUnsafe);
3782
+ optionStatus, {{Context.Id_unsafe , true }},
3783
+ *isUnsafe, [&] () {
3784
+ if (CodeCompletionCallbacks) {
3785
+ CodeCompletionCallbacks->completeDeclAttrParam (
3786
+ ParameterizedDeclAttributeKind::Nonisolated, 0 , false );
3787
+ consumeToken (tok::code_complete);
3788
+ }
3789
+ });
3725
3790
if (!isUnsafe) {
3726
3791
return makeParserSuccess ();
3727
3792
}
@@ -3920,8 +3985,9 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
3920
3985
}
3921
3986
3922
3987
case DeclAttrKind::Execution: {
3988
+ ParserStatus optionStatus;
3923
3989
auto behavior = parseSingleAttrOption<ExecutionKind>(
3924
- *this , Loc, AttrRange, AttrName, DK,
3990
+ *this , Loc, AttrRange, AttrName, DK, optionStatus,
3925
3991
{{Context.Id_concurrent , ExecutionKind::Concurrent},
3926
3992
{Context.Id_caller , ExecutionKind::Caller}});
3927
3993
if (!behavior)
0 commit comments