Skip to content

Commit 2fdfc74

Browse files
authored
Merge pull request #4247 from benlangmuir/completion-escaping-attr
[codecompletion] Add @escaping to override completions
2 parents cd7c802 + 89fd31d commit 2fdfc74

File tree

7 files changed

+82
-32
lines changed

7 files changed

+82
-32
lines changed

include/swift/AST/PrintOptions.h

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,36 @@ class BracketOptions {
110110
}
111111
};
112112

113+
/// A union of DeclAttrKind and TypeAttrKind.
114+
class AnyAttrKind {
115+
unsigned kind : 31;
116+
unsigned isType : 1;
117+
118+
public:
119+
AnyAttrKind(TypeAttrKind K) : kind(static_cast<unsigned>(K)), isType(1) {
120+
static_assert(TAK_Count < UINT_MAX, "TypeAttrKind is > 31 bits");
121+
}
122+
AnyAttrKind(DeclAttrKind K) : kind(static_cast<unsigned>(K)), isType(0) {
123+
static_assert(DAK_Count < UINT_MAX, "DeclAttrKind is > 31 bits");
124+
}
125+
AnyAttrKind() : kind(TAK_Count), isType(1) {}
126+
AnyAttrKind(const AnyAttrKind &) = default;
127+
128+
/// Returns the TypeAttrKind, or TAK_Count if this is not a type attribute.
129+
TypeAttrKind type() const {
130+
return isType ? static_cast<TypeAttrKind>(kind) : TAK_Count;
131+
}
132+
/// Returns the DeclAttrKind, or DAK_Count if this is not a decl attribute.
133+
DeclAttrKind decl() const {
134+
return isType ? DAK_Count : static_cast<DeclAttrKind>(kind);
135+
}
136+
137+
bool operator==(AnyAttrKind K) const {
138+
return kind == K.kind && isType == K.isType;
139+
}
140+
bool operator!=(AnyAttrKind K) const { return !(*this == K); }
141+
};
142+
113143
/// Options for printing AST nodes.
114144
///
115145
/// A default-constructed PrintOptions is suitable for printing to users;
@@ -225,12 +255,12 @@ struct PrintOptions {
225255
bool PrintUserInaccessibleAttrs = true;
226256

227257
/// List of attribute kinds that should not be printed.
228-
std::vector<DeclAttrKind> ExcludeAttrList =
258+
std::vector<AnyAttrKind> ExcludeAttrList =
229259
{ DAK_Transparent, DAK_Effects, DAK_FixedLayout };
230260

231261
/// List of attribute kinds that should be printed exclusively.
232262
/// Empty means allow all.
233-
std::vector<DeclAttrKind> ExclusiveAttrList;
263+
std::vector<AnyAttrKind> ExclusiveAttrList;
234264

235265
/// Whether to print function @convention attribute on function types.
236266
bool PrintFunctionRepresentationAttrs = true;
@@ -326,6 +356,16 @@ struct PrintOptions {
326356

327357
BracketOptions BracketOptions;
328358

359+
bool excludeAttrKind(AnyAttrKind K) const {
360+
if (std::any_of(ExcludeAttrList.begin(), ExcludeAttrList.end(),
361+
[K](AnyAttrKind other) { return other == K; }))
362+
return true;
363+
if (!ExclusiveAttrList.empty())
364+
return std::none_of(ExclusiveAttrList.begin(), ExclusiveAttrList.end(),
365+
[K](AnyAttrKind other) { return other == K; });
366+
return false;
367+
}
368+
329369
/// Retrieve the set of options for verbose printing to users.
330370
static PrintOptions printVerbose() {
331371
PrintOptions result;

include/swift/AST/TypeRepr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ class AttributedTypeRepr : public TypeRepr {
166166
TypeRepr *getTypeRepr() const { return Ty; }
167167

168168
void printAttrs(llvm::raw_ostream &OS) const;
169-
void printAttrs(ASTPrinter &Printer) const;
169+
void printAttrs(ASTPrinter &Printer, const PrintOptions &Options) const;
170170

171171
static bool classof(const TypeRepr *T) {
172172
return T->getKind() == TypeReprKind::Attributed;

lib/AST/ASTPrinter.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,12 @@ class PrintAST : public ASTVisitor<PrintAST> {
11721172
void printTypeLoc(const TypeLoc &TL) {
11731173
if (Options.TransformContext && TL.getType()) {
11741174
if (auto RT = Options.TransformContext->transform(TL.getType())) {
1175+
// FIXME: it's not clear exactly what we want to keep from the existing
1176+
// options, and what we want to discard.
11751177
PrintOptions FreshOptions;
1178+
FreshOptions.PrintAsInParamType = Options.PrintAsInParamType;
1179+
FreshOptions.ExcludeAttrList = Options.ExcludeAttrList;
1180+
FreshOptions.ExclusiveAttrList = Options.ExclusiveAttrList;
11761181
RT.print(Printer, FreshOptions);
11771182
return;
11781183
}
@@ -2527,10 +2532,8 @@ void PrintAST::visitVarDecl(VarDecl *decl) {
25272532

25282533
void PrintAST::visitParamDecl(ParamDecl *decl) {
25292534
// Set and restore in-parameter-position printing of types
2530-
auto prior = Options.PrintAsInParamType;
2531-
Options.PrintAsInParamType = true;
2535+
llvm::SaveAndRestore<bool> savePrintParam(Options.PrintAsInParamType, true);
25322536
visitVarDecl(decl);
2533-
Options.PrintAsInParamType = prior;
25342537
}
25352538

25362539
void PrintAST::printOneParameter(const ParamDecl *param, bool Curried,
@@ -2585,10 +2588,8 @@ void PrintAST::printOneParameter(const ParamDecl *param, bool Curried,
25852588
}
25862589

25872590
// Set and restore in-parameter-position printing of types
2588-
auto prior = Options.PrintAsInParamType;
2589-
Options.PrintAsInParamType = true;
2591+
llvm::SaveAndRestore<bool> savePrintParam(Options.PrintAsInParamType, true);
25902592
printTypeLoc(TheTypeLoc);
2591-
Options.PrintAsInParamType = prior;
25922593

25932594
if (param->isVariadic())
25942595
Printer << "...";
@@ -3768,16 +3769,18 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
37683769
if (Options.SkipAttributes)
37693770
return;
37703771

3771-
if (info.isAutoClosure()) {
3772+
if (info.isAutoClosure() && !Options.excludeAttrKind(TAK_autoclosure)) {
37723773
Printer.printAttrName("@autoclosure");
37733774
Printer << " ";
37743775
}
3775-
if (inParameterPrinting && !info.isNoEscape()) {
3776+
if (inParameterPrinting && !info.isNoEscape() &&
3777+
!Options.excludeAttrKind(TAK_escaping)) {
37763778
Printer.printAttrName("@escaping");
37773779
Printer << " ";
37783780
}
37793781

3780-
if (Options.PrintFunctionRepresentationAttrs) {
3782+
if (Options.PrintFunctionRepresentationAttrs &&
3783+
!Options.excludeAttrKind(TAK_convention)) {
37813784
// TODO: coalesce into a single convention attribute.
37823785
switch (info.getSILRepresentation()) {
37833786
case SILFunctionType::Representation::Thick:

lib/AST/Attr.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -249,16 +249,8 @@ void DeclAttributes::print(ASTPrinter &Printer,
249249
if (!Options.PrintUserInaccessibleAttrs &&
250250
DeclAttribute::isUserInaccessible(DA->getKind()))
251251
continue;
252-
if (std::find(Options.ExcludeAttrList.begin(),
253-
Options.ExcludeAttrList.end(),
254-
DA->getKind()) != Options.ExcludeAttrList.end())
252+
if (Options.excludeAttrKind(DA->getKind()))
255253
continue;
256-
if (!Options.ExclusiveAttrList.empty()) {
257-
if (std::find(Options.ExclusiveAttrList.begin(),
258-
Options.ExclusiveAttrList.end(),
259-
DA->getKind()) == Options.ExclusiveAttrList.end())
260-
continue;
261-
}
262254

263255
AttributeVector &which = DA->isDeclModifier() ? modifiers :
264256
isShortAvailable(DA) ? shortAvailableAttributes :

lib/AST/TypeRepr.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -264,36 +264,43 @@ void ErrorTypeRepr::printImpl(ASTPrinter &Printer,
264264

265265
void AttributedTypeRepr::printImpl(ASTPrinter &Printer,
266266
const PrintOptions &Opts) const {
267-
printAttrs(Printer);
267+
printAttrs(Printer, Opts);
268268
printTypeRepr(Ty, Printer, Opts);
269269
}
270270

271271
void AttributedTypeRepr::printAttrs(llvm::raw_ostream &OS) const {
272272
StreamPrinter Printer(OS);
273-
printAttrs(Printer);
273+
printAttrs(Printer, PrintOptions());
274274
}
275275

276-
void AttributedTypeRepr::printAttrs(ASTPrinter &Printer) const {
276+
void AttributedTypeRepr::printAttrs(ASTPrinter &Printer,
277+
const PrintOptions &Options) const {
277278
const TypeAttributes &Attrs = getAttrs();
278279

279-
if (Attrs.has(TAK_autoclosure)) {
280+
auto hasAttr = [&](TypeAttrKind K) -> bool {
281+
if (Options.excludeAttrKind(K))
282+
return false;
283+
return Attrs.has(K);
284+
};
285+
286+
if (hasAttr(TAK_autoclosure)) {
280287
Printer.printAttrName("@autoclosure");
281288
Printer << " ";
282289
}
283-
if (Attrs.has(TAK_escaping)) {
290+
if (hasAttr(TAK_escaping)) {
284291
Printer.printAttrName("@escaping");
285292
Printer << " ";
286293
}
287294

288-
if (Attrs.has(TAK_thin)) {
295+
if (hasAttr(TAK_thin)) {
289296
Printer.printAttrName("@thin");
290297
Printer << " ";
291298
}
292-
if (Attrs.has(TAK_thick)) {
299+
if (hasAttr(TAK_thick)) {
293300
Printer.printAttrName("@thick");
294301
Printer << " ";
295302
}
296-
if (Attrs.convention.hasValue()) {
303+
if (hasAttr(TAK_convention) && Attrs.convention.hasValue()) {
297304
Printer.printAttrName("@convention");
298305
Printer << "(" << Attrs.convention.getValue() << ") ";
299306
}

lib/IDE/CodeCompletion.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4117,7 +4117,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
41174117
Options.setArchetypeSelfTransform(transformType, VD->getDeclContext());
41184118
Options.PrintDefaultParameterPlaceholder = false;
41194119
Options.PrintImplicitAttrs = false;
4120-
Options.SkipAttributes = true;
4120+
Options.ExclusiveAttrList.push_back(TAK_escaping);
41214121
Options.PrintOverrideKeyword = false;
41224122
Options.PrintPropertyAccessors = false;
41234123
VD->print(Printer, Options);

test/IDE/complete_override.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ASSOC_TYPE1 -code-completion-keywords=false | %FileCheck %s -check-prefix=ASSOC_TYPE1
106106

107107
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEPRECATED_1 -code-completion-keywords=false | %FileCheck %s -check-prefix=DEPRECATED_1
108+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ESCAPING_1 -code-completion-keywords=false | %FileCheck %s -check-prefix=ESCAPING_1
108109

109110
@objc
110111
class TagPA {}
@@ -463,8 +464,7 @@ class TestClassWithThrows : HasThrowing, HasThrowingProtocol {
463464
// HAS_THROWING: Begin completions
464465
// HAS_THROWING-DAG: Decl[InstanceMethod]/Super: func foo() throws {|}; name=foo() throws
465466
// HAS_THROWING-DAG: Decl[InstanceMethod]/Super: override func bar() throws {|}; name=bar() throws
466-
// FIXME: SR-2214 make the below require printing @escaping
467-
// HAS_THROWING-DAG: Decl[InstanceMethod]/Super: override func baz(x: {{(@escaping )?}}() throws -> ()) rethrows {|}; name=baz(x: {{(@escaping )?}}() throws -> ()) rethrows
467+
// HAS_THROWING-DAG: Decl[InstanceMethod]/Super: override func baz(x: @escaping () throws -> ()) rethrows {|}; name=baz(x: {{(@escaping )?}}() throws -> ()) rethrows
468468
// HAS_THROWING-DAG: Decl[Constructor]/Super: init() throws {|}; name=init() throws
469469
// HAS_THROWING: End completions
470470

@@ -490,3 +490,11 @@ class Deprecated2 : Deprecated1 {
490490
override func #^DEPRECATED_1^#
491491
}
492492
// DEPRECATED_1: Decl[InstanceMethod]/Super/NotRecommended: deprecated() {|};
493+
494+
class EscapingBase {
495+
func method(_ x: @escaping (@escaping ()->()) -> (@escaping ()->())) -> (@escaping (@escaping ()->() )->()) { }
496+
}
497+
class Escaping : EscapingBase {
498+
override func #^ESCAPING_1^#
499+
}
500+
// ESCAPING_1: Decl[InstanceMethod]/Super: method(_ x: @escaping (@escaping () -> ()) -> (@escaping () -> ())) -> ((@escaping () -> ()) -> ()) {|};

0 commit comments

Comments
 (0)