Skip to content

Commit

Permalink
Merge pull request #2658 from square/add_missing_parameterized_imports
Browse files Browse the repository at this point in the history
[swift] Ensure imports of parameterized type names are emitted
  • Loading branch information
oldergod authored Oct 6, 2023
2 parents fc7e563 + 34edcff commit 126c5f4
Show file tree
Hide file tree
Showing 51 changed files with 637 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ jobs:
run: |
./gradlew generateSwiftTests --stacktrace --warning-mode all
if [ ! -z "$(git status --porcelain)" ]; then git diff; echo -e "\nGenerated files changed. Did you run ./gradlew generateSwiftProtos and generateSwiftTests?"; exit 1; fi
./gradlew :wire-tests-swift:build --stacktrace --warning-mode all
./gradlew -p wire-tests-swift build --stacktrace --warning-mode all
- name: Test Swift Package Manager
run: swift test
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ gradlew.bat
# Maven
plugin*.xml

# SPM
.build

# Special Mkdocs files
docs/3.x
docs/changelog.md
Expand Down
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ let package = Package(
.target(
name: "WireTests",
dependencies: ["Wire"],
path: "wire-tests-swift/src/main/swift"
path: "wire-tests-swift/no-manifest/src/main/swift"
),
.testTarget(
name: "WireCompilerTests",
dependencies: ["WireTests"],
path: "wire-tests-swift/src/test/swift"
path: "wire-tests-swift/no-manifest/src/test/swift"
),
],
swiftLanguageVersions: [.v5]
Expand Down
9 changes: 7 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ allprojects {
subprojects {
if (name != "wire-golden-files" &&
name != "wire-tests-proto3-swift" &&
name != "wire-tests-swift"
name != "wire-tests-swift" &&
name != "no-manifest" &&
name != "module_one" &&
name != "module_two" &&
name != "module_three"
) {
apply(plugin = "com.diffplug.spotless")
configure<SpotlessExtension> {
Expand Down Expand Up @@ -143,7 +147,8 @@ subprojects {
project.name.endsWith("-benchmarks") ||
project.name.contains("golden") ||
project.name.contains("protoc") ||
project.displayName.contains("sample")
project.displayName.contains("sample") ||
project.displayName.contains("wire-tests-swift")
)
) {
apply(plugin = "checkstyle")
Expand Down
20 changes: 19 additions & 1 deletion gen-tests.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,25 @@ val generateSwiftProto3Tests by tasks.creating(JavaExec::class) {
)
}

val generateSwiftProto2ManifestTests by tasks.creating(JavaExec::class) {
val swiftOut = "wire-tests-swift/manifest"

group = "Generate Tests"
description = "Generates Swift classes from the test protos using a manifest"
classpath = wire
mainClass.set("com.squareup.wire.WireCompiler")
args = listOf(
"--proto_path=wire-tests/src/commonTest/proto/kotlin",
"--swift_out=$swiftOut",
"--experimental-module-manifest=wire-tests/src/commonTest/proto/kotlin/swift_modules_manifest.yaml",
"swift_module_one.proto",
"swift_module_two.proto",
"swift_module_three.proto",
)
}

val generateSwiftProto2Tests by tasks.creating(JavaExec::class) {
val swiftOut = "wire-tests-swift/src/main/swift/"
val swiftOut = "wire-tests-swift/no-manifest/src/main/swift"
doFirst {
val outFile = file(swiftOut)
outFile.deleteRecursively()
Expand Down Expand Up @@ -461,6 +478,7 @@ val generateSwiftTests by tasks.creating {
group = "Generate Tests"
description = "Generates Swift classes from the test protos"
dependsOn(
generateSwiftProto2ManifestTests,
generateSwiftProto2Tests,
generateSwiftProto3Tests,
":wire-runtime-swift:generateTestProtos"
Expand Down
4 changes: 4 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ include(":wire-tests")
if (startParameter.projectProperties.get("swift") != "false") {
include(":wire-runtime-swift")
include(":wire-tests-swift")
include(":wire-tests-swift:no-manifest")
include(":wire-tests-swift:manifest:module_one")
include(":wire-tests-swift:manifest:module_two")
include(":wire-tests-swift:manifest:module_three")
include(":wire-tests-proto3-swift")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,13 @@ class SwiftGenerator private constructor(
if (typeName is DeclaredTypeName) {
imports.add(typeName.moduleName)
}
if (typeName is ParameterizedTypeName) {
typeName.typeArguments.forEach { declaredTypeName ->
if (declaredTypeName is DeclaredTypeName) {
imports.add(declaredTypeName.moduleName)
}
}
}

val property = PropertySpec.varBuilder(field.name, field.typeName, visibility)
if (!forStorageType && field.documentation.isNotBlank()) {
Expand Down
44 changes: 16 additions & 28 deletions wire-tests-swift/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,32 +1,20 @@
plugins {
id("swift-library")
id("xcode")
id("xctest")
}

library {
dependencies {
api(projects.wireRuntimeSwift)
}

module.set("WireTests")
}

afterEvaluate {
tasks.withType(SwiftCompile::class).all {
// Include the ${DEVELOPER_DIR}/usr/lib as we also need to use libXCTestSwiftSupport.dylib as of
// Xcode 12.5:
// https://forums.swift.org/t/why-xcode-12-5b-cannot-find-xctassertequal-in-scope-in-playground/44411
val developerDir = compilerArgs.get().extractDeveloperDir() ?: return@all
compilerArgs.add("-I$developerDir/usr/lib")
}
subprojects {
afterEvaluate {
tasks.withType(SwiftCompile::class).all {
// Include the ${DEVELOPER_DIR}/usr/lib as we also need to use libXCTestSwiftSupport.dylib as of
// Xcode 12.5:
// https://forums.swift.org/t/why-xcode-12-5b-cannot-find-xctassertequal-in-scope-in-playground/44411
val developerDir = compilerArgs.get().extractDeveloperDir() ?: return@all
compilerArgs.add("-I$developerDir/usr/lib")
}

tasks.withType(LinkMachOBundle::class).all {
// Include the ${DEVELOPER_DIR}/usr/lib as we also need to use libXCTestSwiftSupport.dylib as of
// Xcode 12.5:
// https://forums.swift.org/t/why-xcode-12-5b-cannot-find-xctassertequal-in-scope-in-playground/44411
val developerDir = linkerArgs.get().extractDeveloperDir() ?: return@all
linkerArgs.add("-L$developerDir/usr/lib")
tasks.withType(LinkMachOBundle::class).all {
// Include the ${DEVELOPER_DIR}/usr/lib as we also need to use libXCTestSwiftSupport.dylib as of
// Xcode 12.5:
// https://forums.swift.org/t/why-xcode-12-5b-cannot-find-xctassertequal-in-scope-in-playground/44411
val developerDir = linkerArgs.get().extractDeveloperDir() ?: return@all
linkerArgs.add("-L$developerDir/usr/lib")
}
}
}

Expand Down
25 changes: 25 additions & 0 deletions wire-tests-swift/manifest/module_one/SwiftModuleOneType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Code generated by Wire protocol buffer compiler, do not edit.
// Source: squareup.protos.kotlin.swift_modules.SwiftModuleOneType in swift_module_one.proto
import Foundation
import Wire

public enum SwiftModuleOneType : UInt32, CaseIterable, ProtoEnum {

case DO_NOT_USE = 0
case ONE = 1
case TWO = 2

public var description: String {
switch self {
case .DO_NOT_USE: return "DO_NOT_USE"
case .ONE: return "ONE"
case .TWO: return "TWO"
}
}

}

#if swift(>=5.5)
extension SwiftModuleOneType : Sendable {
}
#endif
15 changes: 15 additions & 0 deletions wire-tests-swift/manifest/module_one/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
plugins {
id("swift-library")
id("xcode")
id("xctest")
}

library {
dependencies {
api(projects.wireRuntimeSwift)
}

module.set("module_one")

source.from(file("."))
}
190 changes: 190 additions & 0 deletions wire-tests-swift/manifest/module_three/SwiftModuleThreeMessage.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
// Code generated by Wire protocol buffer compiler, do not edit.
// Source: squareup.protos.kotlin.swift_modules.SwiftModuleThreeMessage in swift_module_three.proto
import Foundation
import Wire
import module_one

public struct SwiftModuleThreeMessage {

public var name: String?
public var unknownFields: Foundation.Data = .init()

public init(configure: (inout Self) -> Swift.Void = { _ in }) {
configure(&self)
}

}

#if WIRE_INCLUDE_MEMBERWISE_INITIALIZER
extension SwiftModuleThreeMessage {

@_disfavoredOverload
@available(*, deprecated)
public init(name: Swift.String? = nil) {
self.name = name
}

}
#endif

#if !WIRE_REMOVE_EQUATABLE
extension SwiftModuleThreeMessage : Equatable {
}
#endif

#if !WIRE_REMOVE_HASHABLE
extension SwiftModuleThreeMessage : Hashable {
}
#endif

#if swift(>=5.5)
extension SwiftModuleThreeMessage : Sendable {
}
#endif

extension SwiftModuleThreeMessage : ProtoMessage {

public static func protoMessageTypeURL() -> Swift.String {
return "type.googleapis.com/squareup.protos.kotlin.swift_modules.SwiftModuleThreeMessage"
}

}

extension SwiftModuleThreeMessage : Proto2Codable {

public init(from protoReader: Wire.ProtoReader) throws {
var name: Swift.String? = nil

let token = try protoReader.beginMessage()
while let tag = try protoReader.nextTag(token: token) {
switch tag {
case 1: name = try protoReader.decode(Swift.String.self)
default: try protoReader.readUnknownField(tag: tag)
}
}
self.unknownFields = try protoReader.endMessage(token: token)

self.name = name
}

public func encode(to protoWriter: Wire.ProtoWriter) throws {
try protoWriter.encode(tag: 1, value: self.name)
try protoWriter.writeUnknownFields(unknownFields)
}

}

#if !WIRE_REMOVE_CODABLE
extension SwiftModuleThreeMessage : Codable {

public init(from decoder: Swift.Decoder) throws {
let container = try decoder.container(keyedBy: Wire.StringLiteralCodingKeys.self)
self.name = try container.decodeIfPresent(Swift.String.self, forKey: "name")
}

public func encode(to encoder: Swift.Encoder) throws {
var container = encoder.container(keyedBy: Wire.StringLiteralCodingKeys.self)

try container.encodeIfPresent(self.name, forKey: "name")
}

}
#endif

/**
* Subtypes within SwiftModuleThreeMessage
*/
extension SwiftModuleThreeMessage {

public struct NestedMessage {

public var map_string_types: [Swift.String : module_one.SwiftModuleOneType] = [:]
public var unknownFields: Foundation.Data = .init()

public init(configure: (inout Self) -> Swift.Void = { _ in }) {
configure(&self)
}

}

}

#if WIRE_INCLUDE_MEMBERWISE_INITIALIZER
extension SwiftModuleThreeMessage.NestedMessage {

@_disfavoredOverload
@available(*, deprecated)
public init(map_string_types: [Swift.String : module_one.SwiftModuleOneType] = [:]) {
self.map_string_types = map_string_types
}

}
#endif

#if !WIRE_REMOVE_EQUATABLE
extension SwiftModuleThreeMessage.NestedMessage : Equatable {
}
#endif

#if !WIRE_REMOVE_HASHABLE
extension SwiftModuleThreeMessage.NestedMessage : Hashable {
}
#endif

#if swift(>=5.5)
extension SwiftModuleThreeMessage.NestedMessage : Sendable {
}
#endif

extension SwiftModuleThreeMessage.NestedMessage : ProtoMessage {

public static func protoMessageTypeURL() -> Swift.String {
return "type.googleapis.com/squareup.protos.kotlin.swift_modules.SwiftModuleThreeMessage.NestedMessage"
}

}

extension SwiftModuleThreeMessage.NestedMessage : Proto2Codable {

public init(from protoReader: Wire.ProtoReader) throws {
var map_string_types: [Swift.String : module_one.SwiftModuleOneType] = [:]

let token = try protoReader.beginMessage()
while let tag = try protoReader.nextTag(token: token) {
switch tag {
case 2: try protoReader.decode(into: &map_string_types)
default: try protoReader.readUnknownField(tag: tag)
}
}
self.unknownFields = try protoReader.endMessage(token: token)

self.map_string_types = map_string_types
}

public func encode(to protoWriter: Wire.ProtoWriter) throws {
try protoWriter.encode(tag: 2, value: self.map_string_types)
try protoWriter.writeUnknownFields(unknownFields)
}

}

#if !WIRE_REMOVE_CODABLE
extension SwiftModuleThreeMessage.NestedMessage : Codable {

public init(from decoder: Swift.Decoder) throws {
let container = try decoder.container(keyedBy: Wire.StringLiteralCodingKeys.self)
self.map_string_types = try container.decodeProtoMap([Swift.String : module_one.SwiftModuleOneType].self, firstOfKeys: "mapStringTypes", "map_string_types")
}

public func encode(to encoder: Swift.Encoder) throws {
var container = encoder.container(keyedBy: Wire.StringLiteralCodingKeys.self)
let preferCamelCase = encoder.protoKeyNameEncodingStrategy == .camelCase
let includeDefaults = encoder.protoDefaultValuesEncodingStrategy == .include

if includeDefaults || !self.map_string_types.isEmpty {
try container.encodeProtoMap(self.map_string_types, forKey: preferCamelCase ? "mapStringTypes" : "map_string_types")
}
}

}
#endif
Loading

0 comments on commit 126c5f4

Please sign in to comment.