@@ -1746,13 +1746,21 @@ static PatternBindingInitializer *findAttributeInitContent(
1746
1746
// / Note that various attributes (like mutating, weak, and unowned) are parsed
1747
1747
// / but rejected since they have context-sensitive keywords.
1748
1748
// /
1749
- bool Parser::parseDeclAttribute (DeclAttributes &Attributes, SourceLoc AtLoc) {
1749
+ ParserStatus Parser::parseDeclAttribute (DeclAttributes &Attributes, SourceLoc AtLoc) {
1750
1750
// If this not an identifier, the attribute is malformed.
1751
1751
if (Tok.isNot (tok::identifier) &&
1752
1752
Tok.isNot (tok::kw_in) &&
1753
1753
Tok.isNot (tok::kw_inout)) {
1754
+
1755
+ if (Tok.is (tok::code_complete)) {
1756
+ if (CodeCompletion)
1757
+ CodeCompletion->completeDeclAttrBeginning (isInSILMode ());
1758
+ consumeToken (tok::code_complete);
1759
+ return makeParserCodeCompletionStatus ();
1760
+ }
1761
+
1754
1762
diagnose (Tok, diag::expected_attribute_name);
1755
- return true ;
1763
+ return makeParserError () ;
1756
1764
}
1757
1765
1758
1766
// If the attribute follows the new representation, switch
@@ -1802,7 +1810,8 @@ bool Parser::parseDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc) {
1802
1810
diagnose (AtLoc, diag::attr_warn_unused_result_removed)
1803
1811
.fixItRemove (SourceRange (AtLoc, attrLoc));
1804
1812
1805
- return false ;
1813
+ // Recovered.
1814
+ return makeParserSuccess ();
1806
1815
}
1807
1816
1808
1817
// @warn_unused_result with arguments.
@@ -1823,11 +1832,14 @@ bool Parser::parseDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc) {
1823
1832
diagnose (AtLoc, diag::attr_warn_unused_result_removed)
1824
1833
.fixItRemove (SourceRange (AtLoc, rParenLoc));
1825
1834
1826
- return false ;
1835
+ // Recovered.
1836
+ return makeParserSuccess ();
1827
1837
}
1828
1838
1829
- if (DK != DAK_Count && !DeclAttribute::shouldBeRejectedByParser (DK))
1830
- return parseNewDeclAttribute (Attributes, AtLoc, DK);
1839
+ if (DK != DAK_Count && !DeclAttribute::shouldBeRejectedByParser (DK)) {
1840
+ parseNewDeclAttribute (Attributes, AtLoc, DK);
1841
+ return makeParserSuccess ();
1842
+ }
1831
1843
1832
1844
if (TypeAttributes::getAttrKindFromString (Tok.getText ()) != TAK_Count)
1833
1845
diagnose (Tok, diag::type_attribute_applied_to_decl);
@@ -1842,7 +1854,7 @@ bool Parser::parseDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc) {
1842
1854
if (Tok.is (tok::l_paren))
1843
1855
skipSingle ();
1844
1856
1845
- return true ;
1857
+ return ParserStatus (type) ;
1846
1858
}
1847
1859
1848
1860
// Parse the optional arguments.
@@ -1852,55 +1864,63 @@ bool Parser::parseDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc) {
1852
1864
SmallVector<SourceLoc, 2 > argLabelLocs;
1853
1865
Expr *trailingClosure = nullptr ;
1854
1866
bool hasInitializer = false ;
1867
+ ParserStatus status;
1855
1868
1856
1869
// If we're not in a local context, we'll need a context to parse
1857
1870
// initializers into (should we have one). This happens for properties
1858
1871
// and global variables in libraries.
1859
1872
PatternBindingInitializer *initContext = nullptr ;
1860
1873
1861
1874
if (Tok.isFollowingLParen ()) {
1862
-
1863
- // If we have no local context to parse the initial value into, create one
1864
- // for the PBD we'll eventually create. This allows us to have reasonable
1865
- // DeclContexts for any closures that may live inside of initializers.
1866
- Optional<ParseFunctionBody> initParser;
1867
- if (!CurDeclContext->isLocalContext ()) {
1868
- initContext = findAttributeInitContent (Attributes);
1869
- if (!initContext)
1870
- initContext = new (Context) PatternBindingInitializer (CurDeclContext);
1871
-
1872
- initParser.emplace (*this , initContext);
1875
+ if (peekToken ().is (tok::code_complete)) {
1876
+ consumeToken (tok::l_paren);
1877
+ if (CodeCompletion) {
1878
+ auto typeE = new (Context) TypeExpr (type.get ());
1879
+ auto CCE = new (Context) CodeCompletionExpr (Tok.getLoc ());
1880
+ CodeCompletion->completePostfixExprParen (typeE, CCE);
1881
+ }
1882
+ consumeToken (tok::code_complete);
1883
+ skipUntil (tok::r_paren);
1884
+ consumeIf (tok::r_paren);
1885
+ status.setHasCodeCompletion ();
1886
+ } else {
1887
+ // If we have no local context to parse the initial value into, create
1888
+ // one for the PBD we'll eventually create. This allows us to have
1889
+ // reasonable DeclContexts for any closures that may live inside of
1890
+ // initializers.
1891
+ Optional<ParseFunctionBody> initParser;
1892
+ if (!CurDeclContext->isLocalContext ()) {
1893
+ initContext = findAttributeInitContent (Attributes);
1894
+ if (!initContext)
1895
+ initContext =
1896
+ new (Context) PatternBindingInitializer (CurDeclContext);
1897
+
1898
+ initParser.emplace (*this , initContext);
1899
+ }
1900
+ status |= parseExprList (tok::l_paren, tok::r_paren,
1901
+ /* isPostfix=*/ false , /* isExprBasic=*/ true ,
1902
+ lParenLoc, args, argLabels, argLabelLocs,
1903
+ rParenLoc, trailingClosure,
1904
+ SyntaxKind::FunctionCallArgumentList);
1905
+ assert (!trailingClosure && " Cannot parse a trailing closure here" );
1906
+ hasInitializer = true ;
1873
1907
}
1874
-
1875
- ParserStatus status = parseExprList (tok::l_paren, tok::r_paren,
1876
- /* isPostfix=*/ false ,
1877
- /* isExprBasic=*/ true ,
1878
- lParenLoc, args, argLabels,
1879
- argLabelLocs,
1880
- rParenLoc,
1881
- trailingClosure,
1882
- SyntaxKind::FunctionCallArgumentList);
1883
- if (status.hasCodeCompletion ())
1884
- return true ;
1885
-
1886
- assert (!trailingClosure && " Cannot parse a trailing closure here" );
1887
- hasInitializer = true ;
1888
1908
}
1889
1909
1890
1910
// Form the attribute.
1891
1911
auto attr = CustomAttr::create (Context, AtLoc, type.get (), hasInitializer,
1892
1912
initContext, lParenLoc, args, argLabels,
1893
1913
argLabelLocs, rParenLoc);
1894
1914
Attributes.add (attr);
1895
- return false ;
1915
+ return status ;
1896
1916
}
1897
1917
1898
1918
// Recover by eating @foo(...) when foo is not known.
1899
1919
consumeToken ();
1900
1920
if (Tok.is (tok::l_paren))
1901
1921
skipSingle ();
1902
1922
1903
- return true ;
1923
+ return makeParserError () ;
1904
1924
}
1905
1925
1906
1926
bool Parser::canParseTypeAttribute () {
@@ -2180,30 +2200,18 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, bool justChecking) {
2180
2200
// / attribute-list-clause:
2181
2201
// / '@' attribute
2182
2202
// / \endverbatim
2183
- bool Parser::parseDeclAttributeList (DeclAttributes &Attributes,
2184
- bool &FoundCCToken) {
2185
- FoundCCToken = false ;
2203
+ ParserStatus Parser::parseDeclAttributeList (DeclAttributes &Attributes) {
2186
2204
if (Tok.isNot (tok::at_sign))
2187
- return false ;
2188
-
2189
- bool error = false ;
2205
+ return makeParserSuccess ();
2190
2206
2207
+ ParserStatus Status;
2191
2208
SyntaxParsingContext AttrListCtx (SyntaxContext, SyntaxKind::AttributeList);
2192
2209
do {
2193
- if (peekToken ().is (tok::code_complete)) {
2194
- consumeToken (tok::at_sign);
2195
- consumeToken (tok::code_complete);
2196
- FoundCCToken = true ;
2197
- continue ;
2198
- }
2199
2210
SyntaxParsingContext AttrCtx (SyntaxContext, SyntaxKind::Attribute);
2200
2211
SourceLoc AtLoc = consumeToken ();
2201
- if (parseDeclAttribute (Attributes, AtLoc)) {
2202
- // Consume any remaining attributes for better error recovery.
2203
- error = true ;
2204
- }
2212
+ Status |= parseDeclAttribute (Attributes, AtLoc);
2205
2213
} while (Tok.is (tok::at_sign));
2206
- return error ;
2214
+ return Status ;
2207
2215
}
2208
2216
2209
2217
// / \verbatim
@@ -2788,8 +2796,7 @@ Parser::parseDecl(ParseDeclOptions Flags,
2788
2796
DeclAttributes Attributes;
2789
2797
if (Tok.hasComment ())
2790
2798
Attributes.add (new (Context) RawDocCommentAttr (Tok.getCommentRange ()));
2791
- bool FoundCCTokenInAttr;
2792
- parseDeclAttributeList (Attributes, FoundCCTokenInAttr);
2799
+ ParserStatus AttrStatus = parseDeclAttributeList (Attributes);
2793
2800
2794
2801
// Parse modifiers.
2795
2802
// Keep track of where and whether we see a contextual keyword on the decl.
@@ -2936,15 +2943,6 @@ Parser::parseDecl(ParseDeclOptions Flags,
2936
2943
2937
2944
// Obvious nonsense.
2938
2945
default :
2939
- if (FoundCCTokenInAttr) {
2940
- if (!CodeCompletion) {
2941
- delayParseFromBeginningToHere (BeginParserPosition, Flags);
2942
- } else {
2943
- CodeCompletion->completeDeclAttrBeginning (nullptr , isInSILMode (),
2944
- false );
2945
- }
2946
- }
2947
-
2948
2946
diagnose (Tok, diag::expected_decl);
2949
2947
2950
2948
if (CurDeclContext) {
@@ -2960,7 +2958,6 @@ Parser::parseDecl(ParseDeclOptions Flags,
2960
2958
}
2961
2959
}
2962
2960
}
2963
- return makeParserErrorResult<Decl>();
2964
2961
}
2965
2962
2966
2963
if (DeclResult.isParseError () && Tok.is (tok::code_complete)) {
@@ -2999,22 +2996,9 @@ Parser::parseDecl(ParseDeclOptions Flags,
2999
2996
consumeToken (tok::code_complete);
3000
2997
}
3001
2998
3002
- if (auto SF = CurDeclContext->getParentSourceFile ()) {
3003
- if (!getScopeInfo ().isInactiveConfigBlock ()) {
3004
- for (auto Attr : Attributes) {
3005
- if (isa<ObjCAttr>(Attr) ||
3006
- /* Pre Swift 5 dymamic implied @objc */
3007
- (!Context.LangOpts .isSwiftVersionAtLeast (5 ) &&
3008
- isa<DynamicAttr>(Attr)))
3009
- SF->AttrsRequiringFoundation .insert (Attr);
3010
- }
3011
- }
3012
- }
3013
-
3014
- if (FoundCCTokenInAttr) {
2999
+ if (AttrStatus.hasCodeCompletion ()) {
3015
3000
if (CodeCompletion) {
3016
- CodeCompletion->completeDeclAttrBeginning (DeclResult.getPtrOrNull (),
3017
- isInSILMode (), false );
3001
+ CodeCompletion->setAttrTargetDecl (DeclResult.getPtrOrNull ());
3018
3002
} else {
3019
3003
delayParseFromBeginningToHere (BeginParserPosition, Flags);
3020
3004
return makeParserError ();
@@ -3030,6 +3014,18 @@ Parser::parseDecl(ParseDeclOptions Flags,
3030
3014
return makeParserError ();
3031
3015
}
3032
3016
3017
+ if (auto SF = CurDeclContext->getParentSourceFile ()) {
3018
+ if (!getScopeInfo ().isInactiveConfigBlock ()) {
3019
+ for (auto Attr : Attributes) {
3020
+ if (isa<ObjCAttr>(Attr) ||
3021
+ /* Pre Swift 5 dymamic implied @objc */
3022
+ (!Context.LangOpts .isSwiftVersionAtLeast (5 ) &&
3023
+ isa<DynamicAttr>(Attr)))
3024
+ SF->AttrsRequiringFoundation .insert (Attr);
3025
+ }
3026
+ }
3027
+ }
3028
+
3033
3029
if (DeclResult.isNonNull ()) {
3034
3030
Decl *D = DeclResult.get ();
3035
3031
if (!declWasHandledAlready (D))
@@ -4402,8 +4398,7 @@ static bool parseAccessorIntroducer(Parser &P,
4402
4398
AccessorKind &Kind,
4403
4399
SourceLoc &Loc) {
4404
4400
assert (Attributes.isEmpty ());
4405
- bool FoundCCToken;
4406
- P.parseDeclAttributeList (Attributes, FoundCCToken);
4401
+ P.parseDeclAttributeList (Attributes);
4407
4402
4408
4403
// Parse the contextual keywords for 'mutating' and 'nonmutating' before
4409
4404
// get and set.
0 commit comments