Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions include/swift/AST/ASTPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,20 @@ enum class PrintStructureKind {
TupleElement,
NumberLiteral,
StringLiteral,
/// ' = defaultValue'.
DefaultArgumentClause,
/// '<T, U: Requirement>'.
DeclGenericParameterClause,
/// 'where T: Collection, T.Element: Equtable'.
DeclGenericRequirementClause,
/// ' async throws'.
EffectsSpecifiers,
/// ' -> ResultTy' or ': ResultTy'.
DeclResultTypeClause,
/// '(a: Int, b param: String)' in function declarations.
FunctionParameterList,
/// '@attribute ParamTy...' in parameter declarations.
FunctionParameterType,
};

/// An abstract class used to print an AST.
Expand Down
52 changes: 49 additions & 3 deletions include/swift/IDE/CodeCompletion.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ class CodeCompletionStringChunk {
Equal,
Whitespace,

/// The first chunk of a whole generic parameter clause.
/// E.g '<T, C: Collection>'
GenericParameterClauseBegin,

/// The first chunk of a generic quirement clause.
/// E.g. 'where T: Collection, T.Element == Int'
GenericRequirementClauseBegin,

/// The first chunk of a substring that describes the parameter for a
/// generic type.
GenericParameterBegin,
Expand Down Expand Up @@ -194,6 +202,30 @@ class CodeCompletionStringChunk {
/// desired.
OptionalMethodCallTail,

/// The first chunk of a substring that describes the single parameter
/// declaration for a parameter clause.
ParameterDeclBegin,

ParameterDeclExternalName,

ParameterDeclLocalName,

ParameterDeclColon,

ParameterDeclTypeBegin,

/// Default argument clause for parameter declarations.
DefaultArgumentClauseBegin,

/// First chunk for effect specifiers. i.e. 'async' and 'throws'.
EffectsSpecifierClauseBegin,

/// First chunk for result type clause i.e. ' -> ResultTy' or ': ResultTy'.
DeclResultTypeClauseBegin,

/// First chunk for attribute and modifier list i.e. 'override public'
AttributeAndModifierListBegin,

/// Specifies the type of the whole entity that is returned in this code
/// completion result. For example, for variable references it is the
/// variable type, for function calls it is the return type.
Expand All @@ -219,7 +251,15 @@ class CodeCompletionStringChunk {
Kind == ChunkKind::GenericParameterBegin ||
Kind == ChunkKind::OptionalBegin ||
Kind == ChunkKind::CallArgumentTypeBegin ||
Kind == ChunkKind::TypeAnnotationBegin;
Kind == ChunkKind::TypeAnnotationBegin ||
Kind == ChunkKind::ParameterDeclBegin ||
Kind == ChunkKind::ParameterDeclTypeBegin ||
Kind == ChunkKind::DefaultArgumentClauseBegin ||
Kind == ChunkKind::GenericParameterClauseBegin ||
Kind == ChunkKind::EffectsSpecifierClauseBegin ||
Kind == ChunkKind::DeclResultTypeClauseBegin ||
Kind == ChunkKind::GenericRequirementClauseBegin ||
Kind == ChunkKind::AttributeAndModifierListBegin;
}

static bool chunkHasText(ChunkKind Kind) {
Expand Down Expand Up @@ -249,11 +289,14 @@ class CodeCompletionStringChunk {
Kind == ChunkKind::CallArgumentName ||
Kind == ChunkKind::CallArgumentInternalName ||
Kind == ChunkKind::CallArgumentColon ||
Kind == ChunkKind::DeclAttrParamColon ||
Kind == ChunkKind::DeclAttrParamKeyword ||
Kind == ChunkKind::CallArgumentType ||
Kind == ChunkKind::CallArgumentClosureType ||
Kind == ChunkKind::CallArgumentClosureExpr ||
Kind == ChunkKind::ParameterDeclExternalName ||
Kind == ChunkKind::ParameterDeclLocalName ||
Kind == ChunkKind::ParameterDeclColon ||
Kind == ChunkKind::DeclAttrParamColon ||
Kind == ChunkKind::DeclAttrParamKeyword ||
Kind == ChunkKind::GenericParameterName ||
Kind == ChunkKind::DynamicLookupMethodCallTail ||
Kind == ChunkKind::OptionalMethodCallTail ||
Expand Down Expand Up @@ -1062,17 +1105,20 @@ class PrintingCodeCompletionConsumer
llvm::raw_ostream &OS;
bool IncludeKeywords;
bool IncludeComments;
bool IncludeSourceText;
bool PrintAnnotatedDescription;
bool RequiresSourceFileInfo = false;

public:
PrintingCodeCompletionConsumer(llvm::raw_ostream &OS,
bool IncludeKeywords = true,
bool IncludeComments = true,
bool IncludeSourceText = false,
bool PrintAnnotatedDescription = false)
: OS(OS),
IncludeKeywords(IncludeKeywords),
IncludeComments(IncludeComments),
IncludeSourceText(IncludeSourceText),
PrintAnnotatedDescription(PrintAnnotatedDescription) {}

void handleResults(CodeCompletionContext &context) override;
Expand Down
160 changes: 103 additions & 57 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2224,8 +2224,11 @@ void PrintAST::printMembers(ArrayRef<Decl *> members, bool needComma,

void PrintAST::printGenericDeclGenericParams(GenericContext *decl) {
if (decl->isGeneric())
if (auto GenericSig = decl->getGenericSignature())
if (auto GenericSig = decl->getGenericSignature()) {
Printer.printStructurePre(PrintStructureKind::DeclGenericParameterClause);
printGenericSignature(GenericSig, PrintParams | InnermostOnly);
Printer.printStructurePost(PrintStructureKind::DeclGenericParameterClause);
}
}

void PrintAST::printDeclGenericRequirements(GenericContext *decl) {
Expand All @@ -2239,12 +2242,14 @@ void PrintAST::printDeclGenericRequirements(GenericContext *decl) {
if (parentSig && parentSig->isEqual(genericSig))
return;

Printer.printStructurePre(PrintStructureKind::DeclGenericParameterClause);
printGenericSignature(genericSig, PrintRequirements,
[parentSig](const Requirement &req) {
if (parentSig)
return !parentSig->isRequirementSatisfied(req);
return true;
});
Printer.printStructurePost(PrintStructureKind::DeclGenericParameterClause);
}

void PrintAST::printInherited(const Decl *decl) {
Expand Down Expand Up @@ -3236,25 +3241,32 @@ void PrintAST::visitVarDecl(VarDecl *decl) {
Printer.printName(decl->getName(), getTypeMemberPrintNameContext(decl));
});

auto type = decl->getInterfaceType();
Printer << ": ";
TypeLoc tyLoc;
if (auto *repr = decl->getTypeReprOrParentPatternTypeRepr()) {
tyLoc = TypeLoc(repr, type);
} else {
tyLoc = TypeLoc::withoutLoc(type);
}
Printer.printDeclResultTypePre(decl, tyLoc);
{
Printer.printStructurePre(PrintStructureKind::DeclResultTypeClause);
SWIFT_DEFER {
Printer.printStructurePost(PrintStructureKind::DeclResultTypeClause);
};

// HACK: When printing result types for vars with opaque result types,
// always print them using the `some` keyword instead of printing
// the full stable reference.
llvm::SaveAndRestore<PrintOptions::OpaqueReturnTypePrintingMode>
x(Options.OpaqueReturnTypePrinting,
PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword);
auto type = decl->getInterfaceType();
Printer << ": ";
TypeLoc tyLoc;
if (auto *repr = decl->getTypeReprOrParentPatternTypeRepr()) {
tyLoc = TypeLoc(repr, type);
} else {
tyLoc = TypeLoc::withoutLoc(type);
}
Printer.printDeclResultTypePre(decl, tyLoc);

printTypeLocForImplicitlyUnwrappedOptional(
tyLoc, decl->isImplicitlyUnwrappedOptional());
// HACK: When printing result types for vars with opaque result types,
// always print them using the `some` keyword instead of printing
// the full stable reference.
llvm::SaveAndRestore<PrintOptions::OpaqueReturnTypePrintingMode>
x(Options.OpaqueReturnTypePrinting,
PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword);

printTypeLocForImplicitlyUnwrappedOptional(
tyLoc, decl->isImplicitlyUnwrappedOptional());
}

printAccessors(decl);
}
Expand Down Expand Up @@ -3332,20 +3344,31 @@ void PrintAST::printOneParameter(const ParamDecl *param,
TheTypeLoc.setType(BGT->getGenericArgs()[0]);
}

if (!param->isVariadic() &&
!willUseTypeReprPrinting(TheTypeLoc, CurrentType, Options)) {
auto type = TheTypeLoc.getType();
printParameterFlags(Printer, Options, paramFlags,
isEscaping(type));
}
{
Printer.printStructurePre(PrintStructureKind::FunctionParameterType);
SWIFT_DEFER {
Printer.printStructurePost(PrintStructureKind::FunctionParameterType);
};
if (!param->isVariadic() &&
!willUseTypeReprPrinting(TheTypeLoc, CurrentType, Options)) {
auto type = TheTypeLoc.getType();
printParameterFlags(Printer, Options, paramFlags,
isEscaping(type));
}

printTypeLocForImplicitlyUnwrappedOptional(
TheTypeLoc, param->isImplicitlyUnwrappedOptional());
printTypeLocForImplicitlyUnwrappedOptional(
TheTypeLoc, param->isImplicitlyUnwrappedOptional());

if (param->isVariadic())
Printer << "...";
if (param->isVariadic())
Printer << "...";
}

if (param->isDefaultArgument() && Options.PrintDefaultArgumentValue) {
Printer.callPrintStructurePre(PrintStructureKind::DefaultArgumentClause);
SWIFT_DEFER {
Printer.printStructurePost(PrintStructureKind::DefaultArgumentClause);
};

SmallString<128> scratch;
auto defaultArgStr = param->getDefaultValueStringRepresentation(scratch);

Expand All @@ -3368,6 +3391,10 @@ void PrintAST::printOneParameter(const ParamDecl *param,
void PrintAST::printParameterList(ParameterList *PL,
ArrayRef<AnyFunctionType::Param> params,
bool isAPINameByDefault) {
Printer.printStructurePre(PrintStructureKind::FunctionParameterList);
SWIFT_DEFER {
Printer.printStructurePost(PrintStructureKind::FunctionParameterList);
};
Printer << "(";
const unsigned paramSize = params.size();
for (unsigned i = 0, e = PL->size(); i != e; ++i) {
Expand Down Expand Up @@ -3398,19 +3425,25 @@ void PrintAST::printFunctionParameters(AbstractFunctionDecl *AFD) {
printParameterList(BodyParams, parameterListTypes,
AFD->argumentNameIsAPIByDefault());

if (AFD->hasAsync()) {
Printer << " ";
if (AFD->getAttrs().hasAttribute<ReasyncAttr>())
Printer.printKeyword("reasync", Options);
else
Printer.printKeyword("async", Options);
}
if (AFD->hasAsync() || AFD->hasThrows()) {
Printer.printStructurePre(PrintStructureKind::EffectsSpecifiers);
SWIFT_DEFER {
Printer.printStructurePost(PrintStructureKind::EffectsSpecifiers);
};
if (AFD->hasAsync()) {
Printer << " ";
if (AFD->getAttrs().hasAttribute<ReasyncAttr>())
Printer.printKeyword("reasync", Options);
else
Printer.printKeyword("async", Options);
}

if (AFD->hasThrows()) {
if (AFD->getAttrs().hasAttribute<RethrowsAttr>())
Printer << " " << tok::kw_rethrows;
else
Printer << " " << tok::kw_throws;
if (AFD->hasThrows()) {
if (AFD->getAttrs().hasAttribute<RethrowsAttr>())
Printer << " " << tok::kw_rethrows;
else
Printer << " " << tok::kw_throws;
}
}
}

Expand Down Expand Up @@ -3522,6 +3555,10 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {

Type ResultTy = decl->getResultInterfaceType();
if (ResultTy && !ResultTy->isVoid()) {
Printer.printStructurePre(PrintStructureKind::DeclResultTypeClause);
SWIFT_DEFER {
Printer.printStructurePost(PrintStructureKind::DeclResultTypeClause);
};
TypeLoc ResultTyLoc(decl->getResultTypeRepr(), ResultTy);

// When printing a protocol requirement with types substituted for a
Expand Down Expand Up @@ -3699,23 +3736,32 @@ void PrintAST::visitSubscriptDecl(SubscriptDecl *decl) {
printParameterList(decl->getIndices(), params,
/*isAPINameByDefault*/false);
});
Printer << " -> ";

TypeLoc elementTy(decl->getElementTypeRepr(),
decl->getElementInterfaceType());
Printer.printDeclResultTypePre(decl, elementTy);
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);

// HACK: When printing result types for subscripts with opaque result types,
// always print them using the `some` keyword instead of printing
// the full stable reference.
llvm::SaveAndRestore<PrintOptions::OpaqueReturnTypePrintingMode>
x(Options.OpaqueReturnTypePrinting,
PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword);

printTypeLocForImplicitlyUnwrappedOptional(
elementTy, decl->isImplicitlyUnwrappedOptional());
Printer.printStructurePost(PrintStructureKind::FunctionReturnType);

{
Printer.printStructurePre(PrintStructureKind::DeclResultTypeClause);
SWIFT_DEFER {
Printer.printStructurePost(PrintStructureKind::DeclResultTypeClause);
};

Printer << " -> ";

TypeLoc elementTy(decl->getElementTypeRepr(),
decl->getElementInterfaceType());
Printer.printDeclResultTypePre(decl, elementTy);
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);

// HACK: When printing result types for subscripts with opaque result types,
// always print them using the `some` keyword instead of printing
// the full stable reference.
llvm::SaveAndRestore<PrintOptions::OpaqueReturnTypePrintingMode>
x(Options.OpaqueReturnTypePrinting,
PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword);

printTypeLocForImplicitlyUnwrappedOptional(
elementTy, decl->isImplicitlyUnwrappedOptional());
Printer.printStructurePost(PrintStructureKind::FunctionReturnType);
}

printDeclGenericRequirements(decl);
printAccessors(decl);
}
Expand Down
Loading