Skip to content

Commit 73d3fd6

Browse files
authored
Merge pull request #24177 from rintaro/sourcekit-opaque-result-types
[SourceKit] SourceKit support for opaque result types
2 parents 0785fd7 + 4773808 commit 73d3fd6

24 files changed

+477
-48
lines changed

include/swift/AST/ASTPrinter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ class ASTPrinter {
118118
/// Callers should use callPrintDeclPost().
119119
virtual void printDeclPost(const Decl *D, Optional<BracketOptions> Bracket) {}
120120

121+
/// Called before printing the result type of the declaration. Printer can
122+
/// replace \p TL to customize the input.
123+
virtual void printDeclResultTypePre(ValueDecl *VD, TypeLoc &TL) {}
124+
121125
/// Called before printing a type.
122126
virtual void printTypePre(const TypeLoc &TL) {}
123127
/// Called after printing a type.

include/swift/AST/PrintOptions.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ struct PrintOptions {
135135
/// Whether to print *any* accessors on properties.
136136
bool PrintPropertyAccessors = true;
137137

138+
/// Whether to print *any* accessors on subscript.
139+
bool PrintSubscriptAccessors = true;
140+
138141
/// Whether to print the accessors of a property abstractly,
139142
/// i.e. always as:
140143
/// ```
@@ -260,9 +263,20 @@ struct PrintOptions {
260263
/// Whether to skip keywords with a prefix of underscore such as __consuming.
261264
bool SkipUnderscoredKeywords = false;
262265

263-
/// Whether to print declarations with opaque return types with a stable,
264-
/// parsable internal syntax.
265-
bool PrintStableReferencesToOpaqueReturnTypes = false;
266+
/// How to print opaque return types.
267+
enum class OpaqueReturnTypePrintingMode {
268+
/// 'some P1 & P2'.
269+
WithOpaqueKeyword,
270+
/// 'P1 & P2'.
271+
WithoutOpaqueKeyword,
272+
/// Stable parsable internal syntax.
273+
StableReference,
274+
/// Description suitable for debugging.
275+
Description
276+
};
277+
278+
OpaqueReturnTypePrintingMode OpaqueReturnTypePrinting =
279+
OpaqueReturnTypePrintingMode::WithOpaqueKeyword;
266280

267281
/// Whether to print decl attributes that are only used internally,
268282
/// such as _silgen_name, transparent, etc.
@@ -521,7 +535,8 @@ struct PrintOptions {
521535
result.PrintInSILBody = true;
522536
result.PreferTypeRepr = false;
523537
result.PrintIfConfig = false;
524-
result.PrintStableReferencesToOpaqueReturnTypes = true;
538+
result.OpaqueReturnTypePrinting =
539+
OpaqueReturnTypePrintingMode::StableReference;
525540
return result;
526541
}
527542

@@ -559,6 +574,7 @@ struct PrintOptions {
559574
PO.ExplodeEnumCaseDecls = true;
560575
PO.ShouldQualifyNestedDeclarations = QualifyNestedDeclarations::TypesOnly;
561576
PO.PrintParameterSpecifiers = true;
577+
PO.SkipImplicit = true;
562578
return PO;
563579
}
564580
};

include/swift/IDE/CodeCompletion.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ enum class CompletionKind {
489489
SuperExprDot,
490490
KeyPathExprObjC,
491491
KeyPathExprSwift,
492+
TypeDeclResultBeginning,
492493
TypeSimpleBeginning,
493494
TypeIdentifierWithDot,
494495
TypeIdentifierWithoutDot,

include/swift/Parse/CodeCompletionCallbacks.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ class CodeCompletionCallbacks {
155155
/// #keyPath argument have been parsed yet.
156156
virtual void completeExprKeyPath(KeyPathExpr *KPE, SourceLoc DotLoc) {};
157157

158+
/// Complete the beginning of the type of result of func/var/let/subscript.
159+
virtual void completeTypeDeclResultBeginning() {};
160+
158161
/// Complete the beginning of type-simple -- no tokens provided
159162
/// by user.
160163
virtual void completeTypeSimpleBeginning() {};

include/swift/Parse/Parser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,8 @@ class Parser {
10281028
ParserResult<PrecedenceGroupDecl>
10291029
parseDeclPrecedenceGroup(ParseDeclOptions flags, DeclAttributes &attributes);
10301030

1031+
ParserResult<TypeRepr> parseDeclResultType(Diag<> MessageID);
1032+
10311033
//===--------------------------------------------------------------------===//
10321034
// Type Parsing
10331035

lib/AST/ASTPrinter.cpp

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ PrintOptions PrintOptions::printParseableInterfaceFile() {
107107
result.FunctionDefinitions = true;
108108
result.CollapseSingleGetterProperty = false;
109109
result.VarInitializers = true;
110-
result.PrintStableReferencesToOpaqueReturnTypes = true;
110+
result.OpaqueReturnTypePrinting =
111+
OpaqueReturnTypePrintingMode::StableReference;
111112

112113
// We should print __consuming, __owned, etc for the module interface file.
113114
result.SkipUnderscoredKeywords = false;
@@ -1713,6 +1714,8 @@ void PrintAST::printMutatingModifiersIfNeeded(const AccessorDecl *accessor) {
17131714
void PrintAST::printAccessors(const AbstractStorageDecl *ASD) {
17141715
if (isa<VarDecl>(ASD) && !Options.PrintPropertyAccessors)
17151716
return;
1717+
if (isa<SubscriptDecl>(ASD) && !Options.PrintSubscriptAccessors)
1718+
return;
17161719

17171720
auto impl = ASD->getImplInfo();
17181721

@@ -2533,6 +2536,7 @@ void PrintAST::visitVarDecl(VarDecl *decl) {
25332536
if (!tyLoc.getTypeRepr())
25342537
tyLoc = TypeLoc::withoutLoc(decl->getInterfaceType());
25352538

2539+
Printer.printDeclResultTypePre(decl, tyLoc);
25362540
if (decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
25372541
printTypeLocForImplicitlyUnwrappedOptional(tyLoc);
25382542
else
@@ -2803,6 +2807,8 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {
28032807
ResultTyLoc = TypeLoc::withoutLoc(ResultTy);
28042808
}
28052809
Printer << " -> ";
2810+
2811+
Printer.printDeclResultTypePre(decl, ResultTyLoc);
28062812
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
28072813
if (decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
28082814
printTypeLocForImplicitlyUnwrappedOptional(ResultTyLoc);
@@ -2930,8 +2936,9 @@ void PrintAST::visitSubscriptDecl(SubscriptDecl *decl) {
29302936
});
29312937
Printer << " -> ";
29322938

2933-
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
29342939
TypeLoc elementTy = decl->getElementTypeLoc();
2940+
Printer.printDeclResultTypePre(decl, elementTy);
2941+
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
29352942
if (!elementTy.getTypeRepr())
29362943
elementTy = TypeLoc::withoutLoc(decl->getElementInterfaceType());
29372944
if (decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
@@ -3402,7 +3409,27 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
34023409
return;
34033410
}
34043411

3405-
if (T->hasSimpleTypeRepr()) {
3412+
bool isSimple = T->hasSimpleTypeRepr();
3413+
if (isSimple && T->is<OpaqueTypeArchetypeType>()) {
3414+
auto opaqueTy = T->castTo<OpaqueTypeArchetypeType>();
3415+
auto opaqueDecl = opaqueTy->getDecl();
3416+
if (!opaqueDecl->hasName()) {
3417+
switch (Options.OpaqueReturnTypePrinting) {
3418+
case PrintOptions::OpaqueReturnTypePrintingMode::StableReference:
3419+
case PrintOptions::OpaqueReturnTypePrintingMode::Description:
3420+
isSimple = true;
3421+
break;
3422+
case PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword:
3423+
isSimple = false;
3424+
break;
3425+
case PrintOptions::OpaqueReturnTypePrintingMode::WithoutOpaqueKeyword: {
3426+
isSimple = opaqueTy->getConformsTo().size() < 2;
3427+
}
3428+
}
3429+
}
3430+
}
3431+
3432+
if (isSimple) {
34063433
visit(T);
34073434
} else {
34083435
Printer << "(";
@@ -4165,7 +4192,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
41654192
}
41664193

41674194
void visitNestedArchetypeType(NestedArchetypeType *T) {
4168-
visit(T->getParent());
4195+
printWithParensIfNotSimple(T->getParent());
41694196
Printer << ".";
41704197
printArchetypeCommon(T);
41714198
}
@@ -4175,16 +4202,28 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
41754202
}
41764203

41774204
void visitOpaqueTypeArchetypeType(OpaqueTypeArchetypeType *T) {
4178-
// Print the type by referencing the opaque decl's synthetic name, if we
4179-
// were asked to.
4180-
OpaqueTypeDecl *decl = T->getDecl();
4181-
4182-
if (Options.PrintStableReferencesToOpaqueReturnTypes) {
4205+
switch (Options.OpaqueReturnTypePrinting) {
4206+
case PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword:
4207+
Printer << "some ";
4208+
LLVM_FALLTHROUGH;
4209+
case PrintOptions::OpaqueReturnTypePrintingMode::WithoutOpaqueKeyword: {
4210+
SmallVector<Type, 2> types;
4211+
for (auto proto : T->getConformsTo())
4212+
types.push_back(proto->TypeDecl::getDeclaredInterfaceType());
4213+
4214+
// Create and visit temporary ProtocolCompositionType.
4215+
auto composition =
4216+
ProtocolCompositionType::get(T->getASTContext(), types, false);
4217+
visit(composition);
4218+
return;
4219+
}
4220+
case PrintOptions::OpaqueReturnTypePrintingMode::StableReference: {
41834221
// Print the source of the opaque return type as a mangled name.
41844222
// We'll use type reconstruction while parsing the attribute to
41854223
// turn this back into a reference to the naming decl for the opaque
41864224
// type.
41874225
Printer << "@_opaqueReturnTypeOf(";
4226+
OpaqueTypeDecl *decl = T->getDecl();
41884227

41894228
Printer.printEscapedStringLiteral(
41904229
decl->getOpaqueReturnTypeIdentifier().str());
@@ -4195,7 +4234,9 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
41954234

41964235
Printer << u8") \U0001F9B8";
41974236
printGenericArgs(T->getSubstitutions().getReplacementTypes());
4198-
} else {
4237+
return;
4238+
}
4239+
case PrintOptions::OpaqueReturnTypePrintingMode::Description: {
41994240
// TODO(opaque): present opaque types with user-facing syntax. we should
42004241
// probably print this as `some P` and record the fact that we printed that
42014242
// so that diagnostics can add followup notes.
@@ -4209,6 +4250,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
42094250
[&] { Printer << ", "; });
42104251
Printer << '>';
42114252
}
4253+
return;
4254+
}
42124255
}
42134256
}
42144257

0 commit comments

Comments
 (0)