Skip to content

Commit

Permalink
Add keyword escaping in resources name (#131)
Browse files Browse the repository at this point in the history
  • Loading branch information
subdan authored Nov 22, 2021
1 parent e48f5ba commit 82c3379
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 30 deletions.
18 changes: 18 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@
"version": "1.0.1"
}
},
{
"package": "swift-custom-dump",
"repositoryURL": "https://github.com/pointfreeco/swift-custom-dump",
"state": {
"branch": null,
"revision": "21f8fdbb3226e5e28a1a2fffac3e0f3deec34bf0",
"version": "0.2.1"
}
},
{
"package": "swift-log",
"repositoryURL": "https://github.com/apple/swift-log.git",
Expand All @@ -64,6 +73,15 @@
"version": "8.5.0"
}
},
{
"package": "xctest-dynamic-overlay",
"repositoryURL": "https://github.com/pointfreeco/xctest-dynamic-overlay",
"state": {
"branch": null,
"revision": "50a70a9d3583fe228ce672e8923010c8df2deddd",
"version": "0.2.1"
}
},
{
"package": "Yams",
"repositoryURL": "https://github.com/jpsim/Yams.git",
Expand Down
3 changes: 2 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ let package = Package(
.package(url: "https://github.com/apple/swift-log.git", from: "1.4.0"),
.package(url: "https://github.com/stencilproject/Stencil.git", from: "0.14.2"),
.package(url: "https://github.com/tuist/XcodeProj.git", from: "8.5.0"),
.package(url: "https://github.com/pointfreeco/swift-custom-dump", from: "0.2.1"),
],
targets: [

Expand Down Expand Up @@ -65,7 +66,7 @@ let package = Package(
),
.testTarget(
name: "XcodeExportTests",
dependencies: ["XcodeExport"]
dependencies: ["XcodeExport", .product(name: "CustomDump", package: "swift-custom-dump")]
),
.testTarget(
name: "AndroidExportTests",
Expand Down
10 changes: 5 additions & 5 deletions Sources/XcodeExport/XcodeColorExporter.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation
import FigmaExportCore

final public class XcodeColorExporter {
final public class XcodeColorExporter: XcodeExporterBase {

private let output: XcodeColorsOutput

Expand Down Expand Up @@ -122,7 +122,7 @@ final public class XcodeColorExporter {
let strings = colorPairs.map { colorPair -> String in
let bundle = output.assetsInMainBundle ? "" : ", bundle: BundleProvider.bundle"
let named = groupUsingNamespace ? "\"\(colorPair.light.originalName)\"" : "#function"
return " static var \(colorPair.light.name): Color { Color(\(named)\(bundle)) }"
return " static var \(normalizeName(colorPair.light.name)): Color { Color(\(named)\(bundle)) }"
}

return """
Expand Down Expand Up @@ -151,12 +151,12 @@ final public class XcodeColorExporter {
let bundle = output.assetsInMainBundle ? "" : ", in: BundleProvider.bundle, compatibleWith: nil"
let prefix = objcAttribute ? "@objc " : ""
let named = groupUsingNamespace ? "\"\(colorPair.light.originalName)\"" : "#function"
content = " \(prefix)static var \(colorPair.light.name): UIColor { UIColor(named: \(named)\(bundle))! }"
content = " \(prefix)static var \(normalizeName(colorPair.light.name)): UIColor { UIColor(named: \(named)\(bundle))! }"
} else {
let lightComponents = colorPair.light.toRgbComponents()
if let darkComponents = colorPair.dark?.toRgbComponents() {
content = """
\(objcAttribute ? "@objc " : "")static var \(colorPair.light.name): UIColor {
\(objcAttribute ? "@objc " : "")static var \(normalizeName(colorPair.light.name)): UIColor {
if #available(iOS 13.0, *) {
return UIColor { traitCollection -> UIColor in
if traitCollection.userInterfaceStyle == .dark {
Expand All @@ -172,7 +172,7 @@ final public class XcodeColorExporter {
"""
} else {
content = """
\(objcAttribute ? "@objc " : "")static var \(colorPair.light.name): UIColor {
\(objcAttribute ? "@objc " : "")static var \(normalizeName(colorPair.light.name)): UIColor {
return UIColor(red: \(lightComponents.red), green: \(lightComponents.green), blue: \(lightComponents.blue), alpha: \(lightComponents.alpha))
}
"""
Expand Down
21 changes: 21 additions & 0 deletions Sources/XcodeExport/XcodeExporterBase.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
public class XcodeExporterBase {

private let declarationKeywords = ["associatedtype", "class", "deinit", "enum", "extension", "fileprivate", "func", "import", "init", "inout", "internal", "let", "open", "operator", "private", "precedencegroup", "protocol", "public", "rethrows", "static", "struct", "subscript", "typealias", "var"]

private let statementKeywords = ["break", "case", "catch", "continue", "default", "defer", "do", "else", "fallthrough", "for", "guard", "if", "in", "repeat", "return", "throw", "switch", "where", "while"]

private let expressionsKeywords = ["Any", "as", "catch", "false", "is", "nil", "rethrows", "self", "Self", "super", "throw", "throws", "true", "try"]

private let otherKeywords = ["associativity", "convenience", "didSet", "dynamic", "final", "get", "indirect", "infix", "lazy", "left", "mutating", "none", "nonmutating", "optional", "override", "postfix", "precedence", "prefix", "Protocol", "required", "right", "set", "some", "Type", "unowned", "weak", "willSet"]

func normalizeName(_ name: String) -> String {
let keyword = (declarationKeywords + statementKeywords + expressionsKeywords + otherKeywords).first { keyword in
name == keyword
}
if let keyword = keyword {
return "`\(keyword)`"
} else {
return name
}
}
}
2 changes: 1 addition & 1 deletion Sources/XcodeExport/XcodeIconsExporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ final public class XcodeIconsExporter: XcodeImagesExporterBase {
}

// Generate extensions
let imageNames = icons.map { $0.light.name }
let imageNames = icons.map { normalizeName($0.light.name) }
let extensionFiles = try generateExtensions(names: imageNames, append: append)

return [contentsFile] + imageAssetsFiles + extensionFiles
Expand Down
2 changes: 1 addition & 1 deletion Sources/XcodeExport/XcodeImagesExporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ final public class XcodeImagesExporter: XcodeImagesExporterBase {
}

// Generate extensions
let imageNames = assets.map { $0.light.name }
let imageNames = assets.map { normalizeName($0.light.name) }
let extensionFiles = try generateExtensions(names: imageNames, append: append)

return [contentsFile] + imageAssetsFiles + extensionFiles
Expand Down
2 changes: 1 addition & 1 deletion Sources/XcodeExport/XcodeImagesExporterBase.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import FigmaExportCore
import Foundation

public class XcodeImagesExporterBase {
public class XcodeImagesExporterBase: XcodeExporterBase {

let output: XcodeImagesOutput

Expand Down
43 changes: 36 additions & 7 deletions Tests/XcodeExportTests/XcodeColorExporterTests.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import XCTest
import FigmaExportCore
@testable import XcodeExport
import CustomDump

final class XcodeColorExporterTests: XCTestCase {

Expand Down Expand Up @@ -28,6 +29,8 @@ final class XcodeColorExporterTests: XCTestCase {
light: color3,
dark: nil)

private let colorWithKeyword = AssetPair<Color>(light: Color(name: "class", platform: .ios, red: 1, green: 1, blue: 1, alpha: 1), dark: nil)

// MARK: - Setup

override func setUp() {
Expand Down Expand Up @@ -74,7 +77,7 @@ final class XcodeColorExporterTests: XCTestCase {
}
"""
XCTAssertEqual(generatedCode, referenceCode)
XCTAssertNoDifference(generatedCode, referenceCode)
}

func testExport_with_assets() {
Expand Down Expand Up @@ -103,7 +106,7 @@ final class XcodeColorExporterTests: XCTestCase {
}
"""
XCTAssertEqual(generatedCode, referenceCode)
XCTAssertNoDifference(generatedCode, referenceCode)
}

func testExport_with_objc() {
Expand Down Expand Up @@ -137,7 +140,7 @@ final class XcodeColorExporterTests: XCTestCase {
}
"""
XCTAssertEqual(generatedCode, referenceCode)
XCTAssertNoDifference(generatedCode, referenceCode)
}

func testExport_with_assets_in_separate_bundle() {
Expand Down Expand Up @@ -170,7 +173,7 @@ final class XcodeColorExporterTests: XCTestCase {
}
"""
XCTAssertEqual(generatedCode, referenceCode)
XCTAssertNoDifference(generatedCode, referenceCode)
}

func testExport_with_assets_in_swift_package() {
Expand Down Expand Up @@ -203,7 +206,7 @@ final class XcodeColorExporterTests: XCTestCase {
}
"""
XCTAssertEqual(generatedCode, referenceCode)
XCTAssertNoDifference(generatedCode, referenceCode)
}

func testExport_swiftui() {
Expand Down Expand Up @@ -232,7 +235,7 @@ final class XcodeColorExporterTests: XCTestCase {
}
"""
XCTAssertEqual(generatedCode, referenceCode)
XCTAssertNoDifference(generatedCode, referenceCode)
}

func testExport_withProvidesNamespace() {
Expand Down Expand Up @@ -265,6 +268,32 @@ final class XcodeColorExporterTests: XCTestCase {
}
"""
XCTAssertEqual(generatedCode, referenceCode)
XCTAssertNoDifference(generatedCode, referenceCode)
}

func testExportWhenNameIsSwiftKeyword() {
let output = XcodeColorsOutput(assetsColorsURL: nil, assetsInMainBundle: true, colorSwiftURL: colorsFile)
let exporter = XcodeColorExporter(output: output)

let result = exporter.export(colorPairs: [colorWithKeyword])
XCTAssertEqual(result.count, 1)

let content = result[0].data
XCTAssertNotNil(content)

let generatedCode = String(data: content!, encoding: .utf8)
let referenceCode = """
\(header)
import UIKit
public extension UIColor {
static var `class`: UIColor {
return UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha: 1.000)
}
}
"""
XCTAssertNoDifference(generatedCode, referenceCode)
}
}
Loading

0 comments on commit 82c3379

Please sign in to comment.