@@ -4080,6 +4080,11 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4080
4080
4081
4081
bool hasFuncIntroducer = false ;
4082
4082
bool hasVarIntroducer = false ;
4083
+ bool hasTypealiasIntroducer = false ;
4084
+ bool hasInitializerModifier = false ;
4085
+ bool hasAccessModifier = false ;
4086
+ bool hasOverride = false ;
4087
+ bool hasOverridabilityModifier = false ;
4083
4088
4084
4089
public:
4085
4090
CompletionOverrideLookup (CodeCompletionResultSink &Sink, ASTContext &Ctx,
@@ -4088,17 +4093,41 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4088
4093
: Sink(Sink), TypeResolver(createLazyResolver(Ctx)),
4089
4094
CurrDeclContext (CurrDeclContext), ParsedKeywords(ParsedKeywords) {
4090
4095
hasFuncIntroducer = isKeywordSpecified (" func" );
4091
- hasVarIntroducer = isKeywordSpecified (" var" ) || isKeywordSpecified (" let" );
4096
+ hasVarIntroducer = isKeywordSpecified (" var" ) ||
4097
+ isKeywordSpecified (" let" );
4098
+ hasTypealiasIntroducer = isKeywordSpecified (" typealias" );
4099
+ hasInitializerModifier = isKeywordSpecified (" required" ) ||
4100
+ isKeywordSpecified (" convenience" );
4101
+ hasAccessModifier = isKeywordSpecified (" private" ) ||
4102
+ isKeywordSpecified (" fileprivate" ) ||
4103
+ isKeywordSpecified (" internal" ) ||
4104
+ isKeywordSpecified (" public" ) ||
4105
+ isKeywordSpecified (" open" );
4106
+ hasOverride = isKeywordSpecified (" override" );
4107
+ hasOverridabilityModifier = isKeywordSpecified (" final" ) ||
4108
+ isKeywordSpecified (" open" );
4092
4109
}
4093
4110
4094
4111
bool isKeywordSpecified (StringRef Word) {
4095
4112
return std::find (ParsedKeywords.begin (), ParsedKeywords.end (), Word)
4096
4113
!= ParsedKeywords.end ();
4097
4114
}
4098
4115
4116
+ void addAccessControl (const ValueDecl *VD,
4117
+ CodeCompletionResultBuilder &Builder) {
4118
+ assert (CurrDeclContext->getAsGenericTypeOrGenericTypeExtensionContext ());
4119
+ auto AccessibilityOfContext =
4120
+ CurrDeclContext->getAsGenericTypeOrGenericTypeExtensionContext ()
4121
+ ->getFormalAccess ();
4122
+ auto Access = std::min (VD->getFormalAccess (), AccessibilityOfContext);
4123
+ // Only emit 'public', not needed otherwise.
4124
+ if (Access >= Accessibility::Public)
4125
+ Builder.addAccessControlKeyword (Access);
4126
+ }
4127
+
4099
4128
void addValueOverride (const ValueDecl *VD, DeclVisibilityKind Reason,
4100
4129
CodeCompletionResultBuilder &Builder,
4101
- StringRef DeclIntroducer = " " ) {
4130
+ bool hasDeclIntroducer ) {
4102
4131
4103
4132
class DeclNameOffsetLocatorPrinter : public StreamPrinter {
4104
4133
public:
@@ -4129,37 +4158,18 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4129
4158
NameOffset = Printer.NameOffset .getValue ();
4130
4159
}
4131
4160
4132
- assert (CurrDeclContext->getAsGenericTypeOrGenericTypeExtensionContext ());
4133
- Accessibility AccessibilityOfContext =
4134
- CurrDeclContext->getAsGenericTypeOrGenericTypeExtensionContext ()
4135
- ->getFormalAccess ();
4136
-
4137
- bool missingDeclIntroducer = !hasVarIntroducer && !hasFuncIntroducer;
4138
- bool missingAccess = !isKeywordSpecified (" private" ) &&
4139
- !isKeywordSpecified (" fileprivate" ) &&
4140
- !isKeywordSpecified (" internal" ) &&
4141
- !isKeywordSpecified (" public" );
4142
- bool missingOverride = Reason == DeclVisibilityKind::MemberOfSuper &&
4143
- !isKeywordSpecified (" override" );
4144
-
4145
- if (missingDeclIntroducer && missingAccess) {
4146
- auto Access = std::min (VD->getFormalAccess (), AccessibilityOfContext);
4147
- // Only emit 'public', not needed otherwise.
4148
- if (Access >= Accessibility::Public)
4149
- Builder.addAccessControlKeyword (Access);
4150
- }
4161
+ if (!hasDeclIntroducer && !hasAccessModifier)
4162
+ addAccessControl (VD, Builder);
4151
4163
4152
4164
// FIXME: if we're missing 'override', but have the decl introducer we
4153
4165
// should delete it and re-add both in the correct order.
4154
- if (missingDeclIntroducer && missingOverride)
4166
+ bool missingOverride = Reason == DeclVisibilityKind::MemberOfSuper &&
4167
+ !hasOverride;
4168
+ if (!hasDeclIntroducer && missingOverride)
4155
4169
Builder.addOverrideKeyword ();
4156
4170
4157
- if (missingDeclIntroducer) {
4158
- if (DeclIntroducer.empty ())
4159
- Builder.addDeclIntroducer (DeclStr.str ().substr (0 , NameOffset));
4160
- else
4161
- Builder.addDeclIntroducer (DeclIntroducer);
4162
- }
4171
+ if (!hasDeclIntroducer)
4172
+ Builder.addDeclIntroducer (DeclStr.str ().substr (0 , NameOffset));
4163
4173
4164
4174
Builder.addTextChunk (DeclStr.str ().substr (NameOffset));
4165
4175
}
@@ -4169,7 +4179,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4169
4179
Sink, CodeCompletionResult::ResultKind::Declaration,
4170
4180
SemanticContextKind::Super, {});
4171
4181
Builder.setAssociatedDecl (FD);
4172
- addValueOverride (FD, Reason, Builder);
4182
+ addValueOverride (FD, Reason, Builder, hasFuncIntroducer );
4173
4183
Builder.addBraceStmtWithCursor ();
4174
4184
}
4175
4185
@@ -4178,27 +4188,54 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4178
4188
Sink, CodeCompletionResult::ResultKind::Declaration,
4179
4189
SemanticContextKind::Super, {});
4180
4190
Builder.setAssociatedDecl (VD);
4181
- addValueOverride (VD, Reason, Builder);
4191
+ addValueOverride (VD, Reason, Builder, hasVarIntroducer );
4182
4192
}
4183
4193
4184
4194
void addTypeAlias (const AssociatedTypeDecl *ATD, DeclVisibilityKind Reason) {
4185
4195
CodeCompletionResultBuilder Builder (Sink,
4186
4196
CodeCompletionResult::ResultKind::Declaration,
4187
4197
SemanticContextKind::Super, {});
4188
4198
Builder.setAssociatedDecl (ATD);
4189
- addValueOverride (ATD, Reason, Builder, " typealias " );
4199
+ if (!hasTypealiasIntroducer && !hasAccessModifier)
4200
+ addAccessControl (ATD, Builder);
4201
+ if (!hasTypealiasIntroducer)
4202
+ Builder.addDeclIntroducer (" typealias " );
4203
+ Builder.addTextChunk (ATD->getName ().str ());
4190
4204
Builder.addTextChunk (" = " );
4191
4205
Builder.addSimpleNamedParameter (" Type" );
4192
4206
}
4193
4207
4194
- void addConstructor (const ConstructorDecl *CD) {
4208
+ void addConstructor (const ConstructorDecl *CD, DeclVisibilityKind Reason ) {
4195
4209
CodeCompletionResultBuilder Builder (
4196
4210
Sink,
4197
4211
CodeCompletionResult::ResultKind::Declaration,
4198
4212
SemanticContextKind::Super, {});
4199
4213
Builder.setAssociatedDecl (CD);
4200
4214
4215
+ if (!hasAccessModifier)
4216
+ addAccessControl (CD, Builder);
4217
+
4218
+ if (!hasOverride && Reason == DeclVisibilityKind::MemberOfSuper &&
4219
+ CD->isDesignatedInit () && !CD->isRequired ())
4220
+ Builder.addOverrideKeyword ();
4221
+
4222
+ // Emit 'required' if we're in class context, 'required' is not specified,
4223
+ // and 1) this is a protocol conformance and the class is not final, or 2)
4224
+ // this is subclass and the initializer is marked as required.
4225
+ bool needRequired = false ;
4226
+ auto C = CurrDeclContext->getAsClassOrClassExtensionContext ();
4227
+ if (C && !isKeywordSpecified (" required" )) {
4228
+ if (Reason ==
4229
+ DeclVisibilityKind::MemberOfProtocolImplementedByCurrentNominal &&
4230
+ !C->isFinal ())
4231
+ needRequired = true ;
4232
+ else if (Reason == DeclVisibilityKind::MemberOfSuper && CD->isRequired ())
4233
+ needRequired = true ;
4234
+ }
4235
+
4201
4236
llvm::SmallString<256 > DeclStr;
4237
+ if (needRequired)
4238
+ DeclStr += " required " ;
4202
4239
{
4203
4240
llvm::raw_svector_ostream OS (DeclStr);
4204
4241
PrintOptions Options;
@@ -4232,7 +4269,9 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4232
4269
if (!D->hasType ())
4233
4270
TypeResolver->resolveDeclSignature (D);
4234
4271
4235
- bool hasIntroducer = hasFuncIntroducer || hasVarIntroducer;
4272
+ bool hasIntroducer = hasFuncIntroducer ||
4273
+ hasVarIntroducer ||
4274
+ hasTypealiasIntroducer;
4236
4275
4237
4276
if (auto *FD = dyn_cast<FuncDecl>(D)) {
4238
4277
// We cannot override operators as members.
@@ -4243,30 +4282,31 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4243
4282
if (FD->isAccessor ())
4244
4283
return ;
4245
4284
4246
- if (!hasIntroducer || hasFuncIntroducer )
4285
+ if (hasFuncIntroducer || (!hasIntroducer && !hasInitializerModifier) )
4247
4286
addMethodOverride (FD, Reason);
4248
4287
return ;
4249
4288
}
4250
4289
4251
4290
if (auto *VD = dyn_cast<VarDecl>(D)) {
4252
- if (!hasIntroducer || hasVarIntroducer) {
4291
+ if (hasVarIntroducer || (!hasIntroducer && !hasInitializerModifier))
4253
4292
addVarOverride (VD, Reason);
4254
- }
4293
+ return ;
4255
4294
}
4256
4295
4257
4296
if (auto *CD = dyn_cast<ConstructorDecl>(D)) {
4258
4297
if (!isa<ProtocolDecl>(CD->getDeclContext ()))
4259
4298
return ;
4260
- if (hasIntroducer || isKeywordSpecified ( " override " ) )
4299
+ if (hasIntroducer || hasOverride || hasOverridabilityModifier )
4261
4300
return ;
4262
4301
if (CD->isRequired () || CD->isDesignatedInit ())
4263
- addConstructor (CD);
4302
+ addConstructor (CD, Reason );
4264
4303
return ;
4265
4304
}
4266
4305
}
4267
4306
4268
4307
void addDesignatedInitializers (Type CurrTy) {
4269
- if (hasFuncIntroducer || hasVarIntroducer || isKeywordSpecified (" override" ))
4308
+ if (hasFuncIntroducer || hasVarIntroducer || hasTypealiasIntroducer ||
4309
+ hasOverridabilityModifier)
4270
4310
return ;
4271
4311
4272
4312
assert (CurrTy);
@@ -4283,12 +4323,14 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4283
4323
if (Constructor->hasStubImplementation ())
4284
4324
continue ;
4285
4325
if (Constructor->isDesignatedInit ())
4286
- addConstructor (Constructor);
4326
+ addConstructor (Constructor, DeclVisibilityKind::MemberOfSuper );
4287
4327
}
4288
4328
}
4289
4329
4290
4330
void addAssociatedTypes (Type CurrTy) {
4291
- if (hasFuncIntroducer || hasVarIntroducer || isKeywordSpecified (" override" ))
4331
+ if (!hasTypealiasIntroducer &&
4332
+ (hasFuncIntroducer || hasVarIntroducer || hasInitializerModifier ||
4333
+ hasOverride || hasOverridabilityModifier))
4292
4334
return ;
4293
4335
4294
4336
NominalTypeDecl *NTD = CurrTy->getAnyNominal ();
0 commit comments