mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Serialize symbol graphs for extended modules separately
When a module extends a type from another module, serialize those symbols into separated files dedicated to those extended modules. This makes it easier to ingest and categorize those symbols under the extended module if desired. rdar://58941718
This commit is contained in:
@@ -403,6 +403,8 @@ public:
|
||||
SmallVectorImpl<GenericSignature> &genericSignatures)
|
||||
override;
|
||||
|
||||
StringRef getTargetTriple() const;
|
||||
|
||||
static bool classof(const FileUnit *file) {
|
||||
return file->getKind() == FileUnitKind::SerializedAST;
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ class ModuleDecl;
|
||||
namespace symbolgraphgen {
|
||||
|
||||
struct SymbolGraphOptions {
|
||||
/// The path to output the symbol graph JSON.
|
||||
StringRef OutputPath;
|
||||
/// The directory to output the symbol graph JSON files.
|
||||
StringRef OutputDir;
|
||||
|
||||
/// The target of the module.
|
||||
llvm::Triple Target;
|
||||
|
||||
@@ -823,6 +823,10 @@ public:
|
||||
return ModuleInputBuffer->getBufferIdentifier();
|
||||
}
|
||||
|
||||
StringRef getTargetTriple() const {
|
||||
return TargetTriple;
|
||||
}
|
||||
|
||||
/// AST-verify imported decls.
|
||||
///
|
||||
/// Has no effect in NDEBUG builds.
|
||||
|
||||
@@ -1181,6 +1181,10 @@ StringRef SerializedASTFile::getFilename() const {
|
||||
return File.getModuleFilename();
|
||||
}
|
||||
|
||||
StringRef SerializedASTFile::getTargetTriple() const {
|
||||
return File.getTargetTriple();
|
||||
}
|
||||
|
||||
const clang::Module *SerializedASTFile::getUnderlyingClangModule() const {
|
||||
if (auto *UnderlyingModule = File.getUnderlyingModule())
|
||||
return UnderlyingModule->findUnderlyingClangModule();
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#define SWIFT_SYMBOLGRAPHGEN_FORMATVERSION_H
|
||||
|
||||
#define SWIFT_SYMBOLGRAPH_FORMAT_MAJOR 0
|
||||
#define SWIFT_SYMBOLGRAPH_FORMAT_MINOR 2
|
||||
#define SWIFT_SYMBOLGRAPH_FORMAT_MINOR 3
|
||||
#define SWIFT_SYMBOLGRAPH_FORMAT_PATCH 0
|
||||
|
||||
#endif // SWIFT_SYMBOLGRAPHGEN_FORMATVERSION_H
|
||||
|
||||
@@ -256,7 +256,11 @@ void Symbol::serializeSwiftExtensionMixin(llvm::json::OStream &OS) const {
|
||||
if (const auto *Extension
|
||||
= dyn_cast_or_null<ExtensionDecl>(VD->getInnermostDeclContext())) {
|
||||
OS.attributeObject("swiftExtension", [&](){
|
||||
OS.attribute("definedInModule", Graph.M.getNameStr());
|
||||
if (const auto *ExtendedNominal = Extension->getExtendedNominal()) {
|
||||
if (const auto *ExtendedModule = ExtendedNominal->getModuleContext()) {
|
||||
OS.attribute("extendedModule", ExtendedModule->getNameStr());
|
||||
}
|
||||
}
|
||||
auto Generics = Extension->getGenericSignature();
|
||||
if (Generics && !Generics->getRequirements().empty()) {
|
||||
OS.attributeArray("constraints", [&](){
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "swift/AST/ProtocolConformance.h"
|
||||
#include "swift/AST/USRGeneration.h"
|
||||
#include "swift/Basic/Version.h"
|
||||
#include "swift/ClangImporter/ClangModule.h"
|
||||
#include "swift/Serialization/SerializedModuleLoader.h"
|
||||
|
||||
#include "DeclarationFragmentPrinter.h"
|
||||
#include "FormatVersion.h"
|
||||
@@ -25,10 +27,16 @@
|
||||
using namespace swift;
|
||||
using namespace symbolgraphgen;
|
||||
|
||||
SymbolGraph::SymbolGraph(ModuleDecl &M, llvm::Triple Target,
|
||||
SymbolGraph::SymbolGraph(ModuleDecl &M,
|
||||
Optional<ModuleDecl *> ExtendedModule,
|
||||
llvm::Triple Target,
|
||||
markup::MarkupContext &Ctx,
|
||||
Optional<llvm::VersionTuple> ModuleVersion)
|
||||
: M(M), Target(Target), Ctx(Ctx), ModuleVersion(ModuleVersion) {}
|
||||
: M(M),
|
||||
ExtendedModule(ExtendedModule),
|
||||
Target(Target),
|
||||
Ctx(Ctx),
|
||||
ModuleVersion(ModuleVersion) {}
|
||||
|
||||
// MARK: - Utilities
|
||||
|
||||
@@ -98,7 +106,23 @@ PrintOptions SymbolGraph::getDeclarationFragmentsPrintOptions() const {
|
||||
return Opts;
|
||||
}
|
||||
|
||||
// MARK: - Relationships
|
||||
// MARK: - Symbols (Nodes)
|
||||
|
||||
void SymbolGraph::recordNode(const ValueDecl *VD) {
|
||||
Nodes.insert(VD);
|
||||
|
||||
// Record all of the possible relationships (edges) originating
|
||||
// with this declaration.
|
||||
recordMemberRelationship(VD);
|
||||
recordConformanceRelationships(VD);
|
||||
recordInheritanceRelationships(VD);
|
||||
recordDefaultImplementationRelationships(VD);
|
||||
recordOverrideRelationship(VD);
|
||||
recordRequirementRelationships(VD);
|
||||
recordOptionalRequirementRelationships(VD);
|
||||
}
|
||||
|
||||
// MARK: - Relationships (Edges)
|
||||
|
||||
void SymbolGraph::recordEdge(const ValueDecl *Source,
|
||||
const ValueDecl *Target,
|
||||
@@ -237,7 +261,36 @@ void SymbolGraph::serialize(llvm::json::OStream &OS) {
|
||||
OS.attributeObject("module", [&](){
|
||||
OS.attribute("name", M.getNameStr());
|
||||
AttributeRAII Platform("platform", OS);
|
||||
|
||||
auto *MainFile = M.getFiles().front();
|
||||
switch (MainFile->getKind()) {
|
||||
case FileUnitKind::Builtin:
|
||||
llvm_unreachable("Unexpected module kind: Builtin");
|
||||
case FileUnitKind::DWARFModule:
|
||||
llvm_unreachable("Unexpected module kind: DWARFModule");
|
||||
case FileUnitKind::Source:
|
||||
llvm_unreachable("Unexpected module kind: Source");
|
||||
break;
|
||||
case FileUnitKind::SerializedAST: {
|
||||
auto SerializedAST = cast<SerializedASTFile>(MainFile);
|
||||
auto Target = llvm::Triple(SerializedAST->getTargetTriple());
|
||||
symbolgraphgen::serialize(Target, OS);
|
||||
break;
|
||||
}
|
||||
case FileUnitKind::ClangModule: {
|
||||
auto ClangModule = cast<ClangModuleUnit>(MainFile);
|
||||
if (const auto *Overlay = ClangModule->getOverlayModule()) {
|
||||
auto &OverlayMainFile =
|
||||
Overlay->getMainFile(FileUnitKind::SerializedAST);
|
||||
auto SerializedAST = cast<SerializedASTFile>(OverlayMainFile);
|
||||
auto Target = llvm::Triple(SerializedAST.getTargetTriple());
|
||||
symbolgraphgen::serialize(Target, OS);
|
||||
} else {
|
||||
symbolgraphgen::serialize(Target, OS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (ModuleVersion) {
|
||||
|
||||
@@ -31,6 +31,11 @@ struct SymbolGraph {
|
||||
*/
|
||||
ModuleDecl &M;
|
||||
|
||||
/**
|
||||
The module whose types were extended in `M`.
|
||||
*/
|
||||
Optional<ModuleDecl *> ExtendedModule;
|
||||
|
||||
/**
|
||||
The module's target triple.
|
||||
*/
|
||||
@@ -60,7 +65,9 @@ struct SymbolGraph {
|
||||
/// A cache of USRs for declarations.
|
||||
llvm::DenseMap<const ValueDecl *, StringRef> USRCache;
|
||||
|
||||
SymbolGraph(ModuleDecl &M, llvm::Triple Target,
|
||||
SymbolGraph(ModuleDecl &M,
|
||||
Optional<ModuleDecl *> ExtendedModule,
|
||||
llvm::Triple Target,
|
||||
markup::MarkupContext &Ctx,
|
||||
Optional<llvm::VersionTuple> ModuleVersion = None);
|
||||
|
||||
@@ -76,6 +83,13 @@ struct SymbolGraph {
|
||||
/// Get the base print options for declaration fragments.
|
||||
PrintOptions getDeclarationFragmentsPrintOptions() const;
|
||||
|
||||
// MARK: - Symbols (Nodes)
|
||||
|
||||
/**
|
||||
Record a symbol as a node in the graph.
|
||||
*/
|
||||
void recordNode(const ValueDecl *VD);
|
||||
|
||||
// MARK: - Relationships (Edges)
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "swift/AST/Decl.h"
|
||||
#include "swift/AST/Module.h"
|
||||
#include "swift/Serialization/SerializedModuleLoader.h"
|
||||
#include "swift/SymbolGraphGen/SymbolGraphGen.h"
|
||||
|
||||
#include "SymbolGraphASTWalker.h"
|
||||
@@ -24,7 +25,7 @@ SymbolGraphASTWalker::SymbolGraphASTWalker(ModuleDecl &M,
|
||||
const SymbolGraphOptions &Options)
|
||||
: Options(Options),
|
||||
M(M),
|
||||
Graph(M, Options.Target, Ctx) {}
|
||||
Graph(M, None, Options.Target, Ctx) {}
|
||||
|
||||
/// Returns `true` if the symbol should be included as a node in the graph.
|
||||
bool SymbolGraphASTWalker::shouldIncludeNode(const Decl *D) const {
|
||||
@@ -86,6 +87,21 @@ bool SymbolGraphASTWalker::shouldIncludeNode(const Decl *D) const {
|
||||
return ShouldInclude;
|
||||
}
|
||||
|
||||
/// Get a "sub" symbol graph for the parent module of a type that the main module `M` is extending.
|
||||
SymbolGraph &SymbolGraphASTWalker::getExtendedModuleSymbolGraph(ModuleDecl *M) {
|
||||
auto Found = ExtendedModuleGraphs.find(M);
|
||||
if (Found != ExtendedModuleGraphs.end()) {
|
||||
return *Found->getSecond();
|
||||
}
|
||||
auto *Memory = Ctx.allocate(sizeof(SymbolGraph), alignof(SymbolGraph));
|
||||
auto *SG = new (Memory) SymbolGraph(Graph.M,
|
||||
Optional<ModuleDecl *>(M),
|
||||
Options.Target,
|
||||
Ctx);
|
||||
ExtendedModuleGraphs.insert({M, SG});
|
||||
return *SG;
|
||||
}
|
||||
|
||||
bool SymbolGraphASTWalker::walkToDeclPre(Decl *D, CharSourceRange Range) {
|
||||
|
||||
switch (D->getKind()) {
|
||||
@@ -111,17 +127,23 @@ bool SymbolGraphASTWalker::walkToDeclPre(Decl *D, CharSourceRange Range) {
|
||||
}
|
||||
|
||||
auto *VD = cast<ValueDecl>(D);
|
||||
Graph.Nodes.insert(VD);
|
||||
|
||||
// Record all of the possible relationships (edges) originating
|
||||
// with this declaration.
|
||||
Graph.recordMemberRelationship(VD);
|
||||
Graph.recordConformanceRelationships(VD);
|
||||
Graph.recordInheritanceRelationships(VD);
|
||||
Graph.recordDefaultImplementationRelationships(VD);
|
||||
Graph.recordOverrideRelationship(VD);
|
||||
Graph.recordRequirementRelationships(VD);
|
||||
Graph.recordOptionalRequirementRelationships(VD);
|
||||
// If this symbol extends a type from another module, record it in that
|
||||
// module's symbol graph, which will be emitted separately.
|
||||
if (const auto *Extension
|
||||
= dyn_cast_or_null<ExtensionDecl>(VD->getInnermostDeclContext())) {
|
||||
if (const auto *ExtendedNominal = Extension->getExtendedNominal()) {
|
||||
auto ExtendedModule = ExtendedNominal->getModuleContext();
|
||||
if (ExtendedModule != &M) {
|
||||
auto &SG = getExtendedModuleSymbolGraph(ExtendedModule);
|
||||
SG.recordNode(VD);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, record this in the main module `M`'s symbol graph.
|
||||
Graph.recordNode(VD);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#ifndef SWIFT_SYMBOLGRAPHGEN_SYMBOLGRAPHASTWALKER_H
|
||||
#define SWIFT_SYMBOLGRAPHGEN_SYMBOLGRAPHASTWALKER_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "swift/AST/Module.h"
|
||||
#include "swift/Basic/LLVM.h"
|
||||
#include "swift/IDE/SourceEntityWalker.h"
|
||||
#include "swift/Markup/Markup.h"
|
||||
@@ -48,16 +50,24 @@ struct SymbolGraphASTWalker : public SourceEntityWalker {
|
||||
/// The symbol graph for a module.
|
||||
SymbolGraph Graph;
|
||||
|
||||
// MARK: -
|
||||
/// A map of modules whose types were extended by the main module of interest `M`.
|
||||
llvm::DenseMap<ModuleDecl *, SymbolGraph *> ExtendedModuleGraphs;
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
SymbolGraphASTWalker(ModuleDecl &M, const SymbolGraphOptions &Options);
|
||||
virtual ~SymbolGraphASTWalker() {}
|
||||
|
||||
// MARK: -
|
||||
// MARK: - Utilities
|
||||
|
||||
/// Returns `true` if the symbol should be included as a node in the graph.
|
||||
bool shouldIncludeNode(const Decl *D) const;
|
||||
|
||||
/// Get a "sub" symbol graph for the parent module of a type that the main module `M` is extending.
|
||||
SymbolGraph &getExtendedModuleSymbolGraph(ModuleDecl *M);
|
||||
|
||||
// MARK: - SourceEntityWalker
|
||||
|
||||
virtual bool walkToDeclPre(Decl *D, CharSourceRange Range);
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,35 @@
|
||||
using namespace swift;
|
||||
using namespace symbolgraphgen;
|
||||
|
||||
namespace {
|
||||
int serializeSymbolGraph(SymbolGraph &SG,
|
||||
const SymbolGraphOptions &Options) {
|
||||
SmallString<256> FileName(SG.M.getNameStr());
|
||||
if (SG.ExtendedModule.hasValue()) {
|
||||
FileName.push_back('@');
|
||||
FileName.append(SG.ExtendedModule.getValue()->getNameStr());
|
||||
}
|
||||
FileName.append(".symbols.json");
|
||||
|
||||
SmallString<1024> OutputPath(Options.OutputDir);
|
||||
llvm::sys::path::append(OutputPath, FileName);
|
||||
|
||||
std::error_code Error;
|
||||
llvm::raw_fd_ostream OS(OutputPath, Error, llvm::sys::fs::FA_Write);
|
||||
if (Error) {
|
||||
llvm::errs() << "Couldn't open output file '" << OutputPath
|
||||
<< " for writing: "
|
||||
<< Error.message() << "\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
llvm::json::OStream J(OS, Options.PrettyPrint ? 2 : 0);
|
||||
SG.serialize(J);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
// MARK: - Main Entry Point
|
||||
|
||||
/// Emit a symbol graph JSON file for a `ModuleDecl`.
|
||||
@@ -41,16 +70,13 @@ symbolgraphgen::emitSymbolGraphForModule(ModuleDecl *M,
|
||||
<< "Found " << Walker.Graph.Nodes.size() << " symbols and "
|
||||
<< Walker.Graph.Edges.size() << " relationships.\n";
|
||||
|
||||
std::error_code Error;
|
||||
llvm::raw_fd_ostream OS(Options.OutputPath, Error, llvm::sys::fs::FA_Write);
|
||||
if (Error) {
|
||||
llvm::errs() << "Couldn't open output file for writing: "
|
||||
<< Error.message() << "\n";
|
||||
return EXIT_FAILURE;
|
||||
int Success = EXIT_SUCCESS;
|
||||
|
||||
Success |= serializeSymbolGraph(Walker.Graph, Options);
|
||||
|
||||
for (auto Pair : Walker.ExtendedModuleGraphs) {
|
||||
Success |= serializeSymbolGraph(*Pair.getSecond(), Options);
|
||||
}
|
||||
|
||||
llvm::json::OStream J(OS, Options.PrettyPrint ? 2 : 0);
|
||||
Walker.Graph.serialize(J);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
return Success;
|
||||
}
|
||||
|
||||
20
test/SymbolGraph/Module/Extension.swift
Normal file
20
test/SymbolGraph/Module/Extension.swift
Normal file
@@ -0,0 +1,20 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name Extension -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name Extension -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/Extension@Swift.symbols.json
|
||||
|
||||
public extension String {
|
||||
/// Return something.
|
||||
var something: String {
|
||||
return "something"
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: module
|
||||
// CHECK-NEXT: "name": "Extension"
|
||||
|
||||
// CHECK: "precise": "s:SS9ExtensionE9somethingSSvp"
|
||||
|
||||
// CHECK: "kind": "memberOf"
|
||||
// CHECK-NEXT: "source": "s:SS9ExtensionE9somethingSSvp"
|
||||
// CHECK-NEXT: "target": "s:SS"
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name SymbolGraphModule -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name SymbolGraphModule -I %t -pretty-print -o %t/SymbolGraphModule.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name SymbolGraphModule -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/SymbolGraphModule.symbols.json
|
||||
|
||||
public struct S {
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name ConformsTo -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name ConformsTo -I %t -pretty-print -o %t/ConformsTo.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name ConformsTo -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/ConformsTo.symbols.json
|
||||
|
||||
public protocol P {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name DefaultImplementationOf -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name DefaultImplementationOf -I %t -pretty-print -o %t/DefaultImplementationOf.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name DefaultImplementationOf -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/DefaultImplementationOf.symbols.json
|
||||
|
||||
public protocol P {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name InheritsFrom -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name InheritsFrom -I %t -pretty-print -o %t/InheritsFrom.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name InheritsFrom -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/InheritsFrom.symbols.json
|
||||
|
||||
public class Base {}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name MemberOf -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name MemberOf -I %t -pretty-print -o %t/MemberOf.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name MemberOf -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/MemberOf.symbols.json
|
||||
|
||||
public struct S {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name Overrides -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name Overrides -I %t -pretty-print -o %t/Overrides.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name Overrides -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/Overrides.symbols.json
|
||||
|
||||
public class Base {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name ConformsTo -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name ConformsTo -I %t -pretty-print -o %t/ConformsTo.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name ConformsTo -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/ConformsTo.symbols.json
|
||||
|
||||
public protocol P {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name TargetFallback -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name TargetFallback -I %t -pretty-print -o %t/TargetFallback.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name TargetFallback -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/TargetFallback.symbols.json
|
||||
|
||||
public struct S: CustomStringConvertible {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name IncludeInternal -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name IncludeInternal -I %t -pretty-print -o %t/IncludeInternal.symbols.json -minimum-access-level internal
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name IncludeInternal -I %t -pretty-print -output-dir %t -minimum-access-level internal
|
||||
// RUN: %FileCheck %s --input-file %t/IncludeInternal.symbols.json
|
||||
|
||||
public struct ShouldAppear {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name PublicDefault -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name PublicDefault -I %t -pretty-print -o %t/PublicDefault.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name PublicDefault -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/PublicDefault.symbols.json
|
||||
|
||||
public struct ShouldAppear {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name AccessLevels -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name AccessLevels -I %t -pretty-print -o %t/AccessLevels.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name AccessLevels -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/AccessLevels.symbols.json
|
||||
|
||||
// CHECK: "accessLevel": "public"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name DocComment -emit-module-path %t/DocComment.swiftmodule
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name DocComment -I %t -pretty-print -o %t/DocComment.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name DocComment -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/DocComment.symbols.json
|
||||
|
||||
// CHECK: "text": "Single line."
|
||||
|
||||
9
test/SymbolGraph/Symbols/Identifier.swift
Normal file
9
test/SymbolGraph/Symbols/Identifier.swift
Normal file
@@ -0,0 +1,9 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name Identifier -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name Identifier -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/Identifier.symbols.json
|
||||
|
||||
public struct MyStruct {}
|
||||
|
||||
// CHECK: "precise": "s:10Identifier8MyStructV",
|
||||
// CHECK-NEXT: "interfaceLanguage": "swift"
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name Kinds -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name Kinds -I %t -pretty-print -o %t/Kinds.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name Kinds -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/Kinds.symbols.json
|
||||
|
||||
// CHECK: "identifier": "swift.class"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name Availability -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name Availability -I %t -pretty-print -o %t/Availability.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name Availability -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/Availability.symbols.json
|
||||
|
||||
@available(macOS, introduced: 10.9, deprecated: 10.10, obsoleted: 10.11, message: "Everyone makes mistakes", renamed: "S2")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name UnconditionallyDeprecated -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name UnconditionallyDeprecated -I %t -pretty-print -o %t/UnconditionallyDeprecated.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name UnconditionallyDeprecated -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/UnconditionallyDeprecated.symbols.json
|
||||
|
||||
@available(*, deprecated)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name UnconditionallyUnavailable -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name UnconditionallyUnavailable -I %t -pretty-print -o %t/UnconditionallyUnavailable.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name UnconditionallyUnavailable -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/UnconditionallyUnavailable.symbols.json
|
||||
|
||||
@available(*, unavailable)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name DeclarationFragments -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name DeclarationFragments -I %t -pretty-print -o %t/DeclarationFragments.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name DeclarationFragments -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/DeclarationFragments.symbols.json
|
||||
|
||||
public func foo<S>(f: @escaping () -> (), x: Int = 2, s: S) {}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name FunctionSignature -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name FunctionSignature -I %t -pretty-print -o %t/FunctionSignature.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name FunctionSignature -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/FunctionSignature.symbols.json
|
||||
|
||||
public func foo(_ noext: Int, ext int: Int) -> String {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name Names -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name Names -I %t -pretty-print -o %t/Names.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name Names -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/Names.symbols.json
|
||||
|
||||
public struct MyStruct {}
|
||||
|
||||
19
test/SymbolGraph/Symbols/PathComponents.swift
Normal file
19
test/SymbolGraph/Symbols/PathComponents.swift
Normal file
@@ -0,0 +1,19 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name PathComponents -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name PathComponents -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/PathComponents.symbols.json
|
||||
|
||||
public struct Outer {
|
||||
public struct Inner {
|
||||
public var x = 1
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: "precise": "s:14PathComponents5OuterV5InnerV1xSivp"
|
||||
// CHECK-NEXT: "interfaceLanguage": "swift"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: "pathComponents": [
|
||||
// CHECK-NEXT: "Outer"
|
||||
// CHECK-NEXT: "Inner"
|
||||
// CHECK-NEXT: "x"
|
||||
// CHECK-NEXT: ]
|
||||
@@ -1,7 +1,7 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name SkipsPublicUnderscore -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name SkipsPublicUnderscore -I %t -pretty-print -o %t/SymbolGraphModule.symbols.json
|
||||
// RUN: %FileCheck %s --input-file %t/SymbolGraphModule.symbols.json
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name SkipsPublicUnderscore -I %t -pretty-print -output-dir %t
|
||||
// RUN: %FileCheck %s --input-file %t/SkipsPublicUnderscore.symbols.json
|
||||
|
||||
public struct _ShouldntAppear {
|
||||
public var shouldntAppear: Int
|
||||
|
||||
@@ -71,7 +71,7 @@ Xcc("Xcc", llvm::cl::desc("Pass the following command-line flag to Clang"),
|
||||
llvm::cl::cat(Category));
|
||||
|
||||
static llvm::cl::opt<std::string>
|
||||
OutputPath("o", llvm::cl::desc("Symbol Graph JSON Output Path (Required)"), llvm::cl::cat(Category));
|
||||
OutputDir("output-dir", llvm::cl::desc("Symbol Graph JSON Output Directory (Required)"), llvm::cl::cat(Category));
|
||||
} // end namespace options
|
||||
|
||||
static bool argumentsAreValid() {
|
||||
@@ -86,8 +86,8 @@ static bool argumentsAreValid() {
|
||||
Valid = false;
|
||||
}
|
||||
|
||||
if (options::OutputPath.empty()) {
|
||||
llvm::errs() << "Required -o argument is missing\n";
|
||||
if (options::OutputDir.empty()) {
|
||||
llvm::errs() << "Required -output-dir argument is missing\n";
|
||||
Valid = false;
|
||||
}
|
||||
|
||||
@@ -116,6 +116,12 @@ int swift_symbolgraph_extract_main(ArrayRef<const char *> Args, const char *Argv
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!llvm::sys::fs::is_directory(options::OutputDir)) {
|
||||
llvm::errs() << "-output-dir argument '" << options::OutputDir
|
||||
<< " does not exist or is not a directory\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
CompilerInvocation Invocation;
|
||||
|
||||
Invocation.setMainExecutablePath(
|
||||
@@ -161,7 +167,7 @@ int swift_symbolgraph_extract_main(ArrayRef<const char *> Args, const char *Argv
|
||||
}
|
||||
|
||||
symbolgraphgen::SymbolGraphOptions Options {
|
||||
options::OutputPath,
|
||||
options::OutputDir,
|
||||
llvm::Triple(options::Target),
|
||||
options::PrettyPrint,
|
||||
AccessLevel::Public,
|
||||
|
||||
Reference in New Issue
Block a user