@@ -4212,10 +4212,12 @@ struct Parser::ParsedAccessors {
4212
4212
}
4213
4213
};
4214
4214
4215
- static bool parseAccessorIntroducer (Parser &P, DeclAttributes &Attributes,
4215
+ static bool parseAccessorIntroducer (Parser &P,
4216
+ DeclAttributes &Attributes,
4216
4217
AccessorKind &Kind,
4217
4218
AddressorKind &addressorKind,
4218
4219
SourceLoc &Loc) {
4220
+ assert (Attributes.isEmpty ());
4219
4221
bool FoundCCToken;
4220
4222
P.parseDeclAttributeList (Attributes, FoundCCToken);
4221
4223
@@ -4258,12 +4260,12 @@ static bool parseAccessorIntroducer(Parser &P, DeclAttributes &Attributes,
4258
4260
return false ;
4259
4261
}
4260
4262
4261
- bool Parser::parseGetSet (ParseDeclOptions Flags,
4262
- GenericParamList *GenericParams,
4263
- ParameterList *Indices,
4264
- TypeLoc ElementTy, ParsedAccessors &accessors,
4265
- AbstractStorageDecl *storage,
4266
- SourceLoc StaticLoc) {
4263
+ ParserStatus Parser::parseGetSet (ParseDeclOptions Flags,
4264
+ GenericParamList *GenericParams,
4265
+ ParameterList *Indices,
4266
+ TypeLoc ElementTy, ParsedAccessors &accessors,
4267
+ AbstractStorageDecl *storage,
4268
+ SourceLoc StaticLoc) {
4267
4269
assert (Tok.is (tok::l_brace));
4268
4270
4269
4271
// Properties in protocols use a very limited syntax.
@@ -4288,14 +4290,14 @@ bool Parser::parseGetSet(ParseDeclOptions Flags,
4288
4290
4289
4291
// In the limited syntax, fall out and let the caller handle it.
4290
4292
if (parsingLimitedSyntax)
4291
- return false ;
4293
+ return makeParserSuccess () ;
4292
4294
4293
4295
diagnose (accessors.RBLoc , diag::computed_property_no_accessors,
4294
4296
/* subscript*/ Indices != nullptr );
4295
- return true ;
4297
+ return makeParserError () ;
4296
4298
}
4297
4299
4298
- auto parseImplicitGetter = [&]() -> bool {
4300
+ auto parseImplicitGetter = [&]() {
4299
4301
assert (Tok.is (tok::l_brace));
4300
4302
accessors.LBLoc = Tok.getLoc ();
4301
4303
auto getter =
@@ -4306,14 +4308,14 @@ bool Parser::parseGetSet(ParseDeclOptions Flags,
4306
4308
accessors.add (getter);
4307
4309
parseAbstractFunctionBody (getter);
4308
4310
accessors.RBLoc = getter->getEndLoc ();
4309
- return false ;
4310
4311
};
4311
4312
4312
4313
// Prepare backtracking for implicit getter.
4313
4314
Optional<BacktrackingScope> backtrack;
4314
4315
backtrack.emplace (*this );
4315
4316
4316
4317
bool Invalid = false ;
4318
+ bool accessorHasCodeCompletion = false ;
4317
4319
bool IsFirstAccessor = true ;
4318
4320
accessors.LBLoc = consumeToken (tok::l_brace);
4319
4321
while (!Tok.isAny (tok::r_brace, tok::eof)) {
@@ -4331,6 +4333,29 @@ bool Parser::parseGetSet(ParseDeclOptions Flags,
4331
4333
AccessorCtx->setTransparent ();
4332
4334
AccessorCtx.reset ();
4333
4335
4336
+ if (Tok.is (tok::code_complete)) {
4337
+ if (CodeCompletion) {
4338
+ if (IsFirstAccessor && !parsingLimitedSyntax) {
4339
+ // If CC token is the first token after '{', it might be implicit
4340
+ // getter. Set up dummy accessor as the decl context to populate
4341
+ // 'self' decl.
4342
+ auto getter = createAccessorFunc (
4343
+ accessors.LBLoc , /* ValueNamePattern*/ nullptr , GenericParams,
4344
+ Indices, ElementTy, StaticLoc, Flags, AccessorKind::Get,
4345
+ AddressorKind::NotAddressor, storage, this ,
4346
+ /* AccessorKeywordLoc*/ SourceLoc ());
4347
+ accessors.add (getter);
4348
+ CodeCompletion->setParsedDecl (getter);
4349
+ } else {
4350
+ CodeCompletion->setParsedDecl (storage);
4351
+ }
4352
+ CodeCompletion->completeAccessorBeginning ();
4353
+ }
4354
+ consumeToken (tok::code_complete);
4355
+ accessorHasCodeCompletion = true ;
4356
+ break ;
4357
+ }
4358
+
4334
4359
// parsingLimitedSyntax mode cannot have a body.
4335
4360
if (parsingLimitedSyntax) {
4336
4361
diagnose (Tok, diag::expected_getset_in_protocol);
@@ -4350,7 +4375,8 @@ bool Parser::parseGetSet(ParseDeclOptions Flags,
4350
4375
// position.
4351
4376
backtrack.reset ();
4352
4377
AccessorListCtx.setTransparent ();
4353
- return parseImplicitGetter ();
4378
+ parseImplicitGetter ();
4379
+ return makeParserSuccess ();
4354
4380
}
4355
4381
IsFirstAccessor = false ;
4356
4382
@@ -4415,7 +4441,9 @@ bool Parser::parseGetSet(ParseDeclOptions Flags,
4415
4441
4416
4442
parseMatchingToken (tok::r_brace, accessors.RBLoc ,
4417
4443
diag::expected_rbrace_in_getset, accessors.LBLoc );
4418
- return Invalid;
4444
+ if (accessorHasCodeCompletion)
4445
+ return makeParserCodeCompletionStatus ();
4446
+ return Invalid ? makeParserError () : makeParserSuccess ();
4419
4447
}
4420
4448
4421
4449
static void fillInAccessorTypeErrors (Parser &P, FuncDecl *accessor,
@@ -4461,12 +4489,12 @@ static void fillInAccessorTypeErrors(Parser &P,
4461
4489
}
4462
4490
4463
4491
// / \brief Parse the brace-enclosed getter and setter for a variable.
4464
- VarDecl * Parser::parseDeclVarGetSet (Pattern *pattern,
4465
- ParseDeclOptions Flags,
4466
- SourceLoc StaticLoc, SourceLoc VarLoc,
4467
- bool hasInitializer,
4468
- const DeclAttributes &Attributes,
4469
- SmallVectorImpl<Decl *> &Decls) {
4492
+ ParserResult< VarDecl>
4493
+ Parser::parseDeclVarGetSet (Pattern *pattern, ParseDeclOptions Flags,
4494
+ SourceLoc StaticLoc, SourceLoc VarLoc,
4495
+ bool hasInitializer,
4496
+ const DeclAttributes &Attributes,
4497
+ SmallVectorImpl<Decl *> &Decls) {
4470
4498
bool Invalid = false ;
4471
4499
4472
4500
// The grammar syntactically requires a simple identifier for the variable
@@ -4539,8 +4567,12 @@ VarDecl *Parser::parseDeclVarGetSet(Pattern *pattern,
4539
4567
4540
4568
// Parse getter and setter.
4541
4569
ParsedAccessors accessors;
4542
- if (parseGetSet (Flags, /* GenericParams=*/ nullptr ,
4543
- /* Indices=*/ nullptr , TyLoc, accessors, storage, StaticLoc))
4570
+ auto AccessorStatus = parseGetSet (Flags, /* GenericParams=*/ nullptr ,
4571
+ /* Indices=*/ nullptr , TyLoc, accessors,
4572
+ storage, StaticLoc);
4573
+ if (AccessorStatus.hasCodeCompletion ())
4574
+ return makeParserCodeCompletionStatus ();
4575
+ if (AccessorStatus.isError ())
4544
4576
Invalid = true ;
4545
4577
4546
4578
// If we have an invalid case, bail out now.
@@ -4588,7 +4620,7 @@ VarDecl *Parser::parseDeclVarGetSet(Pattern *pattern,
4588
4620
accessors.record (*this , PrimaryVar, Invalid, Flags, StaticLoc,
4589
4621
Attributes, TyLoc, /* indices*/ nullptr , Decls);
4590
4622
4591
- return PrimaryVar;
4623
+ return makeParserResult ( PrimaryVar) ;
4592
4624
}
4593
4625
4594
4626
// / Add the given accessor to the collection of parsed accessors. If
@@ -5124,16 +5156,16 @@ Parser::parseDeclVar(ParseDeclOptions Flags,
5124
5156
// var-get-set clause, parse the var-get-set clause.
5125
5157
} else if (Tok.is (tok::l_brace)) {
5126
5158
HasAccessors = true ;
5127
-
5128
- if (auto *boundVar = parseDeclVarGetSet (pattern, Flags,
5129
- StaticLoc, VarLoc,
5130
- PatternInit != nullptr ,
5131
- Attributes, Decls)) {
5132
- if (PatternInit && !boundVar->hasStorage ()) {
5133
- diagnose (pattern->getLoc (), diag::getset_init)
5159
+ auto boundVar = parseDeclVarGetSet (pattern, Flags, StaticLoc, VarLoc,
5160
+ PatternInit != nullptr ,Attributes,
5161
+ Decls);
5162
+ if (boundVar.hasCodeCompletion ())
5163
+ return makeResult (makeParserCodeCompletionStatus ());
5164
+ if (PatternInit && boundVar.isNonNull () &&
5165
+ !boundVar.get ()->hasStorage ()) {
5166
+ diagnose (pattern->getLoc (), diag::getset_init)
5134
5167
.highlight (PatternInit->getSourceRange ());
5135
- PatternInit = nullptr ;
5136
- }
5168
+ PatternInit = nullptr ;
5137
5169
}
5138
5170
}
5139
5171
@@ -6225,10 +6257,9 @@ Parser::parseDeclSubscript(ParseDeclOptions Flags,
6225
6257
Status.setIsParseError ();
6226
6258
}
6227
6259
} else {
6228
- if (parseGetSet (Flags, GenericParams,
6229
- Indices.get (), ElementTy.get (),
6230
- accessors, Subscript, /* StaticLoc=*/ SourceLoc ()))
6231
- Status.setIsParseError ();
6260
+ Status |= parseGetSet (Flags, GenericParams,
6261
+ Indices.get (), ElementTy.get (),
6262
+ accessors, Subscript, /* StaticLoc=*/ SourceLoc ());
6232
6263
}
6233
6264
6234
6265
bool Invalid = false ;
0 commit comments