mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
These links will never resolve because the symbols are never emitted in the first place. rdar://64178490
196 lines
5.4 KiB
C++
196 lines
5.4 KiB
C++
//===--- DeclarationFragmentPrinter.cpp - Declaration Fragment Printer ----===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "swift/AST/USRGeneration.h"
|
|
#include "swift/Syntax/TokenKinds.h"
|
|
#include "DeclarationFragmentPrinter.h"
|
|
#include "SymbolGraphASTWalker.h"
|
|
|
|
using namespace swift;
|
|
using namespace symbolgraphgen;
|
|
|
|
void DeclarationFragmentPrinter::openFragment(FragmentKind Kind) {
|
|
assert(Kind != FragmentKind::None);
|
|
if (this->Kind != Kind) {
|
|
closeFragment();
|
|
this->Kind = Kind,
|
|
Spelling.clear();
|
|
USR.clear();
|
|
}
|
|
}
|
|
|
|
StringRef
|
|
DeclarationFragmentPrinter::getKindSpelling(FragmentKind Kind) const {
|
|
switch (Kind) {
|
|
case FragmentKind::Keyword:
|
|
return "keyword";
|
|
case FragmentKind::Attribute:
|
|
return "attribute";
|
|
case FragmentKind::NumberLiteral:
|
|
return "number";
|
|
case FragmentKind::StringLiteral:
|
|
return "string";
|
|
case FragmentKind::Identifier:
|
|
return "identifier";
|
|
case FragmentKind::TypeIdentifier:
|
|
return "typeIdentifier";
|
|
case FragmentKind::GenericParameter:
|
|
return "genericParameter";
|
|
case FragmentKind::InternalParam:
|
|
return "internalParam";
|
|
case FragmentKind::ExternalParam:
|
|
return "externalParam";
|
|
case FragmentKind::Text:
|
|
return "text";
|
|
case FragmentKind::None:
|
|
llvm_unreachable("Fragment kind of 'None' has no spelling");
|
|
}
|
|
llvm_unreachable("invalid fragment kind");
|
|
}
|
|
|
|
void DeclarationFragmentPrinter::closeFragment() {
|
|
if (Kind == FragmentKind::None) {
|
|
return;
|
|
}
|
|
|
|
++NumFragments;
|
|
|
|
if (!Spelling.empty()) {
|
|
OS.object([&](){
|
|
OS.attribute("kind", getKindSpelling(Kind));
|
|
OS.attribute("spelling", Spelling.str());
|
|
if (!USR.empty()) {
|
|
OS.attribute("preciseIdentifier", USR.str());
|
|
}
|
|
});
|
|
}
|
|
|
|
Spelling.clear();
|
|
USR.clear();
|
|
Kind = FragmentKind::None;
|
|
}
|
|
|
|
void DeclarationFragmentPrinter::printDeclLoc(const Decl *D) {
|
|
switch (D->getKind()) {
|
|
case DeclKind::Constructor:
|
|
case DeclKind::Destructor:
|
|
case DeclKind::Subscript:
|
|
openFragment(FragmentKind::Keyword);
|
|
break;
|
|
default:
|
|
openFragment(FragmentKind::Identifier);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
DeclarationFragmentPrinter::printNamePre(PrintNameContext Context) {
|
|
switch (Context) {
|
|
case PrintNameContext::Keyword:
|
|
openFragment(FragmentKind::Keyword);
|
|
break;
|
|
case PrintNameContext::GenericParameter:
|
|
openFragment(FragmentKind::GenericParameter);
|
|
break;
|
|
case PrintNameContext::Attribute:
|
|
openFragment(FragmentKind::Attribute);
|
|
break;
|
|
case PrintNameContext::ClassDynamicSelf:
|
|
case PrintNameContext::FunctionParameterExternal:
|
|
openFragment(FragmentKind::ExternalParam);
|
|
break;
|
|
case PrintNameContext::FunctionParameterLocal:
|
|
openFragment(FragmentKind::InternalParam);
|
|
break;
|
|
case PrintNameContext::TupleElement:
|
|
case PrintNameContext::TypeMember:
|
|
case PrintNameContext::Normal:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void DeclarationFragmentPrinter::printStructurePre(PrintStructureKind Kind,
|
|
const Decl *D) {
|
|
switch (Kind) {
|
|
case PrintStructureKind::NumberLiteral:
|
|
openFragment(FragmentKind::NumberLiteral);
|
|
break;
|
|
case PrintStructureKind::StringLiteral:
|
|
openFragment(FragmentKind::StringLiteral);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void DeclarationFragmentPrinter::printTypeRef(Type T, const TypeDecl *RefTo,
|
|
Identifier Name,
|
|
PrintNameContext NameContext) {
|
|
openFragment(FragmentKind::TypeIdentifier);
|
|
printText(Name.str());
|
|
USR.clear();
|
|
|
|
auto ShouldLink = Name.str() != "Self";
|
|
if (const auto *TD = T->getAnyNominal()) {
|
|
if (SG->isImplicitlyPrivate(TD)) {
|
|
ShouldLink = false;
|
|
}
|
|
}
|
|
|
|
if (ShouldLink) {
|
|
llvm::raw_svector_ostream OS(USR);
|
|
ide::printDeclUSR(RefTo, OS);
|
|
}
|
|
closeFragment();
|
|
}
|
|
|
|
void DeclarationFragmentPrinter::printText(StringRef Text) {
|
|
if (Kind == FragmentKind::None) {
|
|
openFragment(FragmentKind::Text);
|
|
}
|
|
Spelling.append(Text);
|
|
}
|
|
|
|
void DeclarationFragmentPrinter::printAbridgedType(const GenericTypeDecl *TD,
|
|
bool PrintKeyword) {
|
|
if (PrintKeyword) {
|
|
openFragment(DeclarationFragmentPrinter::FragmentKind::Keyword);
|
|
switch (TD->getKind()) {
|
|
case DeclKind::Struct:
|
|
printText(getTokenText(tok::kw_struct));
|
|
break;
|
|
case DeclKind::Enum:
|
|
printText(getTokenText(tok::kw_enum));
|
|
break;
|
|
case DeclKind::Protocol:
|
|
printText(getTokenText(tok::kw_protocol));
|
|
break;
|
|
case DeclKind::Class:
|
|
printText(getTokenText(tok::kw_class));
|
|
break;
|
|
case DeclKind::TypeAlias:
|
|
printText(getTokenText(tok::kw_typealias));
|
|
break;
|
|
case DeclKind::OpaqueType:
|
|
llvm_unreachable("OpaqueType should not be in symbol graphs!");
|
|
default:
|
|
llvm_unreachable("GenericTypeDecl kind not handled in DeclarationFragmentPrinter!");
|
|
}
|
|
|
|
openFragment(DeclarationFragmentPrinter::FragmentKind::Text);
|
|
printText(" ");
|
|
}
|
|
|
|
openFragment(DeclarationFragmentPrinter::FragmentKind::Identifier);
|
|
printText(TD->getNameStr());
|
|
}
|