@@ -1250,6 +1250,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
1250
1250
Optional<StmtKind> ParentStmtKind;
1251
1251
1252
1252
SmallVector<StringRef, 3 > ParsedKeywords;
1253
+ SourceLoc introducerLoc;
1253
1254
1254
1255
std::vector<std::pair<std::string, bool >> SubModuleNameVisibilityPairs;
1255
1256
@@ -1348,7 +1349,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
1348
1349
void completeDeclAttrParam (DeclAttrKind DK, int Index) override ;
1349
1350
void completeInPrecedenceGroup (SyntaxKind SK) override ;
1350
1351
void completeNominalMemberBeginning (
1351
- SmallVectorImpl<StringRef> &Keywords) override ;
1352
+ SmallVectorImpl<StringRef> &Keywords, SourceLoc introducerLoc ) override ;
1352
1353
void completeAccessorBeginning () override ;
1353
1354
1354
1355
void completePoundAvailablePlatform () override ;
@@ -3858,9 +3859,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3858
3859
3859
3860
class CompletionOverrideLookup : public swift ::VisibleDeclConsumer {
3860
3861
CodeCompletionResultSink &Sink;
3862
+ ASTContext &Ctx;
3861
3863
const DeclContext *CurrDeclContext;
3862
3864
LazyResolver *TypeResolver;
3863
3865
SmallVectorImpl<StringRef> &ParsedKeywords;
3866
+ SourceLoc introducerLoc;
3864
3867
3865
3868
bool hasFuncIntroducer = false ;
3866
3869
bool hasVarIntroducer = false ;
@@ -3869,13 +3872,15 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
3869
3872
bool hasAccessModifier = false ;
3870
3873
bool hasOverride = false ;
3871
3874
bool hasOverridabilityModifier = false ;
3875
+ bool hasStaticOrClass = false ;
3872
3876
3873
3877
public:
3874
3878
CompletionOverrideLookup (CodeCompletionResultSink &Sink, ASTContext &Ctx,
3875
3879
const DeclContext *CurrDeclContext,
3876
- SmallVectorImpl<StringRef> &ParsedKeywords)
3877
- : Sink(Sink),
3878
- CurrDeclContext (CurrDeclContext), ParsedKeywords(ParsedKeywords) {
3880
+ SmallVectorImpl<StringRef> &ParsedKeywords,
3881
+ SourceLoc introducerLoc)
3882
+ : Sink(Sink), Ctx(Ctx), CurrDeclContext(CurrDeclContext),
3883
+ ParsedKeywords (ParsedKeywords), introducerLoc(introducerLoc) {
3879
3884
(void )createTypeChecker (Ctx);
3880
3885
TypeResolver = Ctx.getLazyResolver ();
3881
3886
@@ -3893,6 +3898,8 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
3893
3898
hasOverride = isKeywordSpecified (" override" );
3894
3899
hasOverridabilityModifier = isKeywordSpecified (" final" ) ||
3895
3900
isKeywordSpecified (" open" );
3901
+ hasStaticOrClass = isKeywordSpecified (getTokenText (tok::kw_class)) ||
3902
+ isKeywordSpecified (getTokenText (tok::kw_static));
3896
3903
}
3897
3904
3898
3905
bool isKeywordSpecified (StringRef Word) {
@@ -3942,19 +3949,28 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
3942
3949
Options.setBaseType (transformType);
3943
3950
Options.PrintImplicitAttrs = false ;
3944
3951
Options.ExclusiveAttrList .push_back (TAK_escaping);
3952
+ Options.ExclusiveAttrList .push_back (TAK_autoclosure);
3945
3953
Options.PrintOverrideKeyword = false ;
3946
3954
Options.PrintPropertyAccessors = false ;
3955
+ Options.PrintStaticKeyword = !hasStaticOrClass;
3947
3956
VD->print (Printer, Options);
3948
3957
NameOffset = Printer.NameOffset .getValue ();
3949
3958
}
3950
3959
3951
3960
if (!hasDeclIntroducer && !hasAccessModifier)
3952
3961
addAccessControl (VD, Builder);
3953
3962
3954
- // FIXME: if we're missing 'override', but have the decl introducer we
3955
- // should delete it and re-add both in the correct order.
3956
- if (!hasDeclIntroducer && missingOverride (Reason))
3957
- Builder.addOverrideKeyword ();
3963
+ if (missingOverride (Reason)) {
3964
+ if (!hasDeclIntroducer)
3965
+ Builder.addOverrideKeyword ();
3966
+ else {
3967
+ auto dist = Ctx.SourceMgr .getByteDistance (
3968
+ introducerLoc, Ctx.SourceMgr .getCodeCompletionLoc ());
3969
+ Builder.setNumBytesToErase (dist);
3970
+ Builder.addOverrideKeyword ();
3971
+ Builder.addDeclIntroducer (DeclStr.str ().substr (0 , NameOffset));
3972
+ }
3973
+ }
3958
3974
3959
3975
if (!hasDeclIntroducer)
3960
3976
Builder.addDeclIntroducer (DeclStr.str ().substr (0 , NameOffset));
@@ -4050,7 +4066,9 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4050
4066
if (D->shouldHideFromEditor ())
4051
4067
return ;
4052
4068
4053
- if (D->getAttrs ().hasAttribute <FinalAttr>())
4069
+ if (D->getAttrs ().hasAttribute <FinalAttr>() ||
4070
+ // A 'class' member with an initial value cannot be overriden either.
4071
+ (D->isStatic () && D->getAttrs ().hasAttribute <HasInitialValueAttr>()))
4054
4072
return ;
4055
4073
4056
4074
if (!D->hasInterfaceType ())
@@ -4060,6 +4078,15 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4060
4078
hasVarIntroducer ||
4061
4079
hasTypealiasIntroducer;
4062
4080
4081
+ if (hasStaticOrClass && !D->isStatic ())
4082
+ return ;
4083
+
4084
+ // As per the current convention, only instance members are
4085
+ // suggested if an introducer is not accompanied by a 'static' or
4086
+ // 'class' modifier.
4087
+ if (hasIntroducer && !hasStaticOrClass && D->isStatic ())
4088
+ return ;
4089
+
4063
4090
if (auto *FD = dyn_cast<FuncDecl>(D)) {
4064
4091
// We cannot override operators as members.
4065
4092
if (FD->isBinaryOperator () || FD->isUnaryOperator ())
@@ -4083,7 +4110,8 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4083
4110
if (auto *CD = dyn_cast<ConstructorDecl>(D)) {
4084
4111
if (!isa<ProtocolDecl>(CD->getDeclContext ()))
4085
4112
return ;
4086
- if (hasIntroducer || hasOverride || hasOverridabilityModifier)
4113
+ if (hasIntroducer || hasOverride || hasOverridabilityModifier ||
4114
+ hasStaticOrClass)
4087
4115
return ;
4088
4116
if (CD->isRequired () || CD->isDesignatedInit ())
4089
4117
addConstructor (CD, Reason);
@@ -4093,7 +4121,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4093
4121
4094
4122
void addDesignatedInitializers (NominalTypeDecl *NTD) {
4095
4123
if (hasFuncIntroducer || hasVarIntroducer || hasTypealiasIntroducer ||
4096
- hasOverridabilityModifier)
4124
+ hasOverridabilityModifier || hasStaticOrClass )
4097
4125
return ;
4098
4126
4099
4127
const auto *CD = dyn_cast<ClassDecl>(NTD);
@@ -4116,7 +4144,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4116
4144
void addAssociatedTypes (NominalTypeDecl *NTD) {
4117
4145
if (!hasTypealiasIntroducer &&
4118
4146
(hasFuncIntroducer || hasVarIntroducer || hasInitializerModifier ||
4119
- hasOverride || hasOverridabilityModifier))
4147
+ hasOverride || hasOverridabilityModifier || hasStaticOrClass ))
4120
4148
return ;
4121
4149
4122
4150
for (auto Conformance : NTD->getAllConformances ()) {
@@ -4147,9 +4175,11 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4147
4175
Type CurrTy = CurrDeclContext->getSelfTypeInContext ();
4148
4176
auto *NTD = CurrDeclContext->getSelfNominalTypeDecl ();
4149
4177
if (CurrTy && !CurrTy->is <ErrorType>()) {
4150
- lookupVisibleMemberDecls (*this , CurrTy, CurrDeclContext,
4178
+ // Look for overridable static members too.
4179
+ Type Meta = MetatypeType::get (CurrTy);
4180
+ lookupVisibleMemberDecls (*this , Meta, CurrDeclContext,
4151
4181
TypeResolver,
4152
- /* includeInstanceMembers=*/ false );
4182
+ /* includeInstanceMembers=*/ true );
4153
4183
addDesignatedInitializers (NTD);
4154
4184
addAssociatedTypes (NTD);
4155
4185
}
@@ -4471,8 +4501,9 @@ void CodeCompletionCallbacksImpl::completeGenericParams(TypeLoc TL) {
4471
4501
}
4472
4502
4473
4503
void CodeCompletionCallbacksImpl::completeNominalMemberBeginning (
4474
- SmallVectorImpl<StringRef> &Keywords) {
4504
+ SmallVectorImpl<StringRef> &Keywords, SourceLoc introducerLoc ) {
4475
4505
assert (!InEnumElementRawValue);
4506
+ this ->introducerLoc = introducerLoc;
4476
4507
ParsedKeywords.clear ();
4477
4508
ParsedKeywords.append (Keywords.begin (), Keywords.end ());
4478
4509
Kind = CompletionKind::NominalMemberBeginning;
@@ -4651,10 +4682,11 @@ void CodeCompletionCallbacksImpl::addKeywords(CodeCompletionResultSink &Sink,
4651
4682
break ;
4652
4683
4653
4684
case CompletionKind::NominalMemberBeginning: {
4654
- bool HasDeclIntroducer = llvm::find_if (ParsedKeywords, [](const StringRef kw) {
4685
+ bool HasDeclIntroducer = llvm::find_if (ParsedKeywords,
4686
+ [this ](const StringRef kw) {
4655
4687
return llvm::StringSwitch<bool >(kw)
4656
4688
.Case (" associatedtype" , true )
4657
- .Case (" class" , true )
4689
+ .Case (" class" , !CurDeclContext || !isa<ClassDecl>(CurDeclContext) )
4658
4690
.Case (" deinit" , true )
4659
4691
.Case (" enum" , true )
4660
4692
.Case (" extension" , true )
@@ -5027,7 +5059,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
5027
5059
case CompletionKind::NominalMemberBeginning: {
5028
5060
CompletionOverrideLookup OverrideLookup (CompletionContext.getResultSink (),
5029
5061
P.Context , CurDeclContext,
5030
- ParsedKeywords);
5062
+ ParsedKeywords, introducerLoc );
5031
5063
OverrideLookup.getOverrideCompletions (SourceLoc ());
5032
5064
break ;
5033
5065
}
0 commit comments