Skip to content

Commit 53e7102

Browse files
gh-action-runnergh-action-runner
authored andcommitted
Squashed 'apollo-ios-codegen/' changes from 3537e4961..a4e90970f
a4e90970f Remove SPI from internal models (#796) git-subtree-dir: apollo-ios-codegen git-subtree-split: a4e90970fa0a1117dd505eaabb7f8265af49fe8f
1 parent bd517bb commit 53e7102

16 files changed

+241
-176
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import Foundation
2+
3+
/// The @_spi values used by Apollo iOS
4+
enum SPI {
5+
case Unsafe
6+
case Internal
7+
case Execution
8+
}
9+
10+
struct AccessControlRenderer {
11+
12+
enum Scope {
13+
case namespace
14+
case parent
15+
case member
16+
}
17+
18+
private let accessModifier: ApolloCodegenConfiguration.AccessModifier?
19+
20+
init(
21+
target: TemplateTarget,
22+
config: ApolloCodegenConfiguration,
23+
scope: Scope
24+
) {
25+
self.accessModifier = Self.accessControlModifier(target: target, config: config, scope: scope)
26+
}
27+
28+
func render(withSPIs spis: [SPI] = []) -> String {
29+
var string = accessModifier?.swiftString ?? ""
30+
31+
guard shouldIncludeSPI else { return string }
32+
33+
for spi in spis.reversed() {
34+
string = "@_spi(\(spi)) " + string
35+
}
36+
return string
37+
}
38+
39+
/// SPI should only be used on public declarations. Internal declarations must omit them.
40+
private var shouldIncludeSPI: Bool {
41+
accessModifier == .public
42+
}
43+
44+
private static func accessControlModifier(
45+
target: TemplateTarget,
46+
config: ApolloCodegenConfiguration,
47+
scope: Scope
48+
) -> ApolloCodegenConfiguration.AccessModifier? {
49+
switch target {
50+
case .moduleFile, .schemaFile: return schemaAccessControlModifier(scope, config)
51+
case .operationFile: return operationAccessControlModifier(scope, config)
52+
case .testMockFile: return testMockAccessControlModifier(scope, config)
53+
}
54+
}
55+
56+
private static func schemaAccessControlModifier(
57+
_ scope: Scope,
58+
_ config: ApolloCodegenConfiguration,
59+
) -> ApolloCodegenConfiguration.AccessModifier? {
60+
switch (config.output.schemaTypes.moduleType, scope) {
61+
case (.embeddedInTarget, .parent):
62+
return nil
63+
case (.embeddedInTarget(_, .public), .namespace),
64+
(.embeddedInTarget(_, .public), .member):
65+
return .public
66+
case (.embeddedInTarget(_, .internal), .namespace),
67+
(.embeddedInTarget(_, .internal), .member):
68+
return .internal
69+
case (.swiftPackage, _),
70+
(.other, _):
71+
return .public
72+
}
73+
}
74+
75+
private static func operationAccessControlModifier(
76+
_ scope: Scope,
77+
_ config: ApolloCodegenConfiguration,
78+
) -> ApolloCodegenConfiguration.AccessModifier? {
79+
switch (config.output.operations, scope) {
80+
case (.inSchemaModule, _):
81+
return schemaAccessControlModifier(scope, config)
82+
case (.absolute(_, .public), _),
83+
(.relative(_, .public), _):
84+
return .public
85+
case (.absolute(_, .internal), _),
86+
(.relative(_, .internal), _):
87+
return .internal
88+
}
89+
}
90+
91+
private static func testMockAccessControlModifier(
92+
_ scope: Scope,
93+
_ config: ApolloCodegenConfiguration,
94+
) -> ApolloCodegenConfiguration.AccessModifier? {
95+
switch (config.output.testMocks, scope) {
96+
case (.none, _):
97+
return nil
98+
case (.absolute(_, .internal), _):
99+
return .internal
100+
case (.swiftPackage, _),
101+
(.absolute(_, .public), _):
102+
return .public
103+
}
104+
}
105+
106+
}
107+
108+
fileprivate extension ApolloCodegenConfiguration.AccessModifier {
109+
var swiftString: String {
110+
switch self {
111+
case .public: return "public "
112+
case .internal: return ""
113+
}
114+
}
115+
}

Sources/ApolloCodegenLib/Templates/CustomScalarTemplate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ struct CustomScalarTemplate: TemplateRenderer {
2727
"""
2828
\(documentation: documentationTemplate, config: config)
2929
\(graphqlScalar.name.typeNameDocumentation)
30-
\(accessControlModifier(for: .parent))\
30+
\(accessControlRenderer(for: .parent).render())\
3131
typealias \(graphqlScalar.render(as: .typename())) = String
3232
3333
"""

Sources/ApolloCodegenLib/Templates/EnumTemplate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ struct EnumTemplate: TemplateRenderer {
1919
"""
2020
\(documentation: graphqlEnum.documentation, config: config)
2121
\(graphqlEnum.name.typeNameDocumentation)
22-
\(accessControlModifier(for: .parent))\
22+
\(accessControlRenderer(for: .parent).render())\
2323
enum \(graphqlEnum.render(as: .typename())): String, EnumType {
2424
\(graphqlEnum.values.compactMap({
2525
enumCase(for: $0)

Sources/ApolloCodegenLib/Templates/FragmentTemplate.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ struct FragmentTemplate: TemplateRenderer {
1818
nonFatalErrorRecorder: ApolloCodegen.NonFatalError.Recorder
1919
) -> TemplateString {
2020
let includeDefinition = config.options.operationDocumentFormat.contains(.definition)
21-
21+
let memberAccessControlRenderer = accessControlRenderer(for: .member)
2222
return TemplateString(
2323
"""
24-
\(accessControlModifier(for: .parent))\
24+
\(accessControlRenderer(for: .parent).render())\
2525
struct \(fragment.generatedDefinitionName.asFragmentName): \
2626
\(fragment.renderedSelectionSetType(config)), Fragment\
2727
\(if: fragment.isIdentifiable, ", Identifiable")\
2828
{
2929
\(if: includeDefinition, """
30-
\(accessControlModifier(for: .member))\
30+
\(memberAccessControlRenderer.render())\
3131
static var fragmentDefinition: StaticString {
3232
#"\(fragment.definition.source.convertedToSingleLine())"#
3333
}
@@ -38,7 +38,7 @@ struct FragmentTemplate: TemplateRenderer {
3838
generateInitializers: config.config.shouldGenerateSelectionSetInitializers(for: fragment),
3939
config: config,
4040
nonFatalErrorRecorder: nonFatalErrorRecorder,
41-
renderAccessControl: { accessControlModifier(for: .member) }()
41+
accessControlRenderer: memberAccessControlRenderer
4242
).renderBody())
4343
}
4444

Sources/ApolloCodegenLib/Templates/InputObjectTemplate.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,22 @@ struct InputObjectTemplate: TemplateRenderer {
1616
nonFatalErrorRecorder: ApolloCodegen.NonFatalError.Recorder
1717
) -> TemplateString {
1818
let (validFields, deprecatedFields) = graphqlInputObject.fields.filterFields()
19-
let memberAccessControl = accessControlModifier(for: .member)
19+
let memberAccessControl = accessControlRenderer(for: .member)
2020

2121
return TemplateString(
2222
"""
2323
\(documentation: graphqlInputObject.documentation, config: config)
2424
\(graphqlInputObject.name.typeNameDocumentation)
25-
\(accessControlModifier(for: .parent))\
25+
\(accessControlRenderer(for: .parent).render())\
2626
struct \(graphqlInputObject.render(as: .typename())): InputObject {
27-
@_spi(Unsafe) \(memberAccessControl)private(set) var __data: InputDict
27+
\(memberAccessControl.render(withSPIs: [.Unsafe]))private(set) var __data: InputDict
2828
29-
@_spi(Unsafe) \(memberAccessControl)init(_ data: InputDict) {
29+
\(memberAccessControl.render(withSPIs: [.Unsafe]))init(_ data: InputDict) {
3030
__data = data
3131
}
3232
3333
\(if: !deprecatedFields.isEmpty && !validFields.isEmpty && shouldIncludeDeprecatedWarnings, """
34-
\(memberAccessControl)init(
34+
\(memberAccessControl.render())init(
3535
\(InitializerParametersTemplate(validFields))
3636
) {
3737
__data = InputDict([
@@ -44,7 +44,7 @@ struct InputObjectTemplate: TemplateRenderer {
4444
\(if: !deprecatedFields.isEmpty && shouldIncludeDeprecatedWarnings, """
4545
@available(*, deprecated, message: "\(deprecatedMessage(for: deprecatedFields))")
4646
""")
47-
\(memberAccessControl)init(
47+
\(memberAccessControl.render())init(
4848
\(InitializerParametersTemplate(graphqlInputObject.fields))
4949
) {
5050
__data = InputDict([
@@ -104,7 +104,7 @@ struct InputObjectTemplate: TemplateRenderer {
104104
\(documentation: field.documentation, config: config)
105105
\(deprecationReason: field.deprecationReason, config: config)
106106
\(field.name.typeNameDocumentation)
107-
\(accessControlModifier(for: .member))\
107+
\(accessControlRenderer(for: .member).render())\
108108
var \(field.render(config: config)): \(field.renderInputValueType(config: config.config)) {
109109
get { __data["\(field.name.schemaName)"] }
110110
set { __data["\(field.name.schemaName)"] = newValue }

Sources/ApolloCodegenLib/Templates/LocalCacheMutationDefinitionTemplate.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ struct LocalCacheMutationDefinitionTemplate: OperationTemplateRenderer {
1515
func renderBodyTemplate(
1616
nonFatalErrorRecorder: ApolloCodegen.NonFatalError.Recorder
1717
) -> TemplateString {
18-
let memberAccessControl = accessControlModifier(for: .member)
18+
let memberAccessControlRenderer = accessControlRenderer(for: .member)
19+
let memberAccessControl = memberAccessControlRenderer.render()
1920

2021
return TemplateString(
2122
"""
22-
\(accessControlModifier(for: .parent))\
23+
\(accessControlRenderer(for: .parent).render())\
2324
struct \(operation.generatedDefinitionName): LocalCacheMutation {
2425
\(memberAccessControl)static let operationType: GraphQLOperationType = .\(operation.definition.operationType.rawValue)
2526
@@ -35,7 +36,7 @@ struct LocalCacheMutationDefinitionTemplate: OperationTemplateRenderer {
3536
generateInitializers: config.config.shouldGenerateSelectionSetInitializers(for: operation),
3637
config: config,
3738
nonFatalErrorRecorder: nonFatalErrorRecorder,
38-
renderAccessControl: { accessControlModifier(for: .member) }()
39+
accessControlRenderer: memberAccessControlRenderer
3940
).renderBody())
4041
}
4142
}

Sources/ApolloCodegenLib/Templates/MockInterfacesTemplate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct MockInterfacesTemplate: TemplateRenderer {
1515
nonFatalErrorRecorder: ApolloCodegen.NonFatalError.Recorder
1616
) -> TemplateString {
1717
TemplateString("""
18-
\(accessControlModifier(for: .parent))extension MockObject {
18+
\(accessControlRenderer(for: .parent).render())extension MockObject {
1919
\(graphqlInterfaces.map {
2020
"typealias \($0.render(as: .typename())) = Interface"
2121
}, separator: "\n")

Sources/ApolloCodegenLib/Templates/MockObjectTemplate.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,11 @@ struct MockObjectTemplate: TemplateRenderer {
5151
)
5252
}
5353

54-
let memberAccessControl = accessControlModifier(for: .member)
54+
let memberAccessControl = accessControlRenderer(for: .member).render()
55+
let parentAccessControl = accessControlRenderer(for: .parent).render()
5556

5657
return """
57-
\(accessControlModifier(for: .parent))final class \(objectName): MockObject {
58+
\(parentAccessControl)final class \(objectName): MockObject {
5859
\(memberAccessControl)static let objectType: \(TemplateConstants.ApolloAPITargetName).Object = \(config.schemaNamespace.firstUppercased).Objects.\(objectName)
5960
\(memberAccessControl)static let _mockFields = MockFields()
6061
\(memberAccessControl)typealias MockValueCollectionType = Array<Mock<\(objectName)>>
@@ -71,7 +72,7 @@ struct MockObjectTemplate: TemplateRenderer {
7172
\(!fields.isEmpty ?
7273
TemplateString("""
7374
74-
\(accessControlModifier(for: .parent))\
75+
\(parentAccessControl)\
7576
extension Mock where O == \(objectName) {
7677
\(conflictingFieldNameProperties(fields))
7778
convenience init(

Sources/ApolloCodegenLib/Templates/MockUnionsTemplate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct MockUnionsTemplate: TemplateRenderer {
1515
nonFatalErrorRecorder: ApolloCodegen.NonFatalError.Recorder
1616
) -> TemplateString {
1717
TemplateString("""
18-
\(accessControlModifier(for: .parent))extension MockObject {
18+
\(accessControlRenderer(for: .parent).render())extension MockObject {
1919
\(graphqlUnions.map {
2020
"typealias \($0.render(as: .typename())) = Union"
2121
}, separator: "\n")

Sources/ApolloCodegenLib/Templates/OneOfInputObjectTemplate.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ struct OneOfInputObjectTemplate: TemplateRenderer {
1313
func renderBodyTemplate(
1414
nonFatalErrorRecorder: ApolloCodegen.NonFatalError.Recorder
1515
) -> TemplateString {
16-
let memberAccessControl = accessControlModifier(for: .member)
16+
let memberAccessControl = accessControlRenderer(for: .member)
1717

1818
return TemplateString(
1919
"""
2020
\(documentation: graphqlInputObject.documentation, config: config)
2121
\(graphqlInputObject.name.typeNameDocumentation)
22-
\(accessControlModifier(for: .parent))\
22+
\(accessControlRenderer(for: .parent).render())\
2323
enum \(graphqlInputObject.render(as: .typename())): OneOfInputObject {
2424
\(graphqlInputObject.fields.map({ "\(FieldCaseTemplate($1))" }), separator: "\n")
2525
26-
@_spi(Unsafe) \(memberAccessControl)var __data: InputDict {
26+
\(memberAccessControl.render(withSPIs: [.Unsafe]))var __data: InputDict {
2727
switch self {
2828
\(graphqlInputObject.fields.map({ "\(FieldCaseDataTemplate($1))" }), separator: "\n")
2929
}

0 commit comments

Comments
 (0)