Skip to content

Commit

Permalink
Squashed 'apollo-ios-codegen/' changes from 80c4d42e..f499efa4
Browse files Browse the repository at this point in the history
f499efa4 chore: Disable `@defer` support (#122)
70fd68cd Merge branch 'main' into feature/defer
d6c49617 Defer Selection Set Template - Basic (W/clean up) (#118)
f5dc1758 merge: `feature/defer` update to `main` (#116)
2c5463b0 refactor: [1/x] Refactor root field builder for deferred fragments (#74)
25d44b83 Merge branch 'main' into feature/defer
1d8424d3 Merge branch 'main' into feature/defer
a8c31ca3 Merge branch 'main' into feature/defer
d1a3c0ab feature: Operation definition template supports the `@defer` directive (#31)
6a01891b Merge branch 'project-breakup' into feature/defer
11cf5828 Merge branch 'project-breakup' into feature/defer
723b8648 refactor: Don't require `label` argument for deferred named fragments (#33)
9041eee0 feature: Require `label` argument on `@defer` directive (#28)
01b81541 Migrating defer branch to new project structure

git-subtree-dir: apollo-ios-codegen
git-subtree-split: f499efa4ee99c7eb86e5f2e6d0b630756c48f0de
  • Loading branch information
gh-action-runner authored and gh-action-runner committed Nov 2, 2023
1 parent 794f52c commit 68d78db
Show file tree
Hide file tree
Showing 34 changed files with 722 additions and 285 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ xcuserdata/
.DS_Store
*.tar.gz

## Visual Studio Code
.vscode/launch.json

## Obj-C/Swift specific
*.hmap
*.ipa
Expand Down
6 changes: 1 addition & 5 deletions Sources/ApolloCodegenLib/ApolloCodegen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -284,11 +284,7 @@ public class ApolloCodegen {
}

let documents = try await matches.concurrentCompactMap { match in
try await frontend.parseDocument(
from: URL(fileURLWithPath: match),
experimentalClientControlledNullability:
self.config.experimentalFeatures.clientControlledNullability
)
try await frontend.parseDocument(from: URL(fileURLWithPath: match))
}

return try await frontend.mergeDocuments(documents)
Expand Down
30 changes: 0 additions & 30 deletions Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -879,27 +879,6 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
}

public struct ExperimentalFeatures: Codable, Equatable {
/**
* **EXPERIMENTAL**: If enabled, the parser will understand and parse Client Controlled Nullability
* Designators contained in Fields. They'll be represented in the
* `required` field of the FieldNode.
*
* The syntax looks like the following:
*
* ```graphql
* {
* nullableField!
* nonNullableField?
* nonNullableSelectionSet? {
* childField!
* }
* }
* ```
* - Note: This feature is experimental and may change or be removed in the
* future.
*/
public let clientControlledNullability: Bool

/**
* **EXPERIMENTAL**: If enabled, the generated operations will be transformed using a method
* that attempts to maintain compatibility with the legacy behavior from
Expand All @@ -913,33 +892,24 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {

/// Default property values
public struct Default {
public static let clientControlledNullability: Bool = false
public static let legacySafelistingCompatibleOperations: Bool = false
}

public init(
clientControlledNullability: Bool = Default.clientControlledNullability,
legacySafelistingCompatibleOperations: Bool = Default.legacySafelistingCompatibleOperations
) {
self.clientControlledNullability = clientControlledNullability
self.legacySafelistingCompatibleOperations = legacySafelistingCompatibleOperations
}

// MARK: Codable

public enum CodingKeys: CodingKey, CaseIterable {
case clientControlledNullability
case legacySafelistingCompatibleOperations
}

public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)

clientControlledNullability = try values.decodeIfPresent(
Bool.self,
forKey: .clientControlledNullability
) ?? Default.clientControlledNullability

legacySafelistingCompatibleOperations = try values.decodeIfPresent(
Bool.self,
forKey: .legacySafelistingCompatibleOperations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ struct OperationDefinitionTemplate: OperationTemplateRenderer {
\(OperationDeclaration())
\(DocumentType())
\(section: DeferredProperties(operation.containsDeferredFragment))
\(section: VariableProperties(operation.definition.variables))
\(Initializer(operation.definition.variables))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,14 @@ extension OperationTemplateRenderer {
"""
}

func DeferredProperties(
_ hasDeferredFragments: Bool
) -> TemplateString {
return """
\(if: hasDeferredFragments, """
public static let hasDeferredFragments: Bool = true
""")
"""
}

}
133 changes: 111 additions & 22 deletions Sources/ApolloCodegenLib/Templates/SelectionSetTemplate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ struct SelectionSetTemplate {
\(SelectionSetNameDocumentation(inlineFragment))
\(renderAccessControl())\
struct \(inlineFragment.renderedTypeName): \(SelectionSetType(asInlineFragment: true))\
\(if: inlineFragment.isCompositeSelectionSet, ", \(config.ApolloAPITargetName).CompositeInlineFragment") \
{
\(if: inlineFragment.isCompositeSelectionSet, ", \(config.ApolloAPITargetName).CompositeInlineFragment")\
\(if: inlineFragment.isDeferred, ", \(config.ApolloAPITargetName).Deferrable")\
{
\(BodyTemplate(inlineFragment))
}
"""
Expand Down Expand Up @@ -98,7 +99,8 @@ struct SelectionSetTemplate {
let selections = selectionSet.selections
let scope = selectionSet.typeInfo.scope
return """
\(DataFieldAndInitializerTemplate())
\(DataPropertyTemplate())
\(InitializerTemplate())
\(RootEntityTypealias(selectionSet))
\(ParentTypeTemplate(selectionSet.parentType))
Expand All @@ -119,13 +121,28 @@ struct SelectionSetTemplate {
"""
}

private func DataFieldAndInitializerTemplate() -> String {
let accessControl = renderAccessControl()
private func InitializerTemplate(
_ propertiesTemplate: @autoclosure () -> TemplateString? = { nil }()
) -> String {
let dataInitStatement = TemplateString("__data = _dataDict")

return """
\(accessControl)\(isMutable ? "var" : "let") __data: DataDict
\(accessControl)init(_dataDict: DataDict) { __data = _dataDict }
"""
return TemplateString("""
\(renderAccessControl())init(_dataDict: DataDict) {\
\(ifLet: propertiesTemplate(), where: { !$0.isEmpty }, {
"""
\(dataInitStatement)
\($0)
"""
},
else: " \(dataInitStatement) "
)}
""").description
}

private func DataPropertyTemplate() -> TemplateString {
"\(renderAccessControl())\(isMutable ? "var" : "let") __data: DataDict"
}

private func RootEntityTypealias(_ selectionSet: IR.SelectionSet) -> TemplateString {
Expand Down Expand Up @@ -285,9 +302,14 @@ struct SelectionSetTemplate {
}

private func InlineFragmentSelectionTemplate(_ inlineFragment: IR.SelectionSet) -> TemplateString {
"""
.inlineFragment(\(inlineFragment.renderedTypeName).self)
"""
if let deferCondition = inlineFragment.deferCondition {
return DeferredInlineFragmentSelectionTemplate(deferCondition)

} else {
return """
.inlineFragment(\(inlineFragment.renderedTypeName).self)
"""
}
}

private func FragmentSelectionTemplate(_ fragment: IR.NamedFragmentSpread) -> TemplateString {
Expand All @@ -296,6 +318,16 @@ struct SelectionSetTemplate {
"""
}

private func DeferredInlineFragmentSelectionTemplate(
_ deferCondition: CompilationResult.DeferCondition
) -> TemplateString {
"""
.deferred(\
\(ifLet: deferCondition.variable, { "if: \"\($0)\", " })\
\(deferCondition.renderedTypeName).self, label: "\(deferCondition.label)")
"""
}

// MARK: - Accessors
private func FieldAccessorsTemplate(
_ selections: IR.SelectionSet.Selections,
Expand Down Expand Up @@ -343,6 +375,8 @@ struct SelectionSetTemplate {
}

private func InlineFragmentAccessorTemplate(_ inlineFragment: IR.SelectionSet) -> TemplateString {
guard !inlineFragment.typeInfo.scope.isDeferred else { return "" }

let typeName = inlineFragment.renderedTypeName
return """
\(renderAccessControl())var \(typeName.firstLowercased): \(typeName)? {\
Expand All @@ -362,25 +396,57 @@ struct SelectionSetTemplate {
_ selections: IR.SelectionSet.Selections,
in scope: IR.ScopeDescriptor
) -> TemplateString {
guard !(selections.direct?.namedFragments.isEmpty ?? true) ||
!selections.merged.namedFragments.isEmpty else {
guard
!(selections.direct?.namedFragments.isEmpty ?? true)
|| !selections.merged.namedFragments.isEmpty
|| (selections.direct?.inlineFragments.containsDeferredFragment ?? false)
else {
return ""
}

return """
\(renderAccessControl())struct Fragments: FragmentContainer {
\(DataFieldAndInitializerTemplate())
\(DataPropertyTemplate())
\(FragmentInitializerTemplate(selections))
\(ifLet: selections.direct?.namedFragments.values, {
"\($0.map { NamedFragmentAccessorTemplate($0, in: scope) }, separator: "\n")"
})
})
\(selections.merged.namedFragments.values.map {
NamedFragmentAccessorTemplate($0, in: scope)
}, separator: "\n")
NamedFragmentAccessorTemplate($0, in: scope)
}, separator: "\n")
\(forEachIn: selections.direct?.inlineFragments.values.elements ?? [], {
"\(ifLet: $0.typeInfo.deferCondition, DeferredFragmentAccessorTemplate)"
})
}
"""
}

private func FragmentInitializerTemplate(
_ selections: IR.SelectionSet.Selections
) -> String {
if let inlineFragments = selections.direct?.inlineFragments,
inlineFragments.containsDeferredFragment {
return InitializerTemplate("""
\(forEachIn: inlineFragments.values, {
guard let deferCondition = $0.typeInfo.deferCondition else {
return nil
}
return DeferredPropertyInitializationStatement(deferCondition)
})
""")

} else {
return InitializerTemplate()
}
}

private func DeferredPropertyInitializationStatement(
_ deferCondition: CompilationResult.DeferCondition
) -> TemplateString {
"_\(deferCondition.label) = Deferred(_dataDict: _dataDict)"
}

private func NamedFragmentAccessorTemplate(
_ fragment: IR.NamedFragmentSpread,
in scope: IR.ScopeDescriptor
Expand Down Expand Up @@ -412,6 +478,12 @@ struct SelectionSetTemplate {
"""
}

private func DeferredFragmentAccessorTemplate(
_ deferCondition: CompilationResult.DeferCondition
) -> TemplateString {
"@Deferred public var \(deferCondition.label): \(deferCondition.renderedTypeName)?"
}

// MARK: - SelectionSet Initializer

private func InitializerTemplate(_ selectionSet: IR.SelectionSet) -> TemplateString {
Expand Down Expand Up @@ -892,10 +964,15 @@ fileprivate struct SelectionSetNameGenerator {
fileprivate extension IR.ScopeCondition {

var selectionSetNameComponent: String {
return TemplateString("""
\(ifLet: type, { "As\($0.formattedName)" })\
\(ifLet: conditions, { "If\($0.typeNameComponents)"})
""").description
if let deferCondition {
return deferCondition.renderedTypeName

} else {
return TemplateString("""
\(ifLet: type, { "As\($0.formattedName)" })\
\(ifLet: conditions, { "If\($0.typeNameComponents)"})
""").description
}
}

}
Expand Down Expand Up @@ -989,3 +1066,15 @@ extension IR.SelectionSet.Selections {

}
}

fileprivate extension CompilationResult.DeferCondition {
var renderedTypeName: String {
self.label.convertToCamelCase().firstUppercased.asSelectionSetName
}
}

fileprivate extension OrderedDictionary<ScopeCondition, InlineFragmentSpread> {
var containsDeferredFragment: Bool {
keys.contains(where: { $0.isDeferred })
}
}
2 changes: 1 addition & 1 deletion Sources/GraphQLCompiler/ApolloCodegenFrontendBundle.swift

Large diffs are not rendered by default.

Loading

0 comments on commit 68d78db

Please sign in to comment.