Skip to content

Commit fb0233a

Browse files
committed
Sema: Clean up createDesignatedInitOverride()
1 parent 431dd1c commit fb0233a

File tree

1 file changed

+65
-55
lines changed

1 file changed

+65
-55
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 65 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1997,6 +1997,68 @@ static void createStubBody(TypeChecker &tc, ConstructorDecl *ctor) {
19971997
ctor->setStubImplementation(true);
19981998
}
19991999

2000+
static void configureDesignatedInitAttributes(TypeChecker &tc,
2001+
ClassDecl *classDecl,
2002+
ConstructorDecl *ctor,
2003+
ConstructorDecl *superclassCtor) {
2004+
auto &ctx = tc.Context;
2005+
2006+
AccessLevel access = classDecl->getFormalAccess();
2007+
access = std::max(access, AccessLevel::Internal);
2008+
access = std::min(access, superclassCtor->getFormalAccess());
2009+
2010+
ctor->setAccess(access);
2011+
2012+
// Inherit the @inlinable attribute.
2013+
if (superclassCtor->getFormalAccess(/*useDC=*/nullptr,
2014+
/*treatUsableFromInlineAsPublic=*/true)
2015+
>= AccessLevel::Public) {
2016+
if (superclassCtor->getAttrs().hasAttribute<InlinableAttr>()) {
2017+
auto *clonedAttr = new (ctx) InlinableAttr(/*implicit=*/true);
2018+
ctor->getAttrs().add(clonedAttr);
2019+
}
2020+
}
2021+
2022+
// Inherit the @usableFromInline attribute. We need better abstractions
2023+
// for dealing with @usableFromInline.
2024+
if (superclassCtor->getFormalAccess(/*useDC=*/nullptr,
2025+
/*treatUsableFromInlineAsPublic=*/true)
2026+
>= AccessLevel::Public) {
2027+
if (access == AccessLevel::Internal &&
2028+
!superclassCtor->isDynamic()) {
2029+
auto *clonedAttr = new (ctx) UsableFromInlineAttr(/*implicit=*/true);
2030+
ctor->getAttrs().add(clonedAttr);
2031+
}
2032+
}
2033+
2034+
// Make sure the constructor is only as available as its superclass's
2035+
// constructor.
2036+
AvailabilityInference::applyInferredAvailableAttrs(ctor, superclassCtor, ctx);
2037+
2038+
if (superclassCtor->isObjC()) {
2039+
// Inherit the @objc name from the superclass initializer, if it
2040+
// has one.
2041+
if (auto objcAttr = superclassCtor->getAttrs().getAttribute<ObjCAttr>()) {
2042+
if (objcAttr->hasName()) {
2043+
auto *clonedAttr = objcAttr->clone(ctx);
2044+
clonedAttr->setImplicit(true);
2045+
ctor->getAttrs().add(clonedAttr);
2046+
}
2047+
}
2048+
2049+
auto errorConvention = superclassCtor->getForeignErrorConvention();
2050+
markAsObjC(tc, ctor, ObjCReason::ImplicitlyObjC, errorConvention);
2051+
}
2052+
if (superclassCtor->isRequired())
2053+
ctor->getAttrs().add(new (ctx) RequiredAttr(/*IsImplicit=*/true));
2054+
if (superclassCtor->isDynamic())
2055+
ctor->getAttrs().add(new (ctx) DynamicAttr(/*IsImplicit*/true));
2056+
2057+
// Wire up the overrides.
2058+
ctor->getAttrs().add(new (ctx) OverrideAttr(/*IsImplicit=*/true));
2059+
ctor->setOverriddenDecl(superclassCtor);
2060+
}
2061+
20002062
ConstructorDecl *
20012063
swift::createDesignatedInitOverride(TypeChecker &tc,
20022064
ClassDecl *classDecl,
@@ -2082,66 +2144,14 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
20822144

20832145
ctor->setImplicit();
20842146

2085-
AccessLevel access = classDecl->getFormalAccess();
2086-
access = std::max(access, AccessLevel::Internal);
2087-
access = std::min(access, superclassCtor->getFormalAccess());
2088-
2089-
ctor->setAccess(access);
2090-
2091-
// This is really painful. We need better abstractions for dealing with
2092-
// @usableFromInline.
2093-
if (superclassCtor->getFormalAccess(/*useDC=*/nullptr,
2094-
/*treatUsableFromInlineAsPublic=*/true)
2095-
>= AccessLevel::Public) {
2096-
if (access == AccessLevel::Internal &&
2097-
!superclassCtor->isDynamic()) {
2098-
auto *clonedAttr = new (ctx) UsableFromInlineAttr(/*implicit=*/true);
2099-
ctor->getAttrs().add(clonedAttr);
2100-
}
2101-
}
2102-
2103-
// Inherit the @inlinable attribute.
2104-
if (ctor->getFormalAccess(/*useDC=*/nullptr,
2105-
/*treatUsableFromInlineAsPublic=*/true)
2106-
>= AccessLevel::Public) {
2107-
if (superclassCtor->getAttrs().hasAttribute<InlinableAttr>()) {
2108-
auto *clonedAttr = new (ctx) InlinableAttr(/*implicit=*/true);
2109-
ctor->getAttrs().add(clonedAttr);
2110-
}
2111-
}
2112-
2113-
// Make sure the constructor is only as available as its superclass's
2114-
// constructor.
2115-
AvailabilityInference::applyInferredAvailableAttrs(ctor, superclassCtor, ctx);
2116-
21172147
// Set the interface type of the initializer.
21182148
ctor->setGenericEnvironment(classDecl->getGenericEnvironmentOfContext());
21192149
tc.configureInterfaceType(ctor, ctor->getGenericSignature());
2120-
2121-
if (superclassCtor->isObjC()) {
2122-
// Inherit the @objc name from the superclass initializer, if it
2123-
// has one.
2124-
if (auto objcAttr = superclassCtor->getAttrs().getAttribute<ObjCAttr>()) {
2125-
if (objcAttr->hasName()) {
2126-
auto *clonedAttr = objcAttr->clone(ctx);
2127-
clonedAttr->setImplicit(true);
2128-
ctor->getAttrs().add(clonedAttr);
2129-
}
2130-
}
2131-
2132-
auto errorConvention = superclassCtor->getForeignErrorConvention();
2133-
markAsObjC(tc, ctor, ObjCReason::ImplicitlyObjC, errorConvention);
2134-
}
2135-
if (superclassCtor->isRequired())
2136-
ctor->getAttrs().add(new (tc.Context) RequiredAttr(/*IsImplicit=*/true));
2137-
if (superclassCtor->isDynamic())
2138-
ctor->getAttrs().add(new (tc.Context) DynamicAttr(/*IsImplicit*/true));
2139-
2140-
// Wire up the overrides.
2141-
ctor->getAttrs().add(new (tc.Context) OverrideAttr(/*IsImplicit=*/true));
2142-
ctor->setOverriddenDecl(superclassCtor);
21432150
ctor->setValidationStarted();
21442151

2152+
configureDesignatedInitAttributes(tc, classDecl,
2153+
ctor, superclassCtor);
2154+
21452155
if (kind == DesignatedInitKind::Stub) {
21462156
// Make this a stub implementation.
21472157
createStubBody(tc, ctor);

0 commit comments

Comments
 (0)