Skip to content

Commit 5bd605f

Browse files
authored
Merge pull request #24292 from rintaro/5.1-04-24-2019-sourcekit-opaque-result-types
[5.1 04-24-2019][SourceKit] SourceKit support for opaque result types
2 parents b8b6e37 + 909ec57 commit 5bd605f

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;
@@ -1699,6 +1700,8 @@ void PrintAST::printMutatingModifiersIfNeeded(const AccessorDecl *accessor) {
16991700
void PrintAST::printAccessors(const AbstractStorageDecl *ASD) {
17001701
if (isa<VarDecl>(ASD) && !Options.PrintPropertyAccessors)
17011702
return;
1703+
if (isa<SubscriptDecl>(ASD) && !Options.PrintSubscriptAccessors)
1704+
return;
17021705

17031706
auto impl = ASD->getImplInfo();
17041707

@@ -2519,6 +2522,7 @@ void PrintAST::visitVarDecl(VarDecl *decl) {
25192522
if (!tyLoc.getTypeRepr())
25202523
tyLoc = TypeLoc::withoutLoc(decl->getInterfaceType());
25212524

2525+
Printer.printDeclResultTypePre(decl, tyLoc);
25222526
if (decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
25232527
printTypeLocForImplicitlyUnwrappedOptional(tyLoc);
25242528
else
@@ -2789,6 +2793,8 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {
27892793
ResultTyLoc = TypeLoc::withoutLoc(ResultTy);
27902794
}
27912795
Printer << " -> ";
2796+
2797+
Printer.printDeclResultTypePre(decl, ResultTyLoc);
27922798
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
27932799
if (decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
27942800
printTypeLocForImplicitlyUnwrappedOptional(ResultTyLoc);
@@ -2916,8 +2922,9 @@ void PrintAST::visitSubscriptDecl(SubscriptDecl *decl) {
29162922
});
29172923
Printer << " -> ";
29182924

2919-
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
29202925
TypeLoc elementTy = decl->getElementTypeLoc();
2926+
Printer.printDeclResultTypePre(decl, elementTy);
2927+
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
29212928
if (!elementTy.getTypeRepr())
29222929
elementTy = TypeLoc::withoutLoc(decl->getElementInterfaceType());
29232930
if (decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
@@ -3388,7 +3395,27 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
33883395
return;
33893396
}
33903397

3391-
if (T->hasSimpleTypeRepr()) {
3398+
bool isSimple = T->hasSimpleTypeRepr();
3399+
if (isSimple && T->is<OpaqueTypeArchetypeType>()) {
3400+
auto opaqueTy = T->castTo<OpaqueTypeArchetypeType>();
3401+
auto opaqueDecl = opaqueTy->getDecl();
3402+
if (!opaqueDecl->hasName()) {
3403+
switch (Options.OpaqueReturnTypePrinting) {
3404+
case PrintOptions::OpaqueReturnTypePrintingMode::StableReference:
3405+
case PrintOptions::OpaqueReturnTypePrintingMode::Description:
3406+
isSimple = true;
3407+
break;
3408+
case PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword:
3409+
isSimple = false;
3410+
break;
3411+
case PrintOptions::OpaqueReturnTypePrintingMode::WithoutOpaqueKeyword: {
3412+
isSimple = opaqueTy->getConformsTo().size() < 2;
3413+
}
3414+
}
3415+
}
3416+
}
3417+
3418+
if (isSimple) {
33923419
visit(T);
33933420
} else {
33943421
Printer << "(";
@@ -4151,7 +4178,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
41514178
}
41524179

41534180
void visitNestedArchetypeType(NestedArchetypeType *T) {
4154-
visit(T->getParent());
4181+
printWithParensIfNotSimple(T->getParent());
41554182
Printer << ".";
41564183
printArchetypeCommon(T);
41574184
}
@@ -4161,16 +4188,28 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
41614188
}
41624189

41634190
void visitOpaqueTypeArchetypeType(OpaqueTypeArchetypeType *T) {
4164-
// Print the type by referencing the opaque decl's synthetic name, if we
4165-
// were asked to.
4166-
OpaqueTypeDecl *decl = T->getDecl();
4167-
4168-
if (Options.PrintStableReferencesToOpaqueReturnTypes) {
4191+
switch (Options.OpaqueReturnTypePrinting) {
4192+
case PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword:
4193+
Printer << "some ";
4194+
LLVM_FALLTHROUGH;
4195+
case PrintOptions::OpaqueReturnTypePrintingMode::WithoutOpaqueKeyword: {
4196+
SmallVector<Type, 2> types;
4197+
for (auto proto : T->getConformsTo())
4198+
types.push_back(proto->TypeDecl::getDeclaredInterfaceType());
4199+
4200+
// Create and visit temporary ProtocolCompositionType.
4201+
auto composition =
4202+
ProtocolCompositionType::get(T->getASTContext(), types, false);
4203+
visit(composition);
4204+
return;
4205+
}
4206+
case PrintOptions::OpaqueReturnTypePrintingMode::StableReference: {
41694207
// Print the source of the opaque return type as a mangled name.
41704208
// We'll use type reconstruction while parsing the attribute to
41714209
// turn this back into a reference to the naming decl for the opaque
41724210
// type.
41734211
Printer << "@_opaqueReturnTypeOf(";
4212+
OpaqueTypeDecl *decl = T->getDecl();
41744213

41754214
Printer.printEscapedStringLiteral(
41764215
decl->getOpaqueReturnTypeIdentifier().str());
@@ -4181,7 +4220,9 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
41814220

41824221
Printer << u8") \U0001F9B8";
41834222
printGenericArgs(T->getSubstitutions().getReplacementTypes());
4184-
} else {
4223+
return;
4224+
}
4225+
case PrintOptions::OpaqueReturnTypePrintingMode::Description: {
41854226
// TODO(opaque): present opaque types with user-facing syntax. we should
41864227
// probably print this as `some P` and record the fact that we printed that
41874228
// so that diagnostics can add followup notes.
@@ -4195,6 +4236,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
41954236
[&] { Printer << ", "; });
41964237
Printer << '>';
41974238
}
4239+
return;
4240+
}
41984241
}
41994242
}
42004243

0 commit comments

Comments
 (0)