Skip to content

[IDE] Add full documentation to code completion result #82464

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 58 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
4742146
[Demangle] Implement Swift USR to Decl conversion
a7medev Jul 3, 2025
edcc390
[Demangle] Separate DeclNameExtractor & Clang USR to Decl
a7medev Jul 4, 2025
2f6b2e5
[IDE] Export swiftide_completion_item_get_doc_full
a7medev Jul 4, 2025
74db73b
[USR] Allow generating Swift USR for any Clang decl
a7medev Jul 5, 2025
970a455
[Demangle] Optimize USR to Clang Decl performance
a7medev Jul 5, 2025
302b363
[Demangle] Find extension by underlying module for Clang decls
a7medev Jul 5, 2025
6e526f9
[Demangle] Rename getDeclFromUSR to getDeclForUSR for consistency
a7medev Jul 8, 2025
9b7e817
[Demangle] Fix issues with Clang USR to Decl reconstruction
a7medev Jul 8, 2025
8ba8fa4
[IDE] Add AssociatedDecl to CodeCompletionResult
a7medev Jul 8, 2025
36a0278
[IDE] Pass AssociatedDecl to CodeCompletionResult on creation
a7medev Jul 8, 2025
57d34ba
[IDE] Fetch declaration full documentation on-demand
a7medev Jul 11, 2025
b5104a1
[IDE] Store Swift USR in ContextFreeCodeCompletionResult to find Asso…
a7medev Jul 11, 2025
a3a5fac
[IDE] Enable full doc option in complete tests that assert on doc
a7medev Jul 11, 2025
7b376cd
[Demangle] Remove unused lookup DC param to getDeclForUSR
a7medev Jul 11, 2025
37ae9ba
[Demangle] Move move switch' default at the bottom
a7medev Jul 11, 2025
d58d343
[IDE] Verify USR to Decl on code completion
a7medev Jul 11, 2025
7f23a99
[IDE] Add verify USR to Decl completion option
a7medev Jul 11, 2025
8a087e4
[IDE] Don't pass ASTContext directly to verifyUSRToDeclReconstruction
a7medev Jul 12, 2025
7617b21
[Demangle] Compare extension module against underlying module in find…
a7medev Jul 12, 2025
327f09e
[Test] Default to verify USR to Decl in tests
a7medev Jul 12, 2025
5fc0510
[Test] Don't check equality of decls in verifyUSRToDeclReconstruction
a7medev Jul 12, 2025
03dc3b9
[Demangle] Fix DeclName extraction for raw identifiers
a7medev Jul 12, 2025
1394721
[Demangle] Extract identifier from PrivateDeclName & RelatedEntityDec…
a7medev Jul 12, 2025
14cbe80
[ASTContext] Remove module from NameToModules on load module with sam…
a7medev Jul 12, 2025
62f680b
[Demangle] Remove unqualified lookup in ASTBuilder::findDecl
a7medev Jul 12, 2025
abfa8f6
[Demangle] Lookup Decl with privateDiscriminator in ASTBuilder::findDecl
a7medev Jul 13, 2025
dd55e32
[Test] Fix invalid redeclarations in completion tests & disable verif…
a7medev Jul 13, 2025
f596929
[IDE] Fetch completion result associated decl on-demand on printFullD…
a7medev Jul 13, 2025
7487c6d
[IDE] Pass mutable C-string to handler in swiftide_completion_item_ge…
a7medev Jul 14, 2025
22750b3
[IDE] Verify decls match in verify USR to Decl reconstruction
a7medev Jul 19, 2025
a7c0a20
[Demangle] Enhance coding style in ASTDemangler & DeclNameExtractor
a7medev Jul 19, 2025
72e87e5
[Demangle] Generalize ASTDemangler::findDecl to take a predicate func…
a7medev Jul 19, 2025
08c03c1
[IDE] Add full documentation to code completion result
a7medev Mar 25, 2025
58f0a30
[USR] Split USRGenerationRequest into SwiftUSRGenerationRequest & Cla…
a7medev Jul 20, 2025
f4926fe
[IDE] Switch assert false to ABORT in verifyUSRToDeclReconstruction
a7medev Jul 20, 2025
b93a8f6
[IDE] Apply clang-format to full documentation changes
a7medev Jul 20, 2025
e8036eb
[IDE] Update code complete and documentation tests
a7medev Jul 20, 2025
c1d6f7e
[IDE] Rename complete_docbrief to complete_doc
a7medev Jun 26, 2025
732cc76
[IDE] NFC: Add doc comment for on-demand CodeCompletionResult::getAss…
a7medev Jul 20, 2025
f224f39
[IDE] Use response scratch in swiftide_completion_item_get_doc_full
a7medev Jul 21, 2025
2994fc0
[USR] Remove unneeded code in USR to Decl conversion
a7medev Jul 21, 2025
8d5f74b
[Test] Don't print brief comment in diagnostics in swift-ide-test
a7medev Jul 21, 2025
afda1cf
[USR] Move distinguishSynthesizedDecls check from ClangUSRGenerationR…
a7medev Jul 25, 2025
5fe8274
[Demangle] Simplify DeclNameExtractor::extractArgLabelsFromType multi…
a7medev Jul 25, 2025
6bbe2a5
[IDE] Remove includeFullDocumentation option in code complete request
a7medev Jul 25, 2025
e3e9468
[Test] Check full doc in completion with swift-ide-test
a7medev Jul 25, 2025
d18694f
NFC: Apply clang-format to full documentation in completion changes
a7medev Jul 25, 2025
6a93b8f
[IDE] Remove unused DeclNameExtractor::extractTextName & SourceKit Co…
a7medev Jul 25, 2025
0c05f8f
[Test] Revert changes to SourceKit documentation tests
a7medev Jul 25, 2025
041e856
[Test] Add IDE tests for full and brief documentation
a7medev Jul 25, 2025
469f24c
[Demangle] Demangle operator function name in DeclNameExtractor
a7medev Jul 26, 2025
d782aee
[Test] Disable USR to Decl verification in crashers with invalid name…
a7medev Jul 26, 2025
8f3bb9f
[Mangler] Mangle compatibility aliases as decls synthesized by ClangI…
a7medev Aug 2, 2025
5191756
[Test] Add checks for typealias mangling as Clang-importer-synthesized
a7medev Aug 4, 2025
fb8212a
[IDE] Provide raw & XML documentation for completion items
a7medev Aug 13, 2025
e59f263
[Test] Enable USR to Decl verification in IDE/complete_crashes & IDE/…
a7medev Aug 15, 2025
83da955
[Test] Add sort by name option to swift-ide-test for completion
a7medev Aug 16, 2025
380b304
[Test] Update completion doc tests to check for raw doc comment
a7medev Aug 16, 2025
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
21 changes: 19 additions & 2 deletions include/swift/AST/ASTDemangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
#include <optional>

namespace swift {


class Decl;
class TypeDecl;
class DeclName;

namespace Demangle {
SWIFT_BEGIN_INLINE_NAMESPACE
Expand All @@ -50,6 +52,9 @@ TypeDecl *getTypeDeclForUSR(ASTContext &ctx,
llvm::StringRef usr,
GenericSignature genericSig=GenericSignature());

Decl *getDeclForUSR(ASTContext &ctx, llvm::StringRef usr,
GenericSignature genericSig = GenericSignature());

/// An implementation of MetadataReader's BuilderType concept that
/// just finds and builds things in the AST.
class ASTBuilder {
Expand Down Expand Up @@ -122,6 +127,17 @@ class ASTBuilder {

Demangle::NodeFactory &getNodeFactory() { return Factory; }

/// Finds the \c Decl associated with the provided \p node.
/// Attempts to find a type declaration using \c createTypeDecl, if not found,
/// it performs a lookup for the declaration and returns the first declaration
/// for which \c isMatchingValueDecl returns true.
///
/// \note \p isMatchingValueDecl is not evaluated for type declarations, it's
/// only used to choose among lookup results when \c createTypeDecl fails.
Decl *
findDecl(NodePointer node,
llvm::function_ref<bool(const ValueDecl *)> isMatchingValueDecl);

Type decodeMangledType(NodePointer node, bool forRequirement = true);
Type createBuiltinType(StringRef builtinName, StringRef mangledName);

Expand Down Expand Up @@ -286,7 +302,8 @@ class ASTBuilder {
/// The module name encoded in the node is either the module's real or ABI
/// name. Multiple modules can share the same name. This function returns
/// all modules that contain that name.
llvm::ArrayRef<ModuleDecl *> findPotentialModules(NodePointer node);
llvm::ArrayRef<ModuleDecl *> findPotentialModules(NodePointer node,
ModuleDecl *&scratch);

Demangle::NodePointer findModuleNode(NodePointer node);

Expand Down
5 changes: 5 additions & 0 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2909,6 +2909,10 @@ class ValueDecl : public Decl {
/// a null pointer.
unsigned noOpaqueResultType : 1;

/// Whether the ClangUSRGenerationRequest request was evaluated and produced
/// a std::nullopt.
unsigned noClangUSR : 1;

/// Whether the "isFinal" bit has been computed yet.
unsigned isFinalComputed : 1;

Expand Down Expand Up @@ -2943,6 +2947,7 @@ class ValueDecl : public Decl {
friend class OpaqueResultTypeRequest;
friend class ApplyAccessNoteRequest;
friend class AvailabilityDomainForDeclRequest;
friend class ClangUSRGenerationRequest;

friend class Decl;
SourceLoc getLocFromSource() const { return NameLoc; }
Expand Down
58 changes: 58 additions & 0 deletions include/swift/AST/DeclNameExtractor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//===--- DeclNameExtractor.h - Decl Name Demangling -------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the DeclNameExtractor utility.
//
//===----------------------------------------------------------------------===//

#include "swift/AST/ASTContext.h"
#include "swift/AST/Identifier.h"

namespace swift {
namespace Demangle {

class Node;

class DeclNameExtractor {
private:
ASTContext &Ctx;

public:
DeclNameExtractor(ASTContext &ctx) : Ctx(ctx) {}

/// Extract a DeclName from a demangling node
/// \returns true if a \c DeclName is found, false otherwise.
bool extractDeclName(Node *node, DeclName &name,
Identifier &privateDiscriminator);

private:
bool extractIdentifierName(Node *node, DeclName &declName,
Identifier &privateDiscriminator);
bool extractFunctionLikeName(Node *node, DeclName &declName,
Identifier &privateDiscriminator);
void extractArgLabelsFromLabelList(Node *LabelList,
SmallVectorImpl<Identifier> &ArgLabels);
void extractArgLabelsFromType(Node *Type,
SmallVectorImpl<Identifier> &ArgLabels);
DeclBaseName extractOperatorName(Node *node);
};

/// Returns an identifier with the given name, automatically removing any
/// surrounding backticks that are present for raw identifiers.
Identifier getIdentifier(ASTContext &Ctx, StringRef name);

bool extractNameNodeInfo(ASTContext &Ctx, Node *node, StringRef &name,
StringRef &relatedEntityKind,
Identifier &privateDiscriminator);

} // namespace Demangle
} // namespace swift
62 changes: 55 additions & 7 deletions include/swift/AST/TypeCheckRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -757,20 +757,70 @@ class RequirementRequest :
bool isCached() const;
};

/// Generate the Clang USR for the given declaration.
class ClangUSRGenerationRequest
: public SimpleRequest<ClangUSRGenerationRequest,
std::optional<std::string>(const ValueDecl *),
RequestFlags::SeparatelyCached |
RequestFlags::SplitCached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

// Evaluation.
std::optional<std::string> evaluate(Evaluator &eval,
const ValueDecl *d) const;

public:
// Split caching.
bool isCached() const { return true; }
std::optional<std::optional<std::string>> getCachedResult() const;
void cacheResult(std::optional<std::string> result) const;
};

/// Generate the Swift USR for the given declaration.
class SwiftUSRGenerationRequest
: public SimpleRequest<SwiftUSRGenerationRequest,
std::string(const ValueDecl *),
RequestFlags::Cached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

// Evaluation.
std::string evaluate(Evaluator &eval, const ValueDecl *d) const;

public:
// Caching
bool isCached() const { return true; }
};

struct USRGenerationOptions {
/// @brief Whether to emit USRs using the Swift declaration when it is
/// synthesized from a Clang based declaration. Useful in cases where Swift
/// declarations are synthesized from Clang nodes but the caller actually
/// wants the USR of the Swift declaration.
bool distinguishSynthesizedDecls;

/// @brief Whether to emit USRs using the Swift declaration for all
/// declarations specifically, emits a Swift USR for all Clang-based
/// declarations.
bool useSwiftUSR;

friend llvm::hash_code hash_value(const USRGenerationOptions &options) {
return llvm::hash_value(options.distinguishSynthesizedDecls);
return llvm::hash_combine(
llvm::hash_value(options.distinguishSynthesizedDecls),
llvm::hash_value(options.useSwiftUSR));
}

friend bool operator==(const USRGenerationOptions &lhs,
const USRGenerationOptions &rhs) {
return lhs.distinguishSynthesizedDecls == rhs.distinguishSynthesizedDecls;
return lhs.distinguishSynthesizedDecls == rhs.distinguishSynthesizedDecls &&
lhs.useSwiftUSR == rhs.useSwiftUSR;
}

friend bool operator!=(const USRGenerationOptions &lhs,
Expand All @@ -783,10 +833,12 @@ void simple_display(llvm::raw_ostream &out,
const USRGenerationOptions &options);

/// Generate the USR for the given declaration.
/// This is an umbrella request that forwards to ClangUSRGenerationRequest or
/// SwiftUSRGenerationRequest.
class USRGenerationRequest
: public SimpleRequest<USRGenerationRequest,
std::string(const ValueDecl *, USRGenerationOptions),
RequestFlags::Cached> {
RequestFlags::Uncached> {
public:
using SimpleRequest::SimpleRequest;

Expand All @@ -796,10 +848,6 @@ class USRGenerationRequest
// Evaluation.
std::string evaluate(Evaluator &eval, const ValueDecl *d,
USRGenerationOptions options) const;

public:
// Caching
bool isCached() const { return true; }
};

/// Generate the mangling for the given local type declaration.
Expand Down
8 changes: 7 additions & 1 deletion include/swift/AST/TypeCheckerTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -364,9 +364,15 @@ SWIFT_REQUEST(TypeChecker, TypeCheckASTNodeAtLocRequest,
Uncached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, UnderlyingTypeRequest, Type(TypeAliasDecl *),
SeparatelyCached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, ClangUSRGenerationRequest,
std::optional<std::string>(const ValueDecl *),
SeparatelyCached | SplitCached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, SwiftUSRGenerationRequest,
std::string(const ValueDecl *),
Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, USRGenerationRequest,
std::string(const ValueDecl *, USRGenerationOptions),
Cached, NoLocationInfo)
Uncached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, IsABICompatibleOverrideRequest,
bool(ValueDecl *), Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, IsStaticRequest,
Expand Down
13 changes: 12 additions & 1 deletion include/swift/AST/USRGeneration.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,20 @@ bool printDeclTypeUSR(const ValueDecl *D, raw_ostream &OS);
/// Prints out the USR for the given ValueDecl.
/// @param distinguishSynthesizedDecls Whether to use the USR of the
/// synthesized declaration instead of the USR of the underlying Clang USR.
/// @param useSwiftUSR Whether to generate a Swift USR for all Clang
/// declarations as well.
/// \returns true if it failed, false on success.
bool printValueDeclUSR(const ValueDecl *D, raw_ostream &OS,
bool distinguishSynthesizedDecls = false);
bool distinguishSynthesizedDecls = false,
bool useSwiftUSR = false);

/// Prints out the Swift USR for the given ValueDecl regardless of its source
/// (Swift or Clang). Equivalent to `printValueDeclUSR(D, OS, false,
/// /*useSwiftUSR=*/true)`
inline bool printValueDeclSwiftUSR(const ValueDecl *D, raw_ostream &OS) {
return printValueDeclUSR(D, OS, /*distinguishSynthesizedDecls=*/false,
/*useSwiftUSR=*/true);
}

/// Prints out the USR for the given ModuleEntity.
/// In case module aliasing is used, it prints the real module name. For example,
Expand Down
3 changes: 3 additions & 0 deletions include/swift/IDE/CodeCompletionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ class CodeCompletionContext {
return CurrentResults.addCallWithNoDefaultArgs;
}

void setVerifyUSRToDecl(bool flag) { CurrentResults.verifyUSRToDecl = flag; }
bool verifyUSRToDecl() const { return CurrentResults.verifyUSRToDecl; }

/// Allocate a string owned by the code completion context.
StringRef copyString(StringRef Str) {
return Str.copy(*CurrentResults.Allocator);
Expand Down
Loading