add support to getTopLevelDecls for clang submodules (#76401)

rdar://126031510
This commit is contained in:
QuietMisdreavus
2025-01-30 09:39:58 -07:00
committed by GitHub
parent b3275d9db3
commit ab26b8b9d7
23 changed files with 693 additions and 277 deletions

View File

@@ -96,6 +96,9 @@ public:
/// clang::ImportDecl or null if it's neither.
const clang::Module *getClangModule() const;
/// Returns the owning clang module of this node, if it exists.
const clang::Module *getOwningClangModule() const;
clang::SourceLocation getLocation() const;
clang::SourceRange getSourceRange() const;

View File

@@ -195,8 +195,6 @@ public:
virtual Identifier
getDiscriminatorForPrivateDecl(const Decl *D) const = 0;
virtual bool shouldCollectDisplayDecls() const { return true; }
/// Finds all top-level decls in this file.
///
/// This does a simple local lookup, not recursively looking through imports.

View File

@@ -856,6 +856,12 @@ public:
/// returns the module \c Foo.
ModuleDecl *getTopLevelModule(bool overlay = false);
/// Returns whether or not this module is a submodule of the given module.
/// If `this == M`, this returns false. If this is a submodule such as
/// `Foo.Bar.Baz`, and the given module is either `Foo` or `Foo.Bar`, this
/// returns true.
bool isSubmoduleOf(const ModuleDecl *M) const;
bool isResilient() const {
return getResilienceStrategy() != ResilienceStrategy::Default;
}
@@ -1095,15 +1101,6 @@ public:
/// The order of the results is not guaranteed to be meaningful.
void getPrecedenceGroups(SmallVectorImpl<PrecedenceGroupDecl*> &Results) const;
/// Determines whether this module should be recursed into when calling
/// \c getDisplayDecls.
///
/// Some modules should not call \c getDisplayDecls, due to assertions
/// in their implementation. These are usually implicit imports that would be
/// recursed into for parsed modules. This function provides a guard against
/// recusing into modules that should not have decls collected.
bool shouldCollectDisplayDecls() const;
/// Finds all top-level decls that should be displayed to a client of this
/// module.
///

View File

@@ -90,8 +90,6 @@ public:
ObjCSelector selector,
SmallVectorImpl<AbstractFunctionDecl *> &results) const override;
virtual bool shouldCollectDisplayDecls() const override;
virtual void getTopLevelDecls(SmallVectorImpl<Decl*> &results) const override;
virtual void getDisplayDecls(SmallVectorImpl<Decl*> &results, bool recursive = false) const override;

View File

@@ -2702,7 +2702,11 @@ static void addNamespaceMembers(Decl *decl,
const auto *declOwner = namespaceDecl->getOwningModule();
if (declOwner)
declOwner = declOwner->getTopLevelModule();
for (auto redecl : namespaceDecl->redecls()) {
auto Redecls = llvm::SmallVector<clang::NamespaceDecl *, 2>(namespaceDecl->redecls());
std::stable_sort(Redecls.begin(), Redecls.end(), [&](clang::NamespaceDecl *LHS, clang::NamespaceDecl *RHS) {
return LHS->getOwningModule()->Name < RHS->getOwningModule()->Name;
});
for (auto redecl : Redecls) {
// Skip namespace declarations that come from other top-level modules.
if (const auto *redeclOwner = redecl->getOwningModule()) {
if (declOwner && declOwner != redeclOwner->getTopLevelModule())

View File

@@ -131,6 +131,16 @@ const clang::Module *ClangNode::getClangModule() const {
return nullptr;
}
const clang::Module *ClangNode::getOwningClangModule() const {
if (auto *M = getAsModule())
return M;
if (auto D = getAsDecl())
return D->getOwningModule();
if (auto MI = getAsModuleMacro())
return MI->getOwningModule();
return nullptr;
}
void ClangNode::dump() const {
if (auto D = getAsDecl())
D->dump();

View File

@@ -957,6 +957,22 @@ ModuleDecl *ModuleDecl::getTopLevelModule(bool overlay) {
return this;
}
bool ModuleDecl::isSubmoduleOf(const ModuleDecl *M) const {
// Swift modules don't currently support submodules.
if (!isNonSwiftModule())
return false;
auto *ClangParent = M->findUnderlyingClangModule();
if (!ClangParent)
return false;
auto *ClangModule = findUnderlyingClangModule();
if (!ClangModule)
return false;
return ClangModule->isSubModuleOf(ClangParent);
}
static bool isParsedModule(const ModuleDecl *mod) {
// FIXME: If we ever get mixed modules that contain both SourceFiles and other
// kinds of file units, this will break; there all callers of this function should
@@ -1239,14 +1255,6 @@ void SourceFile::lookupObjCMethods(
results.append(known->second.begin(), known->second.end());
}
bool ModuleDecl::shouldCollectDisplayDecls() const {
for (const FileUnit *file : getFiles()) {
if (!file->shouldCollectDisplayDecls())
return false;
}
return true;
}
void ModuleDecl::getLocalTypeDecls(SmallVectorImpl<TypeDecl*> &Results) const {
FORWARD(getLocalTypeDecls, (Results));
}
@@ -1471,9 +1479,6 @@ void ModuleDecl::ImportCollector::collect(
const ImportedModule &importedModule) {
auto *module = importedModule.importedModule;
if (!module->shouldCollectDisplayDecls())
return;
if (importFilter && !importFilter(module))
return;
@@ -1494,11 +1499,17 @@ static void
collectExportedImports(const ModuleDecl *topLevelModule,
ModuleDecl::ImportCollector &importCollector) {
SmallVector<const ModuleDecl *> stack;
SmallPtrSet<const ModuleDecl *, 4> visited;
visited.insert(topLevelModule);
stack.push_back(topLevelModule);
while (!stack.empty()) {
const ModuleDecl *module = stack.pop_back_val();
if (module->isNonSwiftModule())
if (module->isNonSwiftModule() && module != topLevelModule &&
!module->isSubmoduleOf(topLevelModule)) {
// Recurse into submodules of the top-level module so that we can
// re-export them if necessary.
continue;
}
for (const FileUnit *file : module->getFiles()) {
if (const SourceFile *source = dyn_cast<SourceFile>(file)) {
@@ -1518,10 +1529,12 @@ collectExportedImports(const ModuleDecl *topLevelModule,
ModuleDecl::ImportFilterKind::Exported);
for (const auto &im : exportedImports) {
// Skip collecting the underlying clang module as we already have the relevant import.
if (module->isClangOverlayOf(im.importedModule))
continue;
importCollector.collect(im);
stack.push_back(im.importedModule);
if (!module->isClangOverlayOf(im.importedModule))
importCollector.collect(im);
if (!visited.contains(im.importedModule)) {
visited.insert(im.importedModule);
stack.push_back(im.importedModule);
}
}
}
}

View File

@@ -3099,6 +3099,15 @@ static bool isDeclaredInModule(const ClangModuleUnit *ModuleFilter,
if (VD->getModuleContext()->getName().str() == CLANG_HEADER_MODULE_NAME) {
return true;
}
// Because the ClangModuleUnit saved as a decl context will be saved as the top-level module, but
// the ModuleFilter we're given might be a submodule (if a submodule was passed to
// getTopLevelDecls, for example), we should compare the underlying Clang modules to determine
// module membership.
if (auto ClangNode = VD->getClangNode()) {
if (auto *ClangModule = ClangNode.getOwningClangModule()) {
return ModuleFilter->getClangModule() == ClangModule;
}
}
auto ContainingUnit = VD->getDeclContext()->getModuleScopeContext();
return ModuleFilter == ContainingUnit;
}
@@ -3271,7 +3280,7 @@ public:
FilteringDeclaredDeclConsumer(swift::VisibleDeclConsumer &consumer,
const ClangModuleUnit *CMU)
: NextConsumer(consumer), ModuleFilter(CMU) {
assert(CMU && CMU->isTopLevel() && "Only top-level modules supported");
assert(CMU);
}
void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason,
@@ -3622,9 +3631,6 @@ public:
};
} // unnamed namespace
// FIXME(https://github.com/apple/swift-docc/issues/190): Should submodules still be crawled for the symbol graph?
bool ClangModuleUnit::shouldCollectDisplayDecls() const { return isTopLevel(); }
void ClangModuleUnit::getTopLevelDecls(SmallVectorImpl<Decl*> &results) const {
VectorDeclPtrConsumer consumer(results);
FilteringDeclaredDeclConsumer filterConsumer(consumer, this);
@@ -3645,10 +3651,12 @@ void ClangModuleUnit::getTopLevelDecls(SmallVectorImpl<Decl*> &results) const {
// Add the extensions produced by importing categories.
for (auto category : lookupTable->categories()) {
if (auto extension = cast_or_null<ExtensionDecl>(
owner.importDecl(category, owner.CurrentVersion,
/*UseCanonical*/false))) {
results.push_back(extension);
if (category->getOwningModule() == clangModule) {
if (auto extension = cast_or_null<ExtensionDecl>(
owner.importDecl(category, owner.CurrentVersion,
/*UseCanonical*/false))) {
results.push_back(extension);
}
}
}
@@ -3663,11 +3671,11 @@ void ClangModuleUnit::getTopLevelDecls(SmallVectorImpl<Decl*> &results) const {
};
// Retrieve all of the globals that will be mapped to members.
// FIXME: Since we don't represent Clang submodules as Swift
// modules, we're getting everything.
llvm::SmallPtrSet<ExtensionDecl *, 8> knownExtensions;
for (auto entry : lookupTable->allGlobalsAsMembers()) {
auto decl = entry.get<clang::NamedDecl *>();
if (decl->getOwningModule() != clangModule) continue;
Decl *importedDecl = owner.importDecl(decl, owner.CurrentVersion);
if (!importedDecl) continue;

View File

@@ -446,9 +446,6 @@ void swift::ide::printModuleInterface(
const PrintOptions &Options,
const bool PrintSynthesizedExtensions) {
// Clang submodules aren't handled well by `getDisplayDecls()` (no decls are
// returned), so map them to their top-level module and filter out the extra
// results below.
const clang::Module *TargetClangMod = TargetMod->findUnderlyingClangModule();
ModuleDecl *TopLevelMod = TargetMod->getTopLevelModule();
bool IsSubmodule = TargetMod != TopLevelMod;
@@ -460,8 +457,8 @@ void swift::ide::printModuleInterface(
auto AdjustedOptions = Options;
adjustPrintOptions(AdjustedOptions);
SmallVector<Decl *, 1> Decls;
swift::getTopLevelDeclsForDisplay(TopLevelMod, Decls);
SmallVector<ModuleDecl *, 1> ModuleList;
ModuleList.push_back(TargetMod);
SmallVector<ImportDecl *, 1> ImportDecls;
llvm::DenseSet<const clang::Module *> ClangModulesForImports;
@@ -485,6 +482,10 @@ void swift::ide::printModuleInterface(
ClangDecls.insert({ CM, {} });
if (CM != TargetClangMod)
if (auto *OwningModule = Importer.getWrapperForModule(CM))
ModuleList.push_back(OwningModule);
// If we're supposed to visit submodules, add them now.
if (TraversalOptions & ModuleTraversal::VisitSubmodules) {
for (clang::Module * submodule: CM->submodules()) {
@@ -499,6 +500,12 @@ void swift::ide::printModuleInterface(
}
}
SmallVector<Decl *, 1> Decls;
for (ModuleDecl *M : ModuleList) {
swift::getTopLevelDeclsForDisplay(M, Decls);
}
// Collect those submodules that are actually imported but have no import
// decls in the module.
llvm::SmallPtrSet<const clang::Module *, 16> NoImportSubModules;

View File

@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/DeclObjC.h"
#include "clang/Basic/Module.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Comment.h"
#include "swift/AST/Decl.h"
@@ -624,14 +625,14 @@ void SymbolGraph::serialize(llvm::json::OStream &OS) {
OS.attributeObject("module", [&](){
if (DeclaringModule) {
// A cross-import overlay can be considered part of its declaring module
OS.attribute("name", (*DeclaringModule)->getNameStr());
OS.attribute("name", getFullModuleName(*DeclaringModule));
std::vector<StringRef> B;
for (auto BModule : BystanderModules) {
B.push_back(BModule.str());
}
OS.attribute("bystanders", B);
} else {
OS.attribute("name", M.getNameStr());
OS.attribute("name", getFullModuleName(&M));
}
AttributeRAII Platform("platform", OS);
@@ -896,7 +897,15 @@ bool SymbolGraph::canIncludeDeclAsNode(const Decl *D,
// If this decl isn't in this module or module that this module imported with `@_exported`, don't record it,
// as it will appear elsewhere in its module's symbol graph.
if (D->getModuleContext()->getName() != M.getName() && !Walker.isConsideredExportedImported(D)) {
// If a Clang decl was declared in a submodule, the Swift decl's context will still point to the
// top-level module. Instead, we need to probe the owning module on the Clang side, which will
// correctly point to the submodule.
auto RealModuleName = (std::string)D->getModuleContext()->getName();
if (auto *ClangDecl = D->getClangDecl())
if (auto *ClangModule = ClangDecl->getOwningModule())
RealModuleName = ClangModule->Name;
if (RealModuleName != (std::string)M.getName() && !Walker.isConsideredExportedImported(D)) {
return false;
}

View File

@@ -10,7 +10,11 @@
//
//===----------------------------------------------------------------------===//
#include "clang/AST/DeclObjC.h"
#include "clang/Basic/Module.h"
#include "llvm/ADT/StringSwitch.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/ClangModuleLoader.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Module.h"
#include "swift/AST/ProtocolConformance.h"
@@ -41,6 +45,36 @@ bool areModulesEqual(const ModuleDecl *lhs, const ModuleDecl *rhs, bool isClangE
return true;
}
bool clangModuleExports(const clang::Module *ClangParent, const clang::Module *CM) {
if (!ClangParent || !CM) return false;
if (ClangParent == CM) return true;
for (auto ClangExport : ClangParent->Exports) {
auto *ExportedModule = ClangExport.getPointer();
if (ClangExport.getInt()) {
if (!ExportedModule && CM->isSubModuleOf(ClangParent)) {
return true;
} else if (ExportedModule && CM->isSubModuleOf(ExportedModule)) {
return true;
}
}
if (ExportedModule && clangModuleExports(ExportedModule, CM)) {
return true;
}
}
if (ClangParent->Exports.empty() && CM->isSubModuleOf(ClangParent)) {
// HACK: In the absence of an explicit export statement, consider any submodule to be exported.
return true;
}
return false;
}
bool underlyingClangModuleExports(const ModuleDecl *ParentModule, const ModuleDecl *M) {
return clangModuleExports(ParentModule->findUnderlyingClangModule(), M->findUnderlyingClangModule());
}
} // anonymous namespace
SymbolGraphASTWalker::SymbolGraphASTWalker(ModuleDecl &M,
@@ -57,20 +91,32 @@ SymbolGraphASTWalker::SymbolGraphASTWalker(
QualifiedExportedImports(QualifiedExportedImports),
MainGraph(*this, M, std::nullopt, Ctx) {}
ModuleDecl *SymbolGraphASTWalker::getRealModuleOf(const Decl *D) const {
ModuleDecl *Module = D->getModuleContext();
if (auto *ClangDecl = D->getClangDecl())
if (auto *ClangModule = ClangDecl->getOwningModule())
if (auto *ClangModuleLoader = D->getASTContext().getClangModuleLoader())
if (auto *M = ClangModuleLoader->getWrapperForModule(ClangModule))
Module = M;
return Module;
}
/// Get a "sub" symbol graph for the parent module of a type that
/// the main module `M` is extending.
SymbolGraph *SymbolGraphASTWalker::getModuleSymbolGraph(const Decl *D) {
auto *M = D->getModuleContext();
auto *M = getRealModuleOf(D);
const auto *DC = D->getDeclContext();
SmallVector<const NominalTypeDecl *, 2> ParentTypes = {};
const Decl *ExtendedNominal = nullptr;
while (DC) {
M = DC->getParentModule();
if (const auto *NTD = dyn_cast_or_null<NominalTypeDecl>(DC->getAsDecl())) {
DC = NTD->getDeclContext();
M = getRealModuleOf(NTD);
ParentTypes.push_back(NTD);
} else if (const auto *Ext = dyn_cast_or_null<ExtensionDecl>(DC->getAsDecl())) {
DC = Ext->getExtendedNominal()->getDeclContext();
M = getRealModuleOf(Ext->getExtendedNominal());
if (!ExtendedNominal)
ExtendedNominal = Ext->getExtendedNominal();
} else {
@@ -78,26 +124,42 @@ SymbolGraph *SymbolGraphASTWalker::getModuleSymbolGraph(const Decl *D) {
}
}
if (areModulesEqual(&this->M, M)) {
return &MainGraph;
} else if (MainGraph.DeclaringModule.has_value() &&
areModulesEqual(MainGraph.DeclaringModule.value(), M)) {
// Cross-import overlay modules already appear as "extensions" of their declaring module; we
// should put actual extensions of that module into the main graph
return &MainGraph;
}
auto moduleIsMainGraph = [&](const ModuleDecl *M) {
if (areModulesEqual(&this->M, M)) {
return true;
} else if (MainGraph.DeclaringModule.has_value() &&
areModulesEqual(MainGraph.DeclaringModule.value(), M)) {
// Cross-import overlay modules already appear as "extensions" of their declaring module; we
// should put actual extensions of that module into the main graph
return true;
}
// Check the module and decl separately since the extension could be from a different module
// than the decl itself.
if (isExportedImportedModule(M) || isQualifiedExportedImport(D)) {
// Check the module and decl separately since the extension could be from a different module
// than the decl itself.
if (isExportedImportedModule(M)) {
return true;
}
return false;
};
if (moduleIsMainGraph(M) || isQualifiedExportedImport(D))
return &MainGraph;
}
// If this type is the child of a type which was re-exported in a qualified export, use the main graph.
if (llvm::any_of(ParentTypes, [&](const NominalTypeDecl *NTD){ return isQualifiedExportedImport(NTD); })) {
return &MainGraph;
}
// As a shorthand when dealing with Clang submodules, use their top-level module's graph if the
// submodule is ultimately exported from its top-level module.
auto *TopLevelModule = M->getTopLevelModule();
if (TopLevelModule != M && underlyingClangModuleExports(TopLevelModule, M))
M = TopLevelModule;
if (moduleIsMainGraph(M))
return &MainGraph;
auto Found = ExtendedModuleGraphs.find(M->getNameStr());
if (Found != ExtendedModuleGraphs.end()) {
return Found->getValue();
@@ -328,7 +390,7 @@ bool SymbolGraphASTWalker::isConsideredExportedImported(const Decl *D) const {
}
bool SymbolGraphASTWalker::isFromExportedImportedModule(const Decl* D, bool countUnderlyingClangModule) const {
auto *M = D->getModuleContext();
auto *M = getRealModuleOf(D);
return isQualifiedExportedImport(D) || isExportedImportedModule(M, countUnderlyingClangModule);
}

View File

@@ -21,6 +21,8 @@
#include "SymbolGraph.h"
#include <string>
namespace swift {
class Decl;
@@ -144,8 +146,22 @@ public:
/// extension block symbol, or if its members should be directly associated
/// with its extended nominal.
virtual bool shouldBeRecordedAsExtension(const ExtensionDecl *ED) const;
/// Returns the owning module of the given decl. Loads the module from Clang if necessary, to
/// correctly fetch owning submodules.
virtual ModuleDecl *getRealModuleOf(const Decl *D) const;
};
LLVM_ATTRIBUTE_USED
static std::string getFullModuleName(const ModuleDecl *M) {
if (!M) return "";
std::string fullName;
llvm::raw_string_ostream OS(fullName);
M->getReverseFullModuleName().printForward(OS);
return fullName;
}
} // end namespace symbolgraphgen
} // end namespace swift

View File

@@ -17,6 +17,7 @@
#include "swift/AST/Module.h"
#include "swift/AST/NameLookup.h"
#include "swift/Sema/IDETypeChecking.h"
#include "clang/Basic/Module.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/Path.h"
@@ -30,14 +31,16 @@ namespace {
int serializeSymbolGraph(SymbolGraph &SG,
const SymbolGraphOptions &Options) {
SmallString<256> FileName;
FileName.append(SG.M.getNameStr());
FileName.append(getFullModuleName(&SG.M));
if (SG.ExtendedModule.has_value()) {
FileName.push_back('@');
FileName.append(SG.ExtendedModule.value()->getNameStr());
// FileName.append(SG.ExtendedModule.value()->getNameStr());
FileName.append(getFullModuleName(SG.ExtendedModule.value()));
} else if (SG.DeclaringModule.has_value()) {
// Treat cross-import overlay modules as "extensions" of their declaring module
FileName.push_back('@');
FileName.append(SG.DeclaringModule.value()->getNameStr());
// FileName.append(SG.DeclaringModule.value()->getNameStr());
FileName.append(getFullModuleName(SG.DeclaringModule.value()));
}
FileName.append(".symbols.json");
@@ -62,18 +65,60 @@ int symbolgraphgen::emitSymbolGraphForModule(
ModuleDecl *M, const SymbolGraphOptions &Options) {
ModuleDecl::ImportCollector importCollector(Options.MinimumAccessLevel);
auto importFilter = [&Options](const ModuleDecl *module) {
if (!module)
return false;
SmallPtrSet<const clang::Module *, 2> ExportedClangModules = {};
SmallPtrSet<const clang::Module *, 2> WildcardExportClangModules = {};
if (const auto *ClangModule = M->findUnderlyingClangModule()) {
// Scan through the Clang module's exports and collect them for later
// handling
for (auto ClangExport : ClangModule->Exports) {
if (ClangExport.getInt()) {
// Blanket exports are represented as a true boolean tag
if (const auto *ExportParent = ClangExport.getPointer()) {
// If a pointer is present, this is a scoped blanket export, like
// `export Submodule.*`
WildcardExportClangModules.insert(ExportParent);
} else {
// Otherwise it represents a full blanket `export *`
WildcardExportClangModules.insert(ClangModule);
}
} else if (!ClangExport.getInt() && ClangExport.getPointer()) {
// This is an explicit `export Submodule`
ExportedClangModules.insert(ClangExport.getPointer());
}
}
if (ExportedClangModules.empty() && WildcardExportClangModules.empty()) {
// HACK: In the absence of an explicit export declaration, export all of the submodules.
WildcardExportClangModules.insert(ClangModule);
}
}
auto importFilter = [&Options, &WildcardExportClangModules,
&ExportedClangModules](const ModuleDecl *module) {
if (!module)
return false;
if (const auto *ClangModule = module->findUnderlyingClangModule()) {
if (ExportedClangModules.contains(ClangModule)) {
return true;
}
for (const auto *ClangParent : WildcardExportClangModules) {
if (ClangModule->isSubModuleOf(ClangParent))
return true;
}
}
if (Options.AllowedReexportedModules.has_value())
for (const auto &allowedModuleName : *Options.AllowedReexportedModules)
if (allowedModuleName == module->getNameStr())
return true;
return false;
};
return false;
};
if (Options.AllowedReexportedModules.has_value())
if (Options.AllowedReexportedModules.has_value() ||
!WildcardExportClangModules.empty() || !ExportedClangModules.empty())
importCollector.importFilter = std::move(importFilter);
SmallVector<Decl *, 64> ModuleDecls;

View File

@@ -10,10 +10,10 @@
// CHECK-NEXT: init()
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: struct BasicB {
// CHECK-NEXT: init()
// CHECK-NEXT: }
// CHECK-NEXT: struct BasicA {
// CHECK-NEXT: init()
// CHECK-NEXT: }
// CHECK-NEXT: struct BasicB {
// CHECK-NEXT: init()
// CHECK-NEXT: }
// CHECK-NEXT: }

View File

@@ -1,4 +1,3 @@
import FooHelper
func fooSubFunc1(_ a: Int32) -> Int32
@@ -27,324 +26,314 @@ var FooSubUnnamedEnumeratorA1: Int { get }
[
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 0,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 7,
key.length: 9
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 18,
key.offset: 1,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 23,
key.offset: 6,
key.length: 11
},
{
key.kind: source.lang.swift.syntaxtype.argument,
key.offset: 35,
key.offset: 18,
key.length: 1
},
{
key.kind: source.lang.swift.syntaxtype.parameter,
key.offset: 37,
key.offset: 20,
key.length: 1
},
{
key.kind: source.lang.swift.ref.struct,
key.name: "Int32",
key.usr: "s:s5Int32V",
key.offset: 40,
key.offset: 23,
key.length: 5
},
{
key.kind: source.lang.swift.ref.struct,
key.name: "Int32",
key.usr: "s:s5Int32V",
key.offset: 50,
key.offset: 33,
key.length: 5
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 57,
key.offset: 40,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 64,
key.offset: 47,
key.length: 11
},
{
key.kind: source.lang.swift.ref.protocol,
key.name: "Hashable",
key.usr: "s:SH",
key.offset: 78,
key.offset: 61,
key.length: 8
},
{
key.kind: source.lang.swift.ref.protocol,
key.name: "Equatable",
key.usr: "s:SQ",
key.offset: 88,
key.offset: 71,
key.length: 9
},
{
key.kind: source.lang.swift.ref.protocol,
key.name: "RawRepresentable",
key.usr: "s:SY",
key.offset: 99,
key.offset: 82,
key.length: 16
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 123,
key.offset: 106,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.argument,
key.offset: 128,
key.offset: 111,
key.length: 1
},
{
key.kind: source.lang.swift.syntaxtype.parameter,
key.offset: 130,
key.offset: 113,
key.length: 8
},
{
key.kind: source.lang.swift.ref.struct,
key.name: "UInt32",
key.usr: "s:s6UInt32V",
key.offset: 140,
key.offset: 123,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 153,
key.offset: 136,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.argument,
key.offset: 158,
key.offset: 141,
key.length: 8
},
{
key.kind: source.lang.swift.syntaxtype.parameter,
key.offset: 167,
key.offset: 150,
key.length: 8
},
{
key.kind: source.lang.swift.ref.struct,
key.name: "UInt32",
key.usr: "s:s6UInt32V",
key.offset: 177,
key.offset: 160,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 190,
key.offset: 173,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 194,
key.offset: 177,
key.length: 8
},
{
key.kind: source.lang.swift.ref.struct,
key.name: "UInt32",
key.usr: "s:s6UInt32V",
key.offset: 204,
key.offset: 187,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 216,
key.offset: 199,
key.length: 10
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 227,
key.offset: 210,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 231,
key.offset: 214,
key.length: 9
},
{
key.kind: source.lang.swift.ref.struct,
key.name: "Int",
key.usr: "s:Si",
key.offset: 242,
key.offset: 225,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 248,
key.offset: 231,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 259,
key.offset: 242,
key.length: 10
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 270,
key.offset: 253,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 275,
key.offset: 258,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.argument,
key.offset: 280,
key.offset: 263,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.parameter,
key.offset: 285,
key.offset: 268,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 293,
key.offset: 276,
key.length: 5
},
{
key.kind: source.lang.swift.ref.struct,
key.name: "Hasher",
key.usr: "s:s6HasherV",
key.offset: 299,
key.offset: 282,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 312,
key.offset: 295,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 319,
key.offset: 302,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.operator,
key.offset: 324,
key.offset: 307,
key.length: 2
},
{
key.kind: source.lang.swift.syntaxtype.argument,
key.offset: 328,
key.offset: 311,
key.length: 1
},
{
key.kind: source.lang.swift.syntaxtype.parameter,
key.offset: 330,
key.offset: 313,
key.length: 3
},
{
key.kind: source.lang.swift.ref.struct,
key.name: "FooSubEnum1",
key.usr: "c:@E@FooSubEnum1",
key.offset: 335,
key.offset: 318,
key.length: 11
},
{
key.kind: source.lang.swift.syntaxtype.argument,
key.offset: 348,
key.offset: 331,
key.length: 1
},
{
key.kind: source.lang.swift.syntaxtype.parameter,
key.offset: 350,
key.offset: 333,
key.length: 3
},
{
key.kind: source.lang.swift.ref.struct,
key.name: "FooSubEnum1",
key.usr: "c:@E@FooSubEnum1",
key.offset: 355,
key.offset: 338,
key.length: 11
},
{
key.kind: source.lang.swift.ref.struct,
key.name: "Bool",
key.usr: "s:Sb",
key.offset: 371,
key.offset: 354,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 379,
key.offset: 362,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 383,
key.offset: 366,
key.length: 12
},
{
key.kind: source.lang.swift.ref.struct,
key.name: "FooSubEnum1",
key.usr: "c:@E@FooSubEnum1",
key.offset: 397,
key.offset: 380,
key.length: 11
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 411,
key.offset: 394,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 418,
key.offset: 401,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 422,
key.offset: 405,
key.length: 12
},
{
key.kind: source.lang.swift.ref.struct,
key.name: "FooSubEnum1",
key.usr: "c:@E@FooSubEnum1",
key.offset: 436,
key.offset: 419,
key.length: 11
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 450,
key.offset: 433,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 457,
key.offset: 440,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 461,
key.offset: 444,
key.length: 25
},
{
key.kind: source.lang.swift.ref.struct,
key.name: "Int",
key.usr: "s:Si",
key.offset: 488,
key.offset: 471,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 494,
key.offset: 477,
key.length: 3
}
]
@@ -353,7 +342,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.function.free,
key.name: "fooSubFunc1(_:)",
key.usr: "c:@F@fooSubFunc1",
key.offset: 18,
key.offset: 1,
key.length: 37,
key.fully_annotated_decl: "<decl.function.free><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>fooSubFunc1</decl.name>(<decl.var.parameter><decl.var.parameter.argument_label>_</decl.var.parameter.argument_label> <decl.var.parameter.name>a</decl.var.parameter.name>: <decl.var.parameter.type><ref.struct usr=\"s:s5Int32V\">Int32</ref.struct></decl.var.parameter.type></decl.var.parameter>) -&gt; <decl.function.returntype><ref.struct usr=\"s:s5Int32V\">Int32</ref.struct></decl.function.returntype></decl.function.free>",
key.entities: [
@@ -361,7 +350,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.var.local,
key.keyword: "_",
key.name: "a",
key.offset: 40,
key.offset: 23,
key.length: 5
}
],
@@ -371,7 +360,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.struct,
key.name: "FooSubEnum1",
key.usr: "c:@E@FooSubEnum1",
key.offset: 57,
key.offset: 40,
key.length: 320,
key.fully_annotated_decl: "<decl.struct><syntaxtype.keyword>struct</syntaxtype.keyword> <decl.name>FooSubEnum1</decl.name> : <ref.protocol usr=\"s:SH\">Hashable</ref.protocol>, <ref.protocol usr=\"s:SQ\">Equatable</ref.protocol>, <ref.protocol usr=\"s:SY\">RawRepresentable</ref.protocol></decl.struct>",
key.conforms: [
@@ -396,7 +385,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.function.constructor,
key.name: "init(_:)",
key.usr: "s:So11FooSubEnum1VyABs6UInt32Vcfc",
key.offset: 123,
key.offset: 106,
key.length: 24,
key.fully_annotated_decl: "<decl.function.constructor><syntaxtype.keyword>init</syntaxtype.keyword>(<decl.var.parameter><decl.var.parameter.argument_label>_</decl.var.parameter.argument_label> <decl.var.parameter.name>rawValue</decl.var.parameter.name>: <decl.var.parameter.type><ref.struct usr=\"s:s6UInt32V\">UInt32</ref.struct></decl.var.parameter.type></decl.var.parameter>)</decl.function.constructor>",
key.entities: [
@@ -404,7 +393,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.var.local,
key.keyword: "_",
key.name: "rawValue",
key.offset: 140,
key.offset: 123,
key.length: 6
}
]
@@ -413,7 +402,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.function.constructor,
key.name: "init(rawValue:)",
key.usr: "s:So11FooSubEnum1V8rawValueABs6UInt32V_tcfc",
key.offset: 153,
key.offset: 136,
key.length: 31,
key.fully_annotated_decl: "<decl.function.constructor><syntaxtype.keyword>init</syntaxtype.keyword>(<decl.var.parameter><decl.var.parameter.argument_label>rawValue</decl.var.parameter.argument_label>: <decl.var.parameter.type><ref.struct usr=\"s:s6UInt32V\">UInt32</ref.struct></decl.var.parameter.type></decl.var.parameter>)</decl.function.constructor>",
key.entities: [
@@ -421,7 +410,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.var.local,
key.keyword: "rawValue",
key.name: "rawValue",
key.offset: 177,
key.offset: 160,
key.length: 6
}
]
@@ -430,7 +419,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.var.instance,
key.name: "rawValue",
key.usr: "s:So11FooSubEnum1V8rawValues6UInt32Vvp",
key.offset: 190,
key.offset: 173,
key.length: 20,
key.fully_annotated_decl: "<decl.var.instance><syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>rawValue</decl.name>: <decl.var.type><ref.struct usr=\"s:s6UInt32V\">UInt32</ref.struct></decl.var.type></decl.var.instance>"
},
@@ -439,7 +428,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.name: "hashValue",
key.usr: "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp::SYNTHESIZED::c:@E@FooSubEnum1",
key.original_usr: "s:SYsSHRzSH8RawValueSYRpzrlE04hashB0Sivp",
key.offset: 216,
key.offset: 199,
key.length: 37,
key.fully_annotated_decl: "<decl.var.instance><syntaxtype.attribute.builtin><syntaxtype.attribute.name>@inlinable</syntaxtype.attribute.name></syntaxtype.attribute.builtin> <syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>hashValue</decl.name>: <decl.var.type><ref.struct usr=\"s:Si\">Int</ref.struct></decl.var.type> { <syntaxtype.keyword>get</syntaxtype.keyword> }</decl.var.instance>"
},
@@ -448,7 +437,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.name: "hash(into:)",
key.usr: "s:SYsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF::SYNTHESIZED::c:@E@FooSubEnum1",
key.original_usr: "s:SYsSHRzSH8RawValueSYRpzrlE4hash4intoys6HasherVz_tF",
key.offset: 259,
key.offset: 242,
key.length: 47,
key.fully_annotated_decl: "<decl.function.method.instance><syntaxtype.attribute.builtin><syntaxtype.attribute.name>@inlinable</syntaxtype.attribute.name></syntaxtype.attribute.builtin> <syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>hash</decl.name>(<decl.var.parameter><decl.var.parameter.argument_label>into</decl.var.parameter.argument_label> <decl.var.parameter.name>hasher</decl.var.parameter.name>: <syntaxtype.keyword>inout</syntaxtype.keyword> <decl.var.parameter.type><ref.struct usr=\"s:s6HasherV\">Hasher</ref.struct></decl.var.parameter.type></decl.var.parameter>)</decl.function.method.instance>",
key.entities: [
@@ -456,7 +445,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.var.local,
key.keyword: "into",
key.name: "hasher",
key.offset: 299,
key.offset: 282,
key.length: 6
}
]
@@ -467,7 +456,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.usr: "s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::c:@E@FooSubEnum1",
key.original_usr: "s:SQsE2neoiySbx_xtFZ",
key.doc.full_as_xml: "<Function><Name>!=(_:_:)</Name><USR>s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::c:@E@FooSubEnum1</USR><Declaration>static func != (lhs: FooSubEnum1, rhs: FooSubEnum1) -&gt; Bool</Declaration><CommentParts><Abstract><Para>Returns a Boolean value indicating whether two values are not equal.</Para></Abstract><Parameters><Parameter><Name>lhs</Name><Direction isExplicit=\"0\">in</Direction><Discussion><Para>A value to compare.</Para></Discussion></Parameter><Parameter><Name>rhs</Name><Direction isExplicit=\"0\">in</Direction><Discussion><Para>Another value to compare.</Para></Discussion></Parameter></Parameters><Discussion><Para>Inequality is the inverse of equality. For any values <codeVoice>a</codeVoice> and <codeVoice>b</codeVoice>, <codeVoice>a != b</codeVoice> implies that <codeVoice>a == b</codeVoice> is <codeVoice>false</codeVoice>.</Para><Para>This is the default implementation of the not-equal-to operator (<codeVoice>!=</codeVoice>) for any type that conforms to <codeVoice>Equatable</codeVoice>.</Para></Discussion></CommentParts></Function>",
key.offset: 312,
key.offset: 295,
key.length: 63,
key.fully_annotated_decl: "<decl.function.operator.infix><syntaxtype.keyword>static</syntaxtype.keyword> <syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>!= </decl.name>(<decl.var.parameter><decl.var.parameter.name>lhs</decl.var.parameter.name>: <decl.var.parameter.type><ref.struct usr=\"c:@E@FooSubEnum1\">FooSubEnum1</ref.struct></decl.var.parameter.type></decl.var.parameter>, <decl.var.parameter><decl.var.parameter.name>rhs</decl.var.parameter.name>: <decl.var.parameter.type><ref.struct usr=\"c:@E@FooSubEnum1\">FooSubEnum1</ref.struct></decl.var.parameter.type></decl.var.parameter>) -&gt; <decl.function.returntype><ref.struct usr=\"s:Sb\">Bool</ref.struct></decl.function.returntype></decl.function.operator.infix>",
key.entities: [
@@ -475,14 +464,14 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.var.local,
key.keyword: "_",
key.name: "lhs",
key.offset: 335,
key.offset: 318,
key.length: 11
},
{
key.kind: source.lang.swift.decl.var.local,
key.keyword: "_",
key.name: "rhs",
key.offset: 355,
key.offset: 338,
key.length: 11
}
]
@@ -494,7 +483,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.var.global,
key.name: "FooSubEnum1X",
key.usr: "c:@E@FooSubEnum1@FooSubEnum1X",
key.offset: 379,
key.offset: 362,
key.length: 37,
key.fully_annotated_decl: "<decl.var.global><syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>FooSubEnum1X</decl.name>: <decl.var.type><ref.struct usr=\"c:@E@FooSubEnum1\">FooSubEnum1</ref.struct></decl.var.type> { <syntaxtype.keyword>get</syntaxtype.keyword> }</decl.var.global>",
key.modulename: "Foo.FooSub"
@@ -503,7 +492,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.var.global,
key.name: "FooSubEnum1Y",
key.usr: "c:@E@FooSubEnum1@FooSubEnum1Y",
key.offset: 418,
key.offset: 401,
key.length: 37,
key.fully_annotated_decl: "<decl.var.global><syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>FooSubEnum1Y</decl.name>: <decl.var.type><ref.struct usr=\"c:@E@FooSubEnum1\">FooSubEnum1</ref.struct></decl.var.type> { <syntaxtype.keyword>get</syntaxtype.keyword> }</decl.var.global>",
key.modulename: "Foo.FooSub"
@@ -512,7 +501,7 @@ var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.var.global,
key.name: "FooSubUnnamedEnumeratorA1",
key.usr: "c:@Ea@FooSubUnnamedEnumeratorA1@FooSubUnnamedEnumeratorA1",
key.offset: 457,
key.offset: 440,
key.length: 42,
key.fully_annotated_decl: "<decl.var.global><syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>FooSubUnnamedEnumeratorA1</decl.name>: <decl.var.type><ref.struct usr=\"s:Si\">Int</ref.struct></decl.var.type> { <syntaxtype.keyword>get</syntaxtype.keyword> }</decl.var.global>",
key.modulename: "Foo.FooSub"

View File

@@ -1,4 +1,3 @@
import FooHelper
public func fooSubFunc1(_ a: Int32) -> Int32
@@ -20,288 +19,273 @@ public var FooSubUnnamedEnumeratorA1: Int { get }
[
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 0,
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 1,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 8,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 7,
key.length: 9
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 18,
key.length: 6
key.offset: 13,
key.length: 11
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 25,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 30,
key.length: 11
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 42,
key.length: 1
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 44,
key.offset: 27,
key.length: 1
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 47,
key.offset: 30,
key.length: 5
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 57,
key.offset: 40,
key.length: 5
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 64,
key.offset: 47,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 71,
key.offset: 54,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 78,
key.offset: 61,
key.length: 11
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 92,
key.offset: 75,
key.length: 8
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 102,
key.offset: 85,
key.length: 9
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 113,
key.offset: 96,
key.length: 16
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 137,
key.offset: 120,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 144,
key.offset: 127,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 149,
key.offset: 132,
key.length: 1
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 151,
key.offset: 134,
key.length: 8
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 161,
key.offset: 144,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 174,
key.offset: 157,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 181,
key.offset: 164,
key.length: 4
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 186,
key.offset: 169,
key.length: 8
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 196,
key.offset: 179,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 209,
key.offset: 192,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 216,
key.offset: 199,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 220,
key.offset: 203,
key.length: 8
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 213,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 223,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 230,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 240,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 247,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 251,
key.offset: 234,
key.length: 12
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 265,
key.offset: 248,
key.length: 11
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 279,
key.offset: 262,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 286,
key.offset: 269,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 293,
key.offset: 276,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 297,
key.offset: 280,
key.length: 12
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 311,
key.offset: 294,
key.length: 11
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 325,
key.offset: 308,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.attribute.builtin,
key.offset: 332,
key.offset: 315,
key.length: 6
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 339,
key.offset: 322,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.identifier,
key.offset: 343,
key.offset: 326,
key.length: 25
},
{
key.kind: source.lang.swift.syntaxtype.typeidentifier,
key.offset: 370,
key.offset: 353,
key.length: 3
},
{
key.kind: source.lang.swift.syntaxtype.keyword,
key.offset: 376,
key.offset: 359,
key.length: 3
}
]
[
{
key.kind: source.lang.swift.ref.module,
key.offset: 7,
key.length: 9
},
{
key.kind: source.lang.swift.ref.struct,
key.offset: 47,
key.offset: 30,
key.length: 5,
key.is_system: 1
},
{
key.kind: source.lang.swift.ref.struct,
key.offset: 57,
key.offset: 40,
key.length: 5,
key.is_system: 1
},
{
key.kind: source.lang.swift.ref.protocol,
key.offset: 92,
key.offset: 75,
key.length: 8,
key.is_system: 1
},
{
key.kind: source.lang.swift.ref.protocol,
key.offset: 102,
key.offset: 85,
key.length: 9,
key.is_system: 1
},
{
key.kind: source.lang.swift.ref.protocol,
key.offset: 113,
key.offset: 96,
key.length: 16,
key.is_system: 1
},
{
key.kind: source.lang.swift.ref.struct,
key.offset: 161,
key.offset: 144,
key.length: 6,
key.is_system: 1
},
{
key.kind: source.lang.swift.ref.struct,
key.offset: 196,
key.offset: 179,
key.length: 6,
key.is_system: 1
},
{
key.kind: source.lang.swift.ref.struct,
key.offset: 230,
key.offset: 213,
key.length: 6,
key.is_system: 1
},
{
key.kind: source.lang.swift.ref.struct,
key.offset: 265,
key.offset: 248,
key.length: 11
},
{
key.kind: source.lang.swift.ref.struct,
key.offset: 311,
key.offset: 294,
key.length: 11
},
{
key.kind: source.lang.swift.ref.struct,
key.offset: 370,
key.offset: 353,
key.length: 3,
key.is_system: 1
}
@@ -311,14 +295,14 @@ public var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.function.free,
key.accessibility: source.lang.swift.accessibility.public,
key.name: "fooSubFunc1(_:)",
key.offset: 25,
key.offset: 8,
key.length: 37,
key.typename: "Int32",
key.nameoffset: 30,
key.nameoffset: 13,
key.namelength: 23,
key.attributes: [
{
key.offset: 18,
key.offset: 1,
key.length: 6,
key.attribute: source.decl.attribute.public
}
@@ -327,7 +311,7 @@ public var FooSubUnnamedEnumeratorA1: Int { get }
{
key.kind: source.lang.swift.decl.var.parameter,
key.name: "a",
key.offset: 42,
key.offset: 25,
key.length: 10,
key.typename: "Int32"
}
@@ -337,11 +321,11 @@ public var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.struct,
key.accessibility: source.lang.swift.accessibility.public,
key.name: "FooSubEnum1",
key.offset: 71,
key.offset: 54,
key.length: 167,
key.nameoffset: 78,
key.nameoffset: 61,
key.namelength: 11,
key.bodyoffset: 131,
key.bodyoffset: 114,
key.bodylength: 106,
key.inheritedtypes: [
{
@@ -356,7 +340,7 @@ public var FooSubUnnamedEnumeratorA1: Int { get }
],
key.attributes: [
{
key.offset: 64,
key.offset: 47,
key.length: 6,
key.attribute: source.decl.attribute.public
}
@@ -364,17 +348,17 @@ public var FooSubUnnamedEnumeratorA1: Int { get }
key.elements: [
{
key.kind: source.lang.swift.structure.elem.typeref,
key.offset: 92,
key.offset: 75,
key.length: 8
},
{
key.kind: source.lang.swift.structure.elem.typeref,
key.offset: 102,
key.offset: 85,
key.length: 9
},
{
key.kind: source.lang.swift.structure.elem.typeref,
key.offset: 113,
key.offset: 96,
key.length: 16
}
],
@@ -383,13 +367,13 @@ public var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.function.method.instance,
key.accessibility: source.lang.swift.accessibility.public,
key.name: "init(_:)",
key.offset: 144,
key.offset: 127,
key.length: 24,
key.nameoffset: 144,
key.nameoffset: 127,
key.namelength: 24,
key.attributes: [
{
key.offset: 137,
key.offset: 120,
key.length: 6,
key.attribute: source.decl.attribute.public
}
@@ -398,7 +382,7 @@ public var FooSubUnnamedEnumeratorA1: Int { get }
{
key.kind: source.lang.swift.decl.var.parameter,
key.name: "rawValue",
key.offset: 149,
key.offset: 132,
key.length: 18,
key.typename: "UInt32"
}
@@ -408,13 +392,13 @@ public var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.function.method.instance,
key.accessibility: source.lang.swift.accessibility.public,
key.name: "init(rawValue:)",
key.offset: 181,
key.offset: 164,
key.length: 22,
key.nameoffset: 181,
key.nameoffset: 164,
key.namelength: 22,
key.attributes: [
{
key.offset: 174,
key.offset: 157,
key.length: 6,
key.attribute: source.decl.attribute.public
}
@@ -423,10 +407,10 @@ public var FooSubUnnamedEnumeratorA1: Int { get }
{
key.kind: source.lang.swift.decl.var.parameter,
key.name: "rawValue",
key.offset: 186,
key.offset: 169,
key.length: 16,
key.typename: "UInt32",
key.nameoffset: 186,
key.nameoffset: 169,
key.namelength: 8
}
]
@@ -436,14 +420,14 @@ public var FooSubUnnamedEnumeratorA1: Int { get }
key.accessibility: source.lang.swift.accessibility.public,
key.setter_accessibility: source.lang.swift.accessibility.public,
key.name: "rawValue",
key.offset: 216,
key.offset: 199,
key.length: 20,
key.typename: "UInt32",
key.nameoffset: 220,
key.nameoffset: 203,
key.namelength: 8,
key.attributes: [
{
key.offset: 209,
key.offset: 192,
key.length: 6,
key.attribute: source.decl.attribute.public
}
@@ -455,16 +439,16 @@ public var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.var.global,
key.accessibility: source.lang.swift.accessibility.public,
key.name: "FooSubEnum1X",
key.offset: 247,
key.offset: 230,
key.length: 37,
key.typename: "FooSubEnum1",
key.nameoffset: 251,
key.nameoffset: 234,
key.namelength: 12,
key.bodyoffset: 278,
key.bodyoffset: 261,
key.bodylength: 5,
key.attributes: [
{
key.offset: 240,
key.offset: 223,
key.length: 6,
key.attribute: source.decl.attribute.public
}
@@ -474,16 +458,16 @@ public var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.var.global,
key.accessibility: source.lang.swift.accessibility.public,
key.name: "FooSubEnum1Y",
key.offset: 293,
key.offset: 276,
key.length: 37,
key.typename: "FooSubEnum1",
key.nameoffset: 297,
key.nameoffset: 280,
key.namelength: 12,
key.bodyoffset: 324,
key.bodyoffset: 307,
key.bodylength: 5,
key.attributes: [
{
key.offset: 286,
key.offset: 269,
key.length: 6,
key.attribute: source.decl.attribute.public
}
@@ -493,16 +477,16 @@ public var FooSubUnnamedEnumeratorA1: Int { get }
key.kind: source.lang.swift.decl.var.global,
key.accessibility: source.lang.swift.accessibility.public,
key.name: "FooSubUnnamedEnumeratorA1",
key.offset: 339,
key.offset: 322,
key.length: 42,
key.typename: "Int",
key.nameoffset: 343,
key.nameoffset: 326,
key.namelength: 25,
key.bodyoffset: 375,
key.bodyoffset: 358,
key.bodylength: 5,
key.attributes: [
{
key.offset: 332,
key.offset: 315,
key.length: 6,
key.attribute: source.decl.attribute.public
}

View File

@@ -0,0 +1,85 @@
// RUN: %empty-directory(%t)
// RUN: split-file %s %t
// RUN: %target-swift-symbolgraph-extract -sdk %clang-importer-sdk -module-name PartialSubmoduleExport -I %t/PartialSubmoduleExport -output-dir %t -pretty-print -v
// RUN: %FileCheck %s --input-file %t/PartialSubmoduleExport.symbols.json
// check the missing symbols separately to account for arbitrary ordering
// RUN: %FileCheck %s --input-file %t/PartialSubmoduleExport.symbols.json --check-prefix MISSING
// REQUIRES: objc_interop
// The PartialSubmoduleExport module below is structured like this:
// PartialSubmoduleExport
// - GroupA
// - GroupAOne
// - GroupATwo
// - GroupB
// - GroupBOne
// - GroupBTwo
// The module map then exports `GroupA.*` and `GroupB.GroupBOne` explicitly.
// This test ensures that the expected symbols are in the module map,
// and that the deliberately excluded `groupBTwo` symbol is left out.
//--- PartialSubmoduleExport/module.modulemap
module PartialSubmoduleExport {
header "PartialSubmoduleExport.h"
explicit module GroupA {
umbrella header "GroupA/GroupA.h"
module * { export * }
}
explicit module GroupB {
umbrella header "GroupB/GroupB.h"
module * { export * }
}
export GroupA.*
export GroupB.GroupBOne
}
//--- PartialSubmoduleExport/PartialSubmoduleExport.h
#include "GroupA/GroupA.h"
#include "GroupB/GroupB.h"
// CHECK-DAG: "precise": "c:PartialSubmoduleExport.h@umbrellaVar"
static int umbrellaVar = 0;
//--- PartialSubmoduleExport/GroupA/GroupA.h
#include "GroupAOne.h"
#include "GroupATwo.h"
// CHECK-DAG: "precise": "c:GroupA.h@groupAVar"
static int groupAVar = 0;
//--- PartialSubmoduleExport/GroupA/GroupAOne.h
// CHECK-DAG: "precise": "c:GroupAOne.h@groupAOne"
static int groupAOne = 1;
//--- PartialSubmoduleExport/GroupA/GroupATwo.h
// CHECK-DAG: "precise": "c:GroupATwo.h@groupATwo"
static int groupATwo = 2;
//--- PartialSubmoduleExport/GroupB/GroupB.h
#include "GroupBOne.h"
#include "GroupBTwo.h"
// Because GroupB was not exported by itself, this symbol should be missing
// MISSING-NOT: "precise": "c:GroupB.h@groupBVar"
static int groupBVar = 0;
//--- PartialSubmoduleExport/GroupB/GroupBOne.h
// CHECK-DAG: "precise": "c:GroupBOne.h@groupBOne"
static int groupBOne = 1;
//--- PartialSubmoduleExport/GroupB/GroupBTwo.h
// Because GroupBTwo is not exported in the top-level module map,
// this shouldn't be in the symbol graph
// MISSING-NOT: "precise": "c:GroupBTwo.h@groupBTwo"
static int groupBTwo = 2;

View File

@@ -1,11 +1,19 @@
// RUN: %empty-directory(%t)
// Don't crash when a module declared an `@_exported import` for a Clang non-top-level module.
// RUN: cp -r %S/Inputs/EmitWhileBuilding/EmitWhileBuilding.framework %t
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-objc-interop -emit-module-path %t/EmitWhileBuilding.framework/Modules/EmitWhileBuilding.swiftmodule/%target-swiftmodule-name -import-underlying-module -F %t -module-name EmitWhileBuilding -disable-objc-attr-requires-foundation-module %S/EmitWhileBuilding.swift
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -I %S/Inputs/Submodules -emit-module-path %t/Submodules.swiftmodule -enable-objc-interop -module-name Submodules -F %t %s -emit-symbol-graph -emit-symbol-graph-dir %t
// REQUIRES: objc_interop
// When extracting symbol graphs for a Clang submodule, make sure that (1) the program passes
// without crashing, and (2) that the symbols correctly appear in the symbol graph.
// Don't crash when a module declared an `@_exported import` for a Clang non-top-level module.
// RUN: %empty-directory(%t)
// RUN: %target-swift-symbolgraph-extract -sdk %clang-importer-sdk -module-name Mixed.Submodule -I %S/Inputs/Submodules -output-dir %t -pretty-print -v
// RUN: %FileCheck %s --input-file %t/Mixed.Submodule.symbols.json --check-prefix SUBMODULE
// REQUIRES: objc_interop
@_exported import Mixed
@_exported import Mixed.Submodule
@@ -13,3 +21,6 @@
@_exported import EmitWhileBuilding
public func someFunc() {}
// SUBMODULE-DAG: "name": "Mixed.Submodule"
// SUBMODULE-DAG: "precise": "c:@innerVar"

View File

@@ -0,0 +1,40 @@
// RUN: %empty-directory(%t)
// RUN: split-file %s %t
// RUN: %target-swift-symbolgraph-extract -sdk %clang-importer-sdk -module-name SubmodulesNoExport -I %t/SubmodulesNoExport -output-dir %t -pretty-print -v
// RUN: %FileCheck %s --input-file %t/SubmodulesNoExport.symbols.json
// REQUIRES: objc_interop
// Make sure that a Clang module that declares submodules but doesn't have an export declaration
// still contains all the submodules' symbols.
//--- SubmodulesNoExport/module.modulemap
module SubmodulesNoExport {
header "SubmodulesNoExport.h"
module HeaderOne {
header "HeaderOne.h"
export *
}
module HeaderTwo {
header "HeaderTwo.h"
export *
}
}
//--- SubmodulesNoExport/SubmodulesNoExport.h
#include "HeaderOne.h"
#include "HeaderTwo.h"
// CHECK-DAG: "precise": "c:SubmodulesNoExport.h@umbrellaVar"
static int umbrellaVar = 0;
//--- SubmodulesNoExport/HeaderOne.h
// CHECK-DAG: "precise": "c:HeaderOne.h@varOne"
static int varOne = 1;
//--- SubmodulesNoExport/HeaderTwo.h
// CHECK-DAG: "precise": "c:HeaderTwo.h@varTwo"
static int varTwo = 2;

View File

@@ -0,0 +1,34 @@
// REQUIRES: objc_interop
// RUN: %empty-directory(%t)
// RUN: split-file %s %t
// RUN: %target-swift-symbolgraph-extract -sdk %clang-importer-sdk -module-name SwiftName -F %t/frameworks -output-dir %t -pretty-print -v
// RUN: %FileCheck %s --input-file %t/SwiftName.symbols.json
//--- frameworks/SwiftName.framework/Modules/module.modulemap
framework module SwiftName {
umbrella header "SwiftName.h"
export *
module * { export * }
}
//--- frameworks/SwiftName.framework/Headers/SwiftName.h
#import "OtherHeader.h"
typedef struct {
double val;
} MyDouble;
// The swift_name attribute below generates extension decls in both header modules, which trips an
// assertion if they are both added in getDisplayDecls. Make sure that this does not crash when a
// symbol graph is generated.
// CHECK-DAG: "precise": "c:SwiftName.h@MyDoubleFixedValue"
__attribute__((swift_name("MyDouble.FixedValue")))
static double MyDoubleFixedValue = 0.0;
//--- frameworks/SwiftName.framework/Headers/OtherHeader.h
// CHECK-DAG: "precise": "c:OtherHeader.h@myVar"
static int myVar = 0;

View File

@@ -0,0 +1,39 @@
// REQUIRES: objc_interop
// RUN: %empty-directory(%t)
// RUN: mkdir -p %t/frameworks/UmbrellaFramework.framework/Modules/UmbrellaFramework.swiftmodule
// RUN: split-file %s %t
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-objc-interop -emit-module -o %t/frameworks/UmbrellaFramework.framework/Modules/UmbrellaFramework.swiftmodule/%target-swiftmodule-name -import-underlying-module -F %t/frameworks -module-name UmbrellaFramework -disable-objc-attr-requires-foundation-module %t/UmbrellaSwift.swift -emit-symbol-graph -emit-symbol-graph-dir %t
// RUN: %target-swift-symbolgraph-extract -sdk %clang-importer-sdk -module-name UmbrellaFramework -F %t/frameworks -output-dir %t -pretty-print -v
// RUN: %FileCheck %s --input-file %t/UmbrellaFramework.symbols.json
// Ensure that Clang modules with umbrella headers and 'module * { export * }' correctly include
// all their headers' symbols when Swift symbols are also present.
//--- UmbrellaSwift.swift
@_exported import UmbrellaFramework
// CHECK-DAG: "precise": "s:17UmbrellaFramework12SomeProtocolP"
public protocol SomeProtocol {}
//--- frameworks/UmbrellaFramework.framework/Modules/module.modulemap
framework module UmbrellaFramework [system] {
umbrella header "UmbrellaFramework.h"
export *
module * { export * }
}
//--- frameworks/UmbrellaFramework.framework/Headers/UmbrellaFramework.h
#include "HeaderOne.h"
#include "HeaderTwo.h"
// CHECK-DAG: "precise": "c:@umbrellaVar"
static int umbrellaVar = 0;
//--- frameworks/UmbrellaFramework.framework/Headers/HeaderOne.h
// CHECK-DAG: "precise": "c:@varOne"
static int varOne = 1;
//--- frameworks/UmbrellaFramework.framework/Headers/HeaderTwo.h
// CHECK-DAG: "precise": "c:@varTwo"
static int varTwo = 2;

View File

@@ -0,0 +1,32 @@
// RUN: %empty-directory(%t)
// RUN: split-file %s %t
// RUN: %target-swift-symbolgraph-extract -sdk %clang-importer-sdk -module-name UmbrellaNoExport -I %t/UmbrellaNoExport -output-dir %t -pretty-print -v
// RUN: %FileCheck %s --input-file %t/UmbrellaNoExport.symbols.json
// REQUIRES: objc_interop
//--- UmbrellaNoExport/module.modulemap
module UmbrellaNoExport {
umbrella header "UmbrellaNoExport.h"
module * {
export *
}
}
//--- UmbrellaNoExport/UmbrellaNoExport.h
#include "HeaderOne.h"
#include "HeaderTwo.h"
// CHECK-DAG: "precise": "c:UmbrellaNoExport.h@umbrellaVar"
static int umbrellaVar = 0;
//--- UmbrellaNoExport/HeaderOne.h
// CHECK-DAG: "precise": "c:HeaderOne.h@varOne"
static int varOne = 1;
//--- UmbrellaNoExport/HeaderTwo.h
// CHECK-DAG: "precise": "c:HeaderTwo.h@varTwo"
static int varTwo = 2;

View File

@@ -0,0 +1,32 @@
// RUN: %empty-directory(%t)
// RUN: split-file %s %t
// RUN: %target-swift-symbolgraph-extract -sdk %clang-importer-sdk -module-name UmbrellaSubmodules -I %t/UmbrellaSubmodules -output-dir %t -pretty-print -v
// RUN: %FileCheck %s --input-file %t/UmbrellaSubmodules.symbols.json
// REQUIRES: objc_interop
//--- UmbrellaSubmodules/module.modulemap
module UmbrellaSubmodules {
umbrella header "UmbrellaSubmodules.h"
export *
module * {
export *
}
}
//--- UmbrellaSubmodules/UmbrellaSubmodules.h
#include "HeaderOne.h"
#include "HeaderTwo.h"
// CHECK-DAG: "precise": "c:UmbrellaSubmodules.h@umbrellaVar"
static int umbrellaVar = 0;
//--- UmbrellaSubmodules/HeaderOne.h
// CHECK-DAG: "precise": "c:HeaderOne.h@varOne"
static int varOne = 1;
//--- UmbrellaSubmodules/HeaderTwo.h
// CHECK-DAG: "precise": "c:HeaderTwo.h@varTwo"
static int varTwo = 2;