Skip to content

Commit bb9482b

Browse files
committed
[CodeCompletion][Parser] Completions for overridable static members
1 parent 003d601 commit bb9482b

File tree

6 files changed

+128
-14
lines changed

6 files changed

+128
-14
lines changed

include/swift/AST/PrintOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,9 @@ struct PrintOptions {
275275
/// '@sil_weak', '@sil_unmanaged'.
276276
bool PrintStorageRepresentationAttrs = false;
277277

278+
/// Whether to print 'static' or 'class' on static decls.
279+
bool PrintStaticKeyword = true;
280+
278281
/// Whether to print 'override' keyword on overridden decls.
279282
bool PrintOverrideKeyword = true;
280283

lib/AST/ASTPrinter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2403,7 +2403,7 @@ void PrintAST::visitVarDecl(VarDecl *decl) {
24032403
printAttributes(decl);
24042404
printAccess(decl);
24052405
if (!Options.SkipIntroducerKeywords) {
2406-
if (decl->isStatic())
2406+
if (decl->isStatic() && Options.PrintStaticKeyword)
24072407
printStaticKeyword(decl->getCorrectStaticSpelling());
24082408
if (decl->getKind() == DeclKind::Var
24092409
|| Options.PrintParameterSpecifiers) {
@@ -2679,7 +2679,7 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {
26792679
printSourceRange(Range, Ctx);
26802680
} else {
26812681
if (!Options.SkipIntroducerKeywords) {
2682-
if (decl->isStatic())
2682+
if (decl->isStatic() && Options.PrintStaticKeyword)
26832683
printStaticKeyword(decl->getCorrectStaticSpelling());
26842684
if (decl->isMutating() && !decl->getAttrs().hasAttribute<MutatingAttr>()) {
26852685
Printer.printKeyword("mutating", Options, " ");

lib/IDE/CodeCompletion.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3867,6 +3867,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
38673867
bool hasAccessModifier = false;
38683868
bool hasOverride = false;
38693869
bool hasOverridabilityModifier = false;
3870+
bool hasStaticOrClass = false;
38703871

38713872
public:
38723873
CompletionOverrideLookup(CodeCompletionResultSink &Sink, ASTContext &Ctx,
@@ -3891,6 +3892,8 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
38913892
hasOverride = isKeywordSpecified("override");
38923893
hasOverridabilityModifier = isKeywordSpecified("final") ||
38933894
isKeywordSpecified("open");
3895+
hasStaticOrClass = isKeywordSpecified(getTokenText(tok::kw_class)) ||
3896+
isKeywordSpecified(getTokenText(tok::kw_static));
38943897
}
38953898

38963899
bool isKeywordSpecified(StringRef Word) {
@@ -3942,6 +3945,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
39423945
Options.ExclusiveAttrList.push_back(TAK_escaping);
39433946
Options.PrintOverrideKeyword = false;
39443947
Options.PrintPropertyAccessors = false;
3948+
Options.PrintStaticKeyword = !hasStaticOrClass;
39453949
VD->print(Printer, Options);
39463950
NameOffset = Printer.NameOffset.getValue();
39473951
}
@@ -3951,7 +3955,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
39513955

39523956
// FIXME: if we're missing 'override', but have the decl introducer we
39533957
// should delete it and re-add both in the correct order.
3954-
if (!hasDeclIntroducer && missingOverride(Reason))
3958+
if (!hasDeclIntroducer && !hasStaticOrClass && missingOverride(Reason))
39553959
Builder.addOverrideKeyword();
39563960

39573961
if (!hasDeclIntroducer)
@@ -4048,7 +4052,9 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
40484052
if (D->shouldHideFromEditor())
40494053
return;
40504054

4051-
if (D->getAttrs().hasAttribute<FinalAttr>())
4055+
if (D->getAttrs().hasAttribute<FinalAttr>() ||
4056+
// A 'class' member with an initial value cannot be overriden either.
4057+
(D->isStatic() && D->getAttrs().hasAttribute<HasInitialValueAttr>()))
40524058
return;
40534059

40544060
if (!D->hasInterfaceType())
@@ -4058,6 +4064,15 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
40584064
hasVarIntroducer ||
40594065
hasTypealiasIntroducer;
40604066

4067+
if (hasStaticOrClass && !D->isStatic())
4068+
return;
4069+
4070+
// As per the current convention, only instance members are
4071+
// suggested if an introducer is not accompanied by a 'static' or
4072+
// 'class' modifier.
4073+
if (hasIntroducer && !hasStaticOrClass && D->isStatic())
4074+
return;
4075+
40614076
if (auto *FD = dyn_cast<FuncDecl>(D)) {
40624077
// We cannot override operators as members.
40634078
if (FD->isBinaryOperator() || FD->isUnaryOperator())
@@ -4081,7 +4096,8 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
40814096
if (auto *CD = dyn_cast<ConstructorDecl>(D)) {
40824097
if (!isa<ProtocolDecl>(CD->getDeclContext()))
40834098
return;
4084-
if (hasIntroducer || hasOverride || hasOverridabilityModifier)
4099+
if (hasIntroducer || hasOverride || hasOverridabilityModifier ||
4100+
hasStaticOrClass)
40854101
return;
40864102
if (CD->isRequired() || CD->isDesignatedInit())
40874103
addConstructor(CD, Reason);
@@ -4091,7 +4107,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
40914107

40924108
void addDesignatedInitializers(NominalTypeDecl *NTD) {
40934109
if (hasFuncIntroducer || hasVarIntroducer || hasTypealiasIntroducer ||
4094-
hasOverridabilityModifier)
4110+
hasOverridabilityModifier || hasStaticOrClass)
40954111
return;
40964112

40974113
const auto *CD = dyn_cast<ClassDecl>(NTD);
@@ -4114,7 +4130,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
41144130
void addAssociatedTypes(NominalTypeDecl *NTD) {
41154131
if (!hasTypealiasIntroducer &&
41164132
(hasFuncIntroducer || hasVarIntroducer || hasInitializerModifier ||
4117-
hasOverride || hasOverridabilityModifier))
4133+
hasOverride || hasOverridabilityModifier || hasStaticOrClass))
41184134
return;
41194135

41204136
for (auto Conformance : NTD->getAllConformances()) {
@@ -4145,9 +4161,11 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
41454161
Type CurrTy = CurrDeclContext->getSelfTypeInContext();
41464162
auto *NTD = CurrDeclContext->getSelfNominalTypeDecl();
41474163
if (CurrTy && !CurrTy->is<ErrorType>()) {
4148-
lookupVisibleMemberDecls(*this, CurrTy, CurrDeclContext,
4164+
// Look for overridable static members too.
4165+
Type Meta = MetatypeType::get(CurrTy);
4166+
lookupVisibleMemberDecls(*this, Meta, CurrDeclContext,
41494167
TypeResolver,
4150-
/*includeInstanceMembers=*/false);
4168+
/*includeInstanceMembers=*/true);
41514169
addDesignatedInitializers(NTD);
41524170
addAssociatedTypes(NTD);
41534171
}

lib/Parse/ParseDecl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2944,6 +2944,11 @@ Parser::parseDecl(ParseDeclOptions Flags,
29442944
// Other tokens are already accounted for.
29452945
break;
29462946
}
2947+
if (StaticSpelling == StaticSpellingKind::KeywordStatic) {
2948+
Keywords.push_back(getTokenText(tok::kw_static));
2949+
} else if (StaticSpelling == StaticSpellingKind::KeywordClass) {
2950+
Keywords.push_back(getTokenText(tok::kw_class));
2951+
}
29472952
for (auto attr : Attributes) {
29482953
Keywords.push_back(attr->getAttrName());
29492954
}

test/IDE/complete_override.swift

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@
130130
// RUN: %target-swift-ide-test -enable-objc-interop -code-completion -source-filename %s -code-completion-token=MODIFIER12 -code-completion-keywords=false | %FileCheck %s -check-prefix=MODIFIER9
131131
// RUN: %target-swift-ide-test -enable-objc-interop -code-completion -source-filename %s -code-completion-token=MODIFIER13 -code-completion-keywords=false | %FileCheck %s -check-prefix=MODIFIER13
132132
// RUN: %target-swift-ide-test -enable-objc-interop -code-completion -source-filename %s -code-completion-token=MODIFIER14 -code-completion-keywords=false | %FileCheck %s -check-prefix=MODIFIER9
133+
// RUN: %target-swift-ide-test -enable-objc-interop -code-completion -source-filename %s -code-completion-token=MODIFIER15 -code-completion-keywords=false | %FileCheck %s -check-prefix=MODIFIER15
134+
// RUN: %target-swift-ide-test -enable-objc-interop -code-completion -source-filename %s -code-completion-token=MODIFIER16 -code-completion-keywords=false | %FileCheck %s -check-prefix=MODIFIER15
135+
// RUN: %target-swift-ide-test -enable-objc-interop -code-completion -source-filename %s -code-completion-token=MODIFIER17 -code-completion-keywords=false | %FileCheck %s -check-prefix=MODIFIER15
136+
// RUN: %target-swift-ide-test -enable-objc-interop -code-completion -source-filename %s -code-completion-token=MODIFIER18 -code-completion-keywords=false | %FileCheck %s -check-prefix=MODIFIER15
137+
// RUN: %target-swift-ide-test -enable-objc-interop -code-completion -source-filename %s -code-completion-token=MODIFIER19 -code-completion-keywords=false | %FileCheck %s -check-prefix=MODIFIER13
138+
// RUN: %target-swift-ide-test -enable-objc-interop -code-completion -source-filename %s -code-completion-token=MODIFIER20 -code-completion-keywords=false | %FileCheck %s -check-prefix=MODIFIER13
139+
// RUN: %target-swift-ide-test -enable-objc-interop -code-completion -source-filename %s -code-completion-token=MODIFIER21 -code-completion-keywords=false | %FileCheck %s -check-prefix=MODIFIER21
140+
// RUN: %target-swift-ide-test -enable-objc-interop -code-completion -source-filename %s -code-completion-token=MODIFIER22 -code-completion-keywords=false | %FileCheck %s -check-prefix=MODIFIER21
141+
// RUN: %target-swift-ide-test -enable-objc-interop -code-completion -source-filename %s -code-completion-token=MODIFIER23 -code-completion-keywords=false | %FileCheck %s -check-prefix=MODIFIER23
142+
// RUN: %target-swift-ide-test -enable-objc-interop -code-completion -source-filename %s -code-completion-token=MODIFIER24 -code-completion-keywords=false | %FileCheck %s -check-prefix=MODIFIER23
133143

134144
// RUN: %target-swift-ide-test -enable-objc-interop -code-completion -source-filename %s -code-completion-token=PROTOINIT_NORM -code-completion-keywords=false | %FileCheck %s -check-prefix=PROTOINIT_NORM
135145
// RUN: %target-swift-ide-test -enable-objc-interop -code-completion -source-filename %s -code-completion-token=PROTOINIT_FINAL -code-completion-keywords=false | %FileCheck %s -check-prefix=PROTOINIT_FINAL
@@ -563,13 +573,26 @@ class Escaping : EscapingBase {
563573
// ESCAPING_1: Decl[InstanceMethod]/Super: method(_ x: @escaping (@escaping () -> ()) -> (() -> ())) -> ((@escaping () -> ()) -> ()) {|};
564574

565575
class OverrideBase {
576+
static let staticLet = 0
577+
static var staticVar = 0
578+
static var staticGetOnlyVar: Int { return 0 }
579+
580+
class let classLet = 0
581+
class var classVar = 0
582+
class var classGetOnlyVar: Int { return 0 }
583+
584+
static func staticMethod() {}
585+
class func classMethod() {}
586+
587+
let letDecl = 0
588+
var varDecl: Int = 0
589+
566590
init(x: Int) {}
567591
convenience init(y: Int) { self.init(x: y) }
568592
required init(a: Int) {}
569593
required convenience init(b: Int) {}
570594
func defaultMethod() {}
571595
final func finalMethod() {}
572-
var varDecl: Int = 0
573596
open func openMethod() {}
574597
}
575598
protocol OverrideP {
@@ -631,9 +654,49 @@ class Override14 : OverrideBase, OverrideP {
631654
override let #^MODIFIER14^#
632655
// Same as MODIFIER9.
633656
}
657+
class Override15 : OverrideBase, OverrideP {
658+
required static var #^MODIFIER15^#
659+
}
660+
class Override16 : OverrideBase, OverrideP {
661+
override class var #^MODIFIER16^#
662+
// Same as MODIFIER15
663+
}
664+
class Override17 : OverrideBase, OverrideP {
665+
// Note: This *does* emit variables. See MODIFIER14
666+
override static let #^MODIFIER17^#
667+
// Same as MODIFIER15
668+
}
669+
class Override18 : OverrideBase, OverrideP {
670+
class var #^MODIFIER18^#
671+
// Same as MODIFIER15
672+
}
673+
class Override19 : OverrideBase, OverrideP {
674+
// No completions.
675+
class let #^MODIFIER19^#
676+
}
677+
class Override20 : OverrideBase, OverrideP {
678+
// No completions.
679+
static let #^MODIFIER20^#
680+
}
681+
class Override21 : OverrideBase, OverrideP {
682+
override class func #^MODIFIER21^#
683+
}
684+
class Override22 : OverrideBase, OverrideP {
685+
class func #^MODIFIER22^#
686+
// Same as MODIFIER21
687+
}
688+
class Override23 : OverrideBase, OverrideP {
689+
static #^MODIFIER23^#
690+
}
691+
class Override24 : OverrideBase, OverrideP {
692+
override static #^MODIFIER24^#
693+
// Same as MODIFIER23
694+
}
634695

635-
// MODIFIER1: Begin completions, 7 items
696+
// MODIFIER1: Begin completions, 9 items
636697
// MODIFIER1-DAG: Decl[Constructor]/Super: required init(p: Int) {|}; name=required init(p: Int)
698+
// MODIFIER1-DAG: Decl[StaticMethod]/Super: override class func classMethod() {|}; name=classMethod()
699+
// MODIFIER1-DAG: Decl[StaticVar]/Super: override class var classGetOnlyVar: Int; name=classGetOnlyVar: Int
637700
// MODIFIER1-DAG: Decl[InstanceMethod]/Super: override func defaultMethod() {|}; name=defaultMethod()
638701
// MODIFIER1-DAG: Decl[InstanceMethod]/Super: override func openMethod() {|}; name=openMethod()
639702
// MODIFIER1-DAG: Decl[InstanceVar]/Super: override var varDecl: Int; name=varDecl: Int
@@ -642,7 +705,9 @@ class Override14 : OverrideBase, OverrideP {
642705
// MODIFIER1-DAG: Decl[AssociatedType]/Super: typealias Assoc = {#(Type)#}; name=Assoc = Type
643706
// MODIFIER1: End completions
644707

645-
// MODIFIER2: Begin completions, 3 items
708+
// MODIFIER2: Begin completions, 5 items
709+
// MODIFIER2-DAG: Decl[StaticVar]/Super: override class var classGetOnlyVar: Int; name=classGetOnlyVar: Int
710+
// MODIFIER2-DAG: Decl[StaticMethod]/Super: override class func classMethod() {|}; name=classMethod()
646711
// MODIFIER2-DAG: Decl[InstanceMethod]/Super: override func defaultMethod() {|}; name=defaultMethod()
647712
// MODIFIER2-DAG: Decl[InstanceMethod]/Super: override func openMethod() {|}; name=openMethod()
648713
// MODIFIER2-DAG: Decl[InstanceVar]/Super: override var varDecl: Int; name=varDecl: Int
@@ -664,7 +729,9 @@ class Override14 : OverrideBase, OverrideP {
664729
// MODIFIER6-DAG: Decl[AssociatedType]/Super: Assoc = {#(Type)#}; name=Assoc = Type
665730
// MODIFIER6: End completions
666731

667-
// MODIFIER7: Begin completions, 5 items
732+
// MODIFIER7: Begin completions, 7 items
733+
// MODIFIER7-DAG: Decl[StaticVar]/Super: class var classGetOnlyVar: Int; name=classGetOnlyVar: Int
734+
// MODIFIER7-DAG: Decl[StaticMethod]/Super: class func classMethod() {|}; name=classMethod()
668735
// MODIFIER7-DAG: Decl[InstanceMethod]/Super: func defaultMethod() {|}; name=defaultMethod()
669736
// MODIFIER7-DAG: Decl[InstanceVar]/Super: var varDecl: Int; name=varDecl: Int
670737
// MODIFIER7-DAG: Decl[InstanceMethod]/Super: func openMethod() {|}; name=openMethod()
@@ -683,6 +750,19 @@ class Override14 : OverrideBase, OverrideP {
683750

684751
// MODIFIER13-NOT: Begin completions
685752

753+
// MODIFIER15: Begin completions, 1 items
754+
// MODIFIER15-DAG: Decl[StaticVar]/Super: classGetOnlyVar: Int; name=classGetOnlyVar: Int
755+
// MODIFIER15: End completions
756+
757+
// MODIFIER21: Begin completions, 1 items
758+
// MODIFIER21: Decl[StaticMethod]/Super: classMethod() {|}; name=classMethod()
759+
// MODIFIER21: End completions
760+
761+
// MODIFIER23: Begin completions, 2 items
762+
// MODIFIER23-DAG: Decl[StaticMethod]/Super: func classMethod() {|}; name=classMethod()
763+
// MODIFIER23-DAG: Decl[StaticVar]/Super: var classGetOnlyVar: Int; name=classGetOnlyVar: Int
764+
// MODIFIER23: End completions
765+
686766
protocol RequiredP {
687767
init(p: Int)
688768
}

test/IDE/complete_override_objc.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,21 @@ class Sub : FooClassBase {
1010
#^PA^#
1111
}
1212

13-
// CHECK1: Begin completions, 8 items
13+
// CHECK1: Begin completions, 16 items
14+
// CHECK1: Decl[StaticMethod]/Super: override class func fooBaseInstanceFunc0() {|}
1415
// CHECK1: Decl[InstanceMethod]/Super: override func fooBaseInstanceFunc0() {|}
16+
// CHECK1: Decl[StaticMethod]/Super: override class func fooBaseInstanceFunc1(_ anObject: Any!) -> FooClassBase! {|}
1517
// CHECK1: Decl[InstanceMethod]/Super: override func fooBaseInstanceFunc1(_ anObject: Any!) -> FooClassBase! {|}
18+
// CHECK1: Decl[StaticMethod]/Super: override class func fooBaseInstanceFuncOverridden() {|}
1619
// CHECK1: Decl[InstanceMethod]/Super: override func fooBaseInstanceFuncOverridden() {|}
20+
// CHECK1: Decl[StaticMethod]/Super: override class func fooBaseClassFunc0() {|}
21+
// CHECK1: Decl[StaticMethod]/Super: override class func _internalMeth3() -> Any! {|}
1722
// CHECK1: Decl[InstanceMethod]/Super: override func _internalMeth3() -> Any! {|}
23+
// CHECK1: Decl[StaticMethod]/Super: override class func _internalMeth2() -> Any! {|}
1824
// CHECK1: Decl[InstanceMethod]/Super: override func _internalMeth2() -> Any! {|}
25+
// CHECK1: Decl[StaticMethod]/Super: override class func nonInternalMeth() -> Any! {|}
1926
// CHECK1: Decl[InstanceMethod]/Super: override func nonInternalMeth() -> Any! {|}
27+
// CHECK1: Decl[StaticMethod]/Super: override class func _internalMeth1() -> Any! {|}
2028
// CHECK1: Decl[InstanceMethod]/Super: override func _internalMeth1() -> Any! {|}
2129
// CHECK1: Decl[Constructor]/Super: override init!() {|}
2230
// CHECK1: End completions

0 commit comments

Comments
 (0)