[SourceKit] Add optional declarations array to interface gen request (#75802)

Introduces the new DeclarationsArrayBuilder and adds it to the
EditorConsumer. Declaration info always includes a kind, offset, and
length, and includes a USR where applicable.
As the USR is already available for editor.open.interface type requests,
this doesn't compute any new information, it just exposes more of what's
there already.
This commit is contained in:
Jim M. R. Teichgräber
2024-08-31 03:04:12 +02:00
committed by GitHub
parent ada8a3018a
commit f2e57d8c76
15 changed files with 449 additions and 53 deletions

View File

@@ -56,6 +56,8 @@ public:
const Decl *Dcl = nullptr;
/// The range in the interface source.
TextRange Range;
/// The USR, if the declaration has one
StringRef USR;
TextDecl(const Decl *D, TextRange Range)
: Dcl(D), Range(Range) {}
@@ -66,6 +68,8 @@ public:
std::string Text;
std::vector<TextReference> References;
std::vector<TextDecl> Decls;
/// Do not clear the map or erase elements,
/// without keeping the Decls vector in sync
llvm::StringMap<TextDecl> USRMap;
};
@@ -155,8 +159,17 @@ public:
OS << TargetUSR;
}
StringRef USR = OS.str();
Info.USRMap[USR] = Entry;
DeclUSRs.emplace_back(VD, USR);
auto iterator = Info.USRMap.insert_or_assign(USR, Entry).first;
// Set the USR in the declarations to the key in the USRMap, because the
// lifetime of that matches/exceeds the lifetime of Decls. String keys
// in the StringMap are heap allocated and only get destroyed on
// explicit erase() or clear() calls, or on destructor calls (the
// Programmer's Manual description itself also states that StringMap
// "only ever copies a string if a value is inserted").
// Thus this never results in a dangling reference, as the USRMap is
// never cleared and no elements are erased in its lifetime.
Info.Decls.back().USR = iterator->getKey();
}
}
}
@@ -265,6 +278,21 @@ static void reportSemanticAnnotations(const SourceTextInfo &IFaceInfo,
}
}
/// Create the declarations array (sourcekitd::DeclarationsArrayBuilder) from
/// the SourceTextInfo about declarations
static void reportDeclarations(const SourceTextInfo &IFaceInfo,
EditorConsumer &Consumer) {
for (auto &Dcl : IFaceInfo.Decls) {
if (!Dcl.Dcl)
continue;
UIdent Kind = SwiftLangSupport::getUIDForDecl(Dcl.Dcl);
if (Kind.isInvalid())
continue;
Consumer.handleDeclaration(Dcl.Range.Offset, Dcl.Range.Length, Kind,
Dcl.USR);
}
}
namespace {
/// A diagnostic consumer that picks up module loading errors.
class ModuleLoadingErrorConsumer final : public DiagnosticConsumer {
@@ -593,6 +621,8 @@ void SwiftInterfaceGenContext::reportEditorInfo(EditorConsumer &Consumer) const
reportSyntacticAnnotations(Impl.TextCI, Consumer);
reportDocumentStructure(Impl.TextCI, Consumer);
reportSemanticAnnotations(Impl.Info, Consumer);
reportDeclarations(Impl.Info, Consumer);
Consumer.finished();
}