mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
For more fine grained annoations. For now, it's handled as the same as 'Keyword' name kind. Fix an issue where 'extension' wasn't marked as "keyword". Also, move 'static' priting out of 'SkipIntroducerKeywords' guard because 'static' is not an declaration introducer.
205 lines
5.6 KiB
C++
205 lines
5.6 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:
|
|
case PrintNameContext::IntroducerKeyword:
|
|
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 (T) {
|
|
if (const auto *TD = T->getAnyNominal()) {
|
|
if (SG->isImplicitlyPrivate(TD)) {
|
|
ShouldLink = false;
|
|
}
|
|
}
|
|
|
|
if (T->isTypeParameter()) {
|
|
ShouldLink = false;
|
|
}
|
|
}
|
|
|
|
if (ShouldLink) {
|
|
llvm::raw_svector_ostream OS(USR);
|
|
ide::printDeclUSR(RefTo, OS);
|
|
if (ReferencedDecls)
|
|
ReferencedDecls->insert(RefTo);
|
|
}
|
|
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());
|
|
}
|