Skip to content

Commit

Permalink
Merge pull request swiftlang#19645 from pitiphong-p/objc-rename-attri…
Browse files Browse the repository at this point in the history
…bute-type-following

Improve the behavior of the custom @objc name in the available attribute when generates ObjC headers
  • Loading branch information
jrose-apple authored Dec 18, 2018
2 parents f28e440 + 08204ef commit 5e157b8
Show file tree
Hide file tree
Showing 2 changed files with 232 additions and 118 deletions.
144 changes: 92 additions & 52 deletions lib/PrintAsObjC/PrintAsObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ namespace {
using DelayedMemberSet = llvm::SmallSetVector<const ValueDecl *, 32>;

class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
private TypeVisitor<ObjCPrinter, void,
private TypeVisitor<ObjCPrinter, void,
Optional<OptionalTypeKind>>
{
friend ASTVisitor;
Expand Down Expand Up @@ -528,7 +528,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
return sel.getNumArgs() == 0 &&
sel.getSelectorPieces().front().str() == "init";
}

void printAbstractFunctionAsMethod(AbstractFunctionDecl *AFD,
bool isClassMethod,
bool isNSUIntegerSubscript = false) {
Expand All @@ -553,7 +553,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
auto resultTy = getForeignResultType(AFD, methodTy, errorConvention);

// Constructors and methods returning DynamicSelf return
// instancetype.
// instancetype.
if (isa<ConstructorDecl>(AFD) ||
(isa<FuncDecl>(AFD) && cast<FuncDecl>(AFD)->hasDynamicSelf())) {
if (errorConvention && errorConvention->stripsResultOptionality()) {
Expand Down Expand Up @@ -776,9 +776,8 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
};

/// Returns \c true if anything was printed.
bool printAvailability(
const Decl *D,
PrintLeadingSpace printLeadingSpace = PrintLeadingSpace::Yes) {
bool printAvailability(const Decl *D, PrintLeadingSpace printLeadingSpace =
PrintLeadingSpace::Yes) {
bool hasPrintedAnything = false;
auto maybePrintLeadingSpace = [&] {
if (printLeadingSpace == PrintLeadingSpace::Yes || hasPrintedAnything)
Expand All @@ -788,7 +787,8 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,

for (auto AvAttr : D->getAttrs().getAttributes<AvailableAttr>()) {
if (AvAttr->Platform == PlatformKind::none) {
if (AvAttr->PlatformAgnostic == PlatformAgnosticAvailabilityKind::Unavailable) {
if (AvAttr->PlatformAgnostic ==
PlatformAgnosticAvailabilityKind::Unavailable) {
// Availability for *
if (!AvAttr->Rename.empty() && isa<ValueDecl>(D)) {
// rename
Expand Down Expand Up @@ -833,11 +833,10 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
}

// Availability for a specific platform
if (!AvAttr->Introduced.hasValue()
&& !AvAttr->Deprecated.hasValue()
&& !AvAttr->Obsoleted.hasValue()
&& !AvAttr->isUnconditionallyDeprecated()
&& !AvAttr->isUnconditionallyUnavailable()) {
if (!AvAttr->Introduced.hasValue() && !AvAttr->Deprecated.hasValue() &&
!AvAttr->Obsoleted.hasValue() &&
!AvAttr->isUnconditionallyDeprecated() &&
!AvAttr->isUnconditionallyUnavailable()) {
continue;
}

Expand Down Expand Up @@ -912,43 +911,75 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
}
return hasPrintedAnything;
}

void printRenameForDecl(const AvailableAttr *AvAttr, const ValueDecl *D,
bool includeQuotes) {
assert(!AvAttr->Rename.empty());

auto renamedParsedDeclName = parseDeclName(AvAttr->Rename);
auto renamedDeclName = renamedParsedDeclName.formDeclName(D->getASTContext());


const ValueDecl *getRenameDecl(const ValueDecl *D,
const ParsedDeclName renamedParsedDeclName) {
auto declContext = D->getDeclContext();
const ValueDecl *renamedDecl = nullptr;

ASTContext &astContext = D->getASTContext();
auto renamedDeclName = renamedParsedDeclName.formDeclName(astContext);

if (isa<ClassDecl>(D) || isa<ProtocolDecl>(D)) {
if (!renamedParsedDeclName.ContextName.empty()) {
return nullptr;
}
UnqualifiedLookup lookup(renamedDeclName.getBaseIdentifier(),
declContext->getModuleScopeContext(),
nullptr,
declContext->getModuleScopeContext(), nullptr,
SourceLoc(),
UnqualifiedLookup::Flags::TypeLookup);
renamedDecl = lookup.getSingleTypeResult();
return lookup.getSingleTypeResult();
}

TypeDecl *typeDecl = declContext->getSelfNominalTypeDecl();

const ValueDecl *renamedDecl = nullptr;
SmallVector<ValueDecl *, 4> lookupResults;
declContext->lookupQualified(typeDecl->getDeclaredInterfaceType(),
renamedDeclName, NL_QualifiedDefault, nullptr,
lookupResults);

if (lookupResults.size() == 1) {
auto candidate = lookupResults[0];
if (!shouldInclude(candidate))
return nullptr;
if (candidate->getKind() != D->getKind() ||
(candidate->isInstanceMember() !=
cast<ValueDecl>(D)->isInstanceMember()))
return nullptr;

renamedDecl = candidate;
} else {
SmallVector<ValueDecl *, 4> lookupResults;
declContext->lookupQualified(
declContext->getSelfNominalTypeDecl(),
renamedDeclName, NL_QualifiedDefault, lookupResults);
for (auto candidate : lookupResults) {
if (!shouldInclude(candidate))
continue;

if (candidate->getKind() != D->getKind() ||
(candidate->isInstanceMember() !=
cast<ValueDecl>(D)->isInstanceMember()))
continue;

if (isa<FuncDecl>(candidate) &&
(cast<FuncDecl>(candidate)->getParameters()->size() !=
cast<FuncDecl>(D)->getParameters()->size()))
continue;


if (isa<AbstractFunctionDecl>(candidate)) {
auto cParams = cast<AbstractFunctionDecl>(candidate)->getParameters();
auto dParams = cast<AbstractFunctionDecl>(D)->getParameters();

if (cParams->size() != dParams->size())
continue;

bool hasSameParameterTypes = true;
for (auto index : indices(*cParams)) {
auto cParamsType = cParams->get(index)->getType();
auto dParamsType = dParams->get(index)->getType();
if (!cParamsType->matchesParameter(dParamsType,
TypeMatchOptions())) {
hasSameParameterTypes = false;
break;
}
}

if (!hasSameParameterTypes) {
continue;
}
}

if (renamedDecl) {
// If we found a duplicated candidate then we would silently fail.
renamedDecl = nullptr;
Expand All @@ -957,11 +988,20 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
renamedDecl = candidate;
}
}

return renamedDecl;
}

void printRenameForDecl(const AvailableAttr *AvAttr, const ValueDecl *D,
bool includeQuotes) {
assert(!AvAttr->Rename.empty());

const ValueDecl *renamedDecl =
getRenameDecl(D, parseDeclName(AvAttr->Rename));

if (renamedDecl) {
SmallString<128> scratch;
auto renamedObjCRuntimeName = renamedDecl->getObjCRuntimeName()
->getString(scratch);
auto renamedObjCRuntimeName =
renamedDecl->getObjCRuntimeName()->getString(scratch);
printEncodedString(renamedObjCRuntimeName, includeQuotes);
} else {
printEncodedString(AvAttr->Rename, includeQuotes);
Expand Down Expand Up @@ -1476,9 +1516,9 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
MAP(UnsafeMutableRawPointer, "void *", true);

Identifier ID_ObjectiveC = ctx.Id_ObjectiveC;
specialNames[{ID_ObjectiveC, ctx.getIdentifier("ObjCBool")}]
specialNames[{ID_ObjectiveC, ctx.getIdentifier("ObjCBool")}]
= { "BOOL", false};
specialNames[{ID_ObjectiveC, ctx.getIdentifier("Selector")}]
specialNames[{ID_ObjectiveC, ctx.getIdentifier("Selector")}]
= { "SEL", true };
specialNames[{ID_ObjectiveC,
ctx.getIdentifier(
Expand Down Expand Up @@ -1605,7 +1645,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
os << clangDecl->getKindName() << " ";
}

void visitStructType(StructType *ST,
void visitStructType(StructType *ST,
Optional<OptionalTypeKind> optionalKind) {
const StructDecl *SD = ST->getStructOrBoundGenericStruct();

Expand Down Expand Up @@ -1829,7 +1869,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
visitExistentialType(PT, optionalKind, /*isMetatype=*/false);
}

void visitProtocolCompositionType(ProtocolCompositionType *PCT,
void visitProtocolCompositionType(ProtocolCompositionType *PCT,
Optional<OptionalTypeKind> optionalKind) {
visitExistentialType(PCT, optionalKind, /*isMetatype=*/false);
}
Expand All @@ -1840,7 +1880,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
visitExistentialType(instanceTy, optionalKind, /*isMetatype=*/true);
}

void visitMetatypeType(MetatypeType *MT,
void visitMetatypeType(MetatypeType *MT,
Optional<OptionalTypeKind> optionalKind) {
Type instanceTy = MT->getInstanceType();
if (auto classTy = instanceTy->getAs<ClassType>()) {
Expand Down Expand Up @@ -1875,7 +1915,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
os << cast<clang::ObjCTypeParamDecl>(decl->getClangDecl())->getName();
printNullability(optionalKind);
}

void printFunctionType(FunctionType *FT, char pointerSigil,
Optional<OptionalTypeKind> optionalKind) {
visitPart(FT->getResult(), OTK_None);
Expand All @@ -1884,7 +1924,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
openFunctionTypes.push_back(FT);
}

void visitFunctionType(FunctionType *FT,
void visitFunctionType(FunctionType *FT,
Optional<OptionalTypeKind> optionalKind) {
switch (FT->getRepresentation()) {
case AnyFunctionType::Representation::Thin:
Expand Down Expand Up @@ -1928,18 +1968,18 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
visitPart(PT->getSinglyDesugaredType(), optionalKind);
}

void visitSyntaxSugarType(SyntaxSugarType *SST,
void visitSyntaxSugarType(SyntaxSugarType *SST,
Optional<OptionalTypeKind> optionalKind) {
visitPart(SST->getSinglyDesugaredType(), optionalKind);
}

void visitDynamicSelfType(DynamicSelfType *DST,
void visitDynamicSelfType(DynamicSelfType *DST,
Optional<OptionalTypeKind> optionalKind) {
printNullability(optionalKind, NullabilityPrintKind::ContextSensitive);
os << "instancetype";
}

void visitReferenceStorageType(ReferenceStorageType *RST,
void visitReferenceStorageType(ReferenceStorageType *RST,
Optional<OptionalTypeKind> optionalKind) {
visitPart(RST->getReferentType(), optionalKind);
}
Expand Down Expand Up @@ -1977,7 +2017,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
/// finishFunctionType()). If only a part of a type is being printed, use
/// visitPart().
public:
void print(Type ty, Optional<OptionalTypeKind> optionalKind,
void print(Type ty, Optional<OptionalTypeKind> optionalKind,
Identifier name = Identifier(),
IsFunctionParam_t isFuncParam = IsNotFunctionParam) {
PrettyStackTraceType trace(M.getASTContext(), "printing", ty);
Expand Down Expand Up @@ -2829,9 +2869,9 @@ class ModuleWriter {
// FIXME: This will end up taking linear time.
auto lhsMembers = cast<ExtensionDecl>(*lhs)->getMembers();
auto rhsMembers = cast<ExtensionDecl>(*rhs)->getMembers();
unsigned numLHSMembers = std::distance(lhsMembers.begin(),
unsigned numLHSMembers = std::distance(lhsMembers.begin(),
lhsMembers.end());
unsigned numRHSMembers = std::distance(rhsMembers.begin(),
unsigned numRHSMembers = std::distance(rhsMembers.begin(),
rhsMembers.end());
if (numLHSMembers != numRHSMembers)
return numLHSMembers < numRHSMembers ? Descending : Ascending;
Expand Down
Loading

0 comments on commit 5e157b8

Please sign in to comment.