Files
swift-mirror/lib/AST/SwiftNameTranslation.cpp
Jordan Rose 1c651973c3 Excise "Accessibility" from the compiler (2/3)
"Accessibility" has a different meaning for app developers, so we've
already deliberately excised it from our diagnostics in favor of terms
like "access control" and "access level". Do the same in the compiler
now that we aren't constantly pulling things into the release branch.

This commit changes the 'Accessibility' enum to be named 'AccessLevel'.
2017-08-28 11:34:44 -07:00

119 lines
4.3 KiB
C++

//===--- SwiftNameTranslation.cpp - Swift to ObjC Name Translation APIs ---===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file contains utilities for translating Swift names to ObjC.
//
//===----------------------------------------------------------------------===//
#include "swift/AST/SwiftNameTranslation.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include "swift/AST/LazyResolver.h"
#include "swift/Basic/StringExtras.h"
#include "clang/AST/DeclObjC.h"
#include "llvm/ADT/SmallString.h"
using namespace swift;
StringRef swift::objc_translation::
getNameForObjC(const ValueDecl *VD, CustomNamesOnly_t customNamesOnly) {
assert(isa<ClassDecl>(VD) || isa<ProtocolDecl>(VD) || isa<StructDecl>(VD) ||
isa<EnumDecl>(VD) || isa<EnumElementDecl>(VD) ||
isa<TypeAliasDecl>(VD));
if (auto objc = VD->getAttrs().getAttribute<ObjCAttr>()) {
if (auto name = objc->getName()) {
assert(name->getNumSelectorPieces() == 1);
return name->getSelectorPieces().front().str();
}
}
if (customNamesOnly)
return StringRef();
if (auto clangDecl = dyn_cast_or_null<clang::NamedDecl>(VD->getClangDecl())) {
if (const clang::IdentifierInfo *II = clangDecl->getIdentifier())
return II->getName();
if (auto *anonDecl = dyn_cast<clang::TagDecl>(clangDecl))
if (auto *anonTypedef = anonDecl->getTypedefNameForAnonDecl())
return anonTypedef->getIdentifier()->getName();
}
return VD->getBaseName().getIdentifier().str();
}
bool swift::objc_translation::
printSwiftEnumElemNameInObjC(const EnumElementDecl *EL, llvm::raw_ostream &OS,
Identifier PreferredName) {
StringRef ElemName = getNameForObjC(EL, CustomNamesOnly);
if (!ElemName.empty()) {
OS << ElemName;
return true;
}
OS << getNameForObjC(EL->getDeclContext()->getAsEnumOrEnumExtensionContext());
if (PreferredName.empty())
ElemName = EL->getName().str();
else
ElemName = PreferredName.str();
SmallString<64> Scratch;
OS << camel_case::toSentencecase(ElemName, Scratch);
return false;
}
std::pair<Identifier, ObjCSelector> swift::objc_translation::
getObjCNameForSwiftDecl(const ValueDecl *VD, DeclName PreferredName){
ASTContext &Ctx = VD->getASTContext();
LazyResolver *Resolver = Ctx.getLazyResolver();
if (auto *FD = dyn_cast<AbstractFunctionDecl>(VD)) {
return {Identifier(), FD->getObjCSelector(Resolver, PreferredName)};
} else if (auto *VAD = dyn_cast<VarDecl>(VD)) {
if (PreferredName)
return {PreferredName.getBaseIdentifier(), ObjCSelector()};
return {VAD->getObjCPropertyName(), ObjCSelector()};
} else if (auto *SD = dyn_cast<SubscriptDecl>(VD)) {
return getObjCNameForSwiftDecl(SD->getGetter(), PreferredName);
} else if (auto *EL = dyn_cast<EnumElementDecl>(VD)) {
SmallString<64> Buffer;
{
llvm::raw_svector_ostream OS(Buffer);
printSwiftEnumElemNameInObjC(EL, OS, PreferredName.getBaseIdentifier());
}
return {Ctx.getIdentifier(Buffer.str()), ObjCSelector()};
} else {
// @objc(ExplicitName) > PreferredName > Swift name.
StringRef Name = getNameForObjC(VD, CustomNamesOnly);
if (!Name.empty())
return {Ctx.getIdentifier(Name), ObjCSelector()};
if (!PreferredName.getBaseName().empty())
return {PreferredName.getBaseIdentifier(), ObjCSelector()};
return {Ctx.getIdentifier(getNameForObjC(VD)), ObjCSelector()};
}
}
bool swift::objc_translation::
isVisibleToObjC(const ValueDecl *VD, AccessLevel minRequiredAccess,
bool checkParent) {
if (!(VD->isObjC() || VD->getAttrs().hasAttribute<CDeclAttr>()))
return false;
if (VD->hasAccess() && VD->getFormalAccess() >= minRequiredAccess) {
return true;
} else if (checkParent) {
if (auto ctor = dyn_cast<ConstructorDecl>(VD)) {
// Check if we're overriding an initializer that is visible to obj-c
if (auto parent = ctor->getOverriddenDecl())
return isVisibleToObjC(parent, minRequiredAccess, false);
}
}
return false;
}