Skip to content

Commit f34c970

Browse files
authored
Merge pull request #28678 from bitjammer/acgarland/symbol-graph
Symbol graph support
2 parents 0f96a5e + 7a3a0a9 commit f34c970

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+2574
-43
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,8 @@ class alignas(1 << DeclAlignInBits) Decl {
875875
LLVM_READONLY
876876
const GenericContext *getAsGenericContext() const;
877877

878+
bool hasUnderscoredNaming() const;
879+
878880
bool isPrivateStdlibDecl(bool treatNonBuiltinProtocolsAsPublic = true) const;
879881

880882
AvailabilityContext getAvailabilityForLinkage() const;

include/swift/AST/PrintOptions.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,13 @@ struct PrintOptions {
380380
ArgAndParamPrintingMode ArgAndParamPrinting =
381381
ArgAndParamPrintingMode::MatchSource;
382382

383+
/// Whether to print the default argument value string
384+
/// representation.
385+
bool PrintDefaultArgumentValue = true;
386+
387+
/// Whether to print "_" placeholders for empty arguments.
388+
bool PrintEmptyArgumentNames = true;
389+
383390
/// Whether to print documentation comments attached to declarations.
384391
/// Note that this may print documentation comments from related declarations
385392
/// (e.g. the overridden method in the superclass) if such comment is found.

include/swift/Driver/Driver.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ class Driver {
158158
Interactive, // swift
159159
Batch, // swiftc
160160
AutolinkExtract, // swift-autolink-extract
161-
SwiftIndent // swift-indent
161+
SwiftIndent, // swift-indent
162+
SymbolGraph // swift-symbolgraph
162163
};
163164

164165
class InputInfoMap;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//===--- swift_indent_main.cpp - Swift code formatting tool ---------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "llvm/ADT/Triple.h"
14+
#include "swift/AST/AttrKind.h"
15+
16+
namespace swift {
17+
18+
class ModuleDecl;
19+
20+
namespace symbolgraphgen {
21+
22+
struct SymbolGraphOptions {
23+
/// The path to output the symbol graph JSON.
24+
StringRef OutputPath;
25+
26+
/// The target of the module.
27+
llvm::Triple Target;
28+
29+
/// Pretty-print the JSON with newlines and indentation.
30+
bool PrettyPrint;
31+
32+
/// The minimum access level that symbols must have in order to be
33+
/// included in the graph.
34+
AccessLevel MinimumAccessLevel;
35+
};
36+
37+
/// Emit a Symbol Graph JSON file for a module.
38+
int emitSymbolGraphForModule(ModuleDecl *M, const SymbolGraphOptions &Options);
39+
40+
} // end namespace symbolgraphgen
41+
} // end namespace swift

lib/AST/ASTPrinter.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2632,6 +2632,9 @@ void PrintAST::printOneParameter(const ParamDecl *param,
26322632
// Else, print the argument only.
26332633
LLVM_FALLTHROUGH;
26342634
case PrintOptions::ArgAndParamPrintingMode::ArgumentOnly:
2635+
if (ArgName.empty() && !Options.PrintEmptyArgumentNames) {
2636+
return;
2637+
}
26352638
Printer.printName(ArgName, PrintNameContext::FunctionParameterExternal);
26362639

26372640
if (!ArgNameIsAPIByDefault && !ArgName.empty())
@@ -2686,7 +2689,7 @@ void PrintAST::printOneParameter(const ParamDecl *param,
26862689
if (param->isVariadic())
26872690
Printer << "...";
26882691

2689-
if (param->isDefaultArgument()) {
2692+
if (param->isDefaultArgument() && Options.PrintDefaultArgumentValue) {
26902693
SmallString<128> scratch;
26912694
auto defaultArgStr = param->getDefaultValueStringRepresentation(scratch);
26922695

lib/AST/Decl.cpp

Lines changed: 51 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,56 @@ bool ParameterList::hasInternalParameter(StringRef Prefix) const {
697697
return false;
698698
}
699699

700+
bool Decl::hasUnderscoredNaming() const {
701+
const Decl *D = this;
702+
if (const auto AFD = dyn_cast<AbstractFunctionDecl>(D)) {
703+
// If it's a function with a parameter with leading underscore, it's a
704+
// private function.
705+
if (AFD->getParameters()->hasInternalParameter("_")) {
706+
return true;
707+
}
708+
}
709+
710+
if (const auto SubscriptD = dyn_cast<SubscriptDecl>(D)) {
711+
if (SubscriptD->getIndices()->hasInternalParameter("_")) {
712+
return true;
713+
}
714+
}
715+
716+
if (const auto PD = dyn_cast<ProtocolDecl>(D)) {
717+
if (PD->getAttrs().hasAttribute<ShowInInterfaceAttr>()) {
718+
return false;
719+
}
720+
StringRef NameStr = PD->getNameStr();
721+
if (NameStr.startswith("_Builtin")) {
722+
return true;
723+
}
724+
if (NameStr.startswith("_ExpressibleBy")) {
725+
return true;
726+
}
727+
}
728+
729+
if (const auto ImportD = dyn_cast<ImportDecl>(D)) {
730+
if (const auto *Mod = ImportD->getModule()) {
731+
if (Mod->isSwiftShimsModule()) {
732+
return true;
733+
}
734+
}
735+
}
736+
737+
const auto VD = dyn_cast<ValueDecl>(D);
738+
if (!VD || !VD->hasName()) {
739+
return false;
740+
}
741+
742+
if (!VD->getBaseName().isSpecial() &&
743+
VD->getBaseName().getIdentifier().str().startswith("_")) {
744+
return true;
745+
}
746+
747+
return false;
748+
}
749+
700750
bool Decl::isPrivateStdlibDecl(bool treatNonBuiltinProtocolsAsPublic) const {
701751
const Decl *D = this;
702752
if (auto ExtD = dyn_cast<ExtensionDecl>(D)) {
@@ -718,47 +768,12 @@ bool Decl::isPrivateStdlibDecl(bool treatNonBuiltinProtocolsAsPublic) const {
718768
FU->getKind() != FileUnitKind::SerializedAST)
719769
return false;
720770

721-
if (auto AFD = dyn_cast<AbstractFunctionDecl>(D)) {
722-
// If it's a function with a parameter with leading underscore, it's a
723-
// private function.
724-
if (AFD->getParameters()->hasInternalParameter("_"))
725-
return true;
726-
}
727-
728-
if (auto SubscriptD = dyn_cast<SubscriptDecl>(D)) {
729-
if (SubscriptD->getIndices()->hasInternalParameter("_"))
730-
return true;
731-
}
732-
733771
if (auto PD = dyn_cast<ProtocolDecl>(D)) {
734-
if (PD->getAttrs().hasAttribute<ShowInInterfaceAttr>())
735-
return false;
736-
StringRef NameStr = PD->getNameStr();
737-
if (NameStr.startswith("_Builtin"))
738-
return true;
739-
if (NameStr.startswith("_ExpressibleBy"))
740-
return true;
741772
if (treatNonBuiltinProtocolsAsPublic)
742773
return false;
743774
}
744775

745-
if (auto ImportD = dyn_cast<ImportDecl>(D)) {
746-
if (auto *Mod = ImportD->getModule()) {
747-
if (Mod->isSwiftShimsModule())
748-
return true;
749-
}
750-
}
751-
752-
auto VD = dyn_cast<ValueDecl>(D);
753-
if (!VD || !VD->hasName())
754-
return false;
755-
756-
// If the name has leading underscore then it's a private symbol.
757-
if (!VD->getBaseName().isSpecial() &&
758-
VD->getBaseName().getIdentifier().str().startswith("_"))
759-
return true;
760-
761-
return false;
776+
return hasUnderscoredNaming();
762777
}
763778

764779
AvailabilityContext Decl::getAvailabilityForLinkage() const {

lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ add_subdirectory(SwiftRemoteMirror)
4242
add_subdirectory(SIL)
4343
add_subdirectory(SILGen)
4444
add_subdirectory(SILOptimizer)
45+
add_subdirectory(SymbolGraphGen)
4546
add_subdirectory(Syntax)
4647
add_subdirectory(SyntaxParse)
4748
add_subdirectory(TBDGen)

lib/Driver/Driver.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ void Driver::parseDriverKind(ArrayRef<const char *> Args) {
9898
.Case("swiftc", DriverKind::Batch)
9999
.Case("swift-autolink-extract", DriverKind::AutolinkExtract)
100100
.Case("swift-indent", DriverKind::SwiftIndent)
101+
.Case("swift-symbolgraph-extract", DriverKind::SymbolGraph)
101102
.Default(None);
102103

103104
if (Kind.hasValue())
@@ -3252,6 +3253,7 @@ void Driver::printHelp(bool ShowHidden) const {
32523253
case DriverKind::Batch:
32533254
case DriverKind::AutolinkExtract:
32543255
case DriverKind::SwiftIndent:
3256+
case DriverKind::SymbolGraph:
32553257
ExcludedFlagsBitmask |= options::NoBatchOption;
32563258
break;
32573259
}

lib/Markup/LineList.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,6 @@ LineList MarkupContext::getLineList(swift::RawComment RC) {
115115
// Determine if we have leading decorations in this block comment.
116116
bool HasASCIIArt = false;
117117
if (swift::startsWithNewline(Cleaned)) {
118-
Builder.addLine(Cleaned.substr(0, 0), { C.Range.getStart(),
119-
C.Range.getStart() });
120118
unsigned NewlineBytes = swift::measureNewline(Cleaned);
121119
Cleaned = Cleaned.drop_front(NewlineBytes);
122120
CleanedStartLoc = CleanedStartLoc.getAdvancedLocOrInvalid(NewlineBytes);

lib/SymbolGraphGen/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
add_swift_host_library(swiftSymbolGraphGen STATIC
2+
DeclarationFragmentPrinter.cpp
3+
Edge.cpp
4+
JSON.cpp
5+
Symbol.cpp
6+
SymbolGraph.cpp
7+
SymbolGraphGen.cpp
8+
SymbolGraphASTWalker.cpp)
9+
10+
target_link_libraries(swiftSymbolGraphGen
11+
swiftAST
12+
swiftFrontend
13+
swiftMarkup)
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
//===--- DeclarationFragmentPrinter.cpp - Declaration Fragment Printer ----===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "DeclarationFragmentPrinter.h"
14+
#include "SymbolGraphASTWalker.h"
15+
16+
using namespace swift;
17+
using namespace symbolgraphgen;
18+
19+
void DeclarationFragmentPrinter::openFragment(FragmentKind Kind) {
20+
assert(Kind != FragmentKind::None);
21+
if (this->Kind != Kind) {
22+
closeFragment();
23+
this->Kind = Kind,
24+
Spelling.clear();
25+
USR.clear();
26+
}
27+
}
28+
29+
StringRef
30+
DeclarationFragmentPrinter::getKindSpelling(FragmentKind Kind) const {
31+
switch (Kind) {
32+
case FragmentKind::Keyword:
33+
return "keyword";
34+
case FragmentKind::Attribute:
35+
return "attribute";
36+
case FragmentKind::NumberLiteral:
37+
return "number";
38+
case FragmentKind::StringLiteral:
39+
return "string";
40+
case FragmentKind::Identifier:
41+
return "identifier";
42+
case FragmentKind::TypeIdentifier:
43+
return "typeIdentifier";
44+
case FragmentKind::GenericParameter:
45+
return "genericParameter";
46+
case FragmentKind::Text:
47+
return "text";
48+
case FragmentKind::None:
49+
llvm_unreachable("Fragment kind of 'None' has no spelling");
50+
}
51+
}
52+
53+
void DeclarationFragmentPrinter::closeFragment() {
54+
if (Kind == FragmentKind::None) {
55+
return;
56+
}
57+
58+
if (!Spelling.empty()) {
59+
OS.object([&](){
60+
OS.attribute("kind", getKindSpelling(Kind));
61+
OS.attribute("spelling", Spelling.str());
62+
if (!USR.empty()) {
63+
OS.attribute("preciseIdentifier", USR.str());
64+
}
65+
});
66+
}
67+
68+
Spelling.clear();
69+
USR.clear();
70+
Kind = FragmentKind::None;
71+
}
72+
73+
void DeclarationFragmentPrinter::printDeclLoc(const Decl *D) {
74+
switch (D->getKind()) {
75+
case DeclKind::Constructor:
76+
case DeclKind::Destructor:
77+
case DeclKind::Subscript:
78+
openFragment(FragmentKind::Keyword);
79+
break;
80+
default:
81+
openFragment(FragmentKind::Identifier);
82+
break;
83+
}
84+
}
85+
86+
void
87+
DeclarationFragmentPrinter::printNamePre(PrintNameContext Context) {
88+
switch (Context) {
89+
case PrintNameContext::Keyword:
90+
openFragment(FragmentKind::Keyword);
91+
break;
92+
case PrintNameContext::GenericParameter:
93+
openFragment(FragmentKind::GenericParameter);
94+
break;
95+
case PrintNameContext::Attribute:
96+
openFragment(FragmentKind::Attribute);
97+
break;
98+
case PrintNameContext::ClassDynamicSelf:
99+
case PrintNameContext::FunctionParameterExternal:
100+
openFragment(FragmentKind::Identifier);
101+
break;
102+
case PrintNameContext::FunctionParameterLocal:
103+
openFragment(FragmentKind::Identifier);
104+
break;
105+
case PrintNameContext::TupleElement:
106+
case PrintNameContext::TypeMember:
107+
case PrintNameContext::Normal:
108+
break;
109+
}
110+
}
111+
112+
void DeclarationFragmentPrinter::printStructurePre(PrintStructureKind Kind,
113+
const Decl *D) {
114+
switch (Kind) {
115+
case PrintStructureKind::NumberLiteral:
116+
openFragment(FragmentKind::NumberLiteral);
117+
break;
118+
case PrintStructureKind::StringLiteral:
119+
openFragment(FragmentKind::StringLiteral);
120+
break;
121+
default:
122+
break;
123+
}
124+
}
125+
126+
void DeclarationFragmentPrinter::printTypeRef(Type T, const TypeDecl *RefTo,
127+
Identifier Name,
128+
PrintNameContext NameContext) {
129+
openFragment(FragmentKind::TypeIdentifier);
130+
printText(Name.str());
131+
USR = Walker.getUSR(RefTo);
132+
closeFragment();
133+
}
134+
135+
void DeclarationFragmentPrinter::printText(StringRef Text) {
136+
if (Kind == FragmentKind::None) {
137+
openFragment(FragmentKind::Text);
138+
}
139+
Spelling.append(Text);
140+
}

0 commit comments

Comments
 (0)