Upgrade to Pro — share decks privately, control downloads, hide ads and more …

R.swift to Asset Symbols

417.72KI
September 26, 2023

R.swift to Asset Symbols

417.72KI

September 26, 2023
Tweet

More Decks by 417.72KI

Other Decks in Programming

Transcript

  1. .FTXJGU let name = "(redacted)" let twitter = "417_72ki" let

    github = "417-72KI" let company = "(redacted)" var products = [ "MockUserDefaults", "MultipartFormDataParser", "BuildConfig.swift", "SSGH", ] var contributing = [ "Danger-Swift", "octokit.swift", "etc..." ]
  2. ରԠࡦ A3TXJGU3FTPVSDFTAΛ໌ࣔ͢Δ import SwiftUI import RswiftResources struct Item { var

    image: ImageResource } struct ItemView: View { var item: Item var body: some View { VStack { Image(item.image) } } } #if DEBUG struct ItemView_Previews: PreviewProvider { static var previews: some View { Group { ItemView(item: .init(image: R.image.foo)) // Cannot convert value of type } } } #endif
  3. ରԠࡦ A3TXJGU3FTPVSDFTAΛ໌ࣔ͢Δ import SwiftUI import RswiftResources struct Item { var

    image: RswiftResources.ImageResource } struct ItemView: View { var item: Item var body: some View { VStack { Image(item.image) } } } #if DEBUG struct ItemView_Previews: PreviewProvider { static var previews: some View { Group { ItemView(item: .init(image: R.image.foo)) // no error } } } #endif
  4. ରԠࡦ 3ʓʓͷݺͼग़͠Λ"TTFU4ZNCPMTʹࠩ͠ସ͑Δ import SwiftUI import RswiftResources struct Item { var

    image: ImageResource } struct ItemView: View { var item: Item var body: some View { VStack { Image(item.image) } } } #if DEBUG struct ItemView_Previews: PreviewProvider { static var previews: some View { Group { ItemView(item: .init(image: R.image.foo)) // Cannot convert value of type } } } #endif
  5. ରԠࡦ 3ʓʓͷݺͼग़͠Λ"TTFU4ZNCPMTʹࠩ͠ସ͑Δ import SwiftUI import RswiftResources struct Item { var

    image: ImageResource } struct ItemView: View { var item: Item var body: some View { VStack { Image(item.image) } } } #if DEBUG struct ItemView_Previews: PreviewProvider { static var previews: some View { Group { ItemView(item: .init(image: .foo)) // no error } } } #endif
  6. ରԠࡦ 3ʓʓͷݺͼग़͠Λ"TTFU4ZNCPMTʹࠩ͠ସ͑Δ import SwiftUI struct Item { var image: ImageResource

    } struct ItemView: View { var item: Item var body: some View { VStack { Image(item.image) } } } #if DEBUG struct ItemView_Previews: PreviewProvider { static var previews: some View { Group { ItemView(item: .init(image: .foo)) // no error } } } #endif
  7. 3TXJGUͰݺͼग़ͤΔόϦΤʔγϣϯ // Image(UIKit) R.image.foo() UIImage(resource: R.image.foo) // Image(SwiftUI) Image(R.image.foo) Image(uiImage:

    R.image.foo()!) Image(uiImage: UIImage(resource: R.image.foo)!) // Color(UIKit) R.color.primary() UIColor(resource: R.color.primary) //Color(SwiftUI) Color(R.color.primary) Color(uiColor: R.color.primary()!) Color(uiColor: UIColor(resource: R.color.primary)!)
  8. 4XJGU4ZOUBYͰ΍Γ͍ͨ͜ͱ w 3JNBHFGPP ΍6**NBHF SFTPVSDF3JNBHFGPP Λ 6**NBHF SFTPVSDFGPP ʹม׵͢Δ w

    *NBHF 3JNBHFGPP ౳Λ*NBHF GPP ʹม׵͢Δ w 3DPMPSGPP ΍6*$PMPS SFTPVSDF3DPMPSGPP Λ 6*$PMPS SFTPVSDFGPP ʹม׵͢Δ w $PMPS 3DPMPSGPP ౳Λ$PMPS GPP ʹม׵͢Δ
  9. ΍Δ͜ͱ w ύλʔϯຖʹରԠͨ͠ม׵ॲཧΛ࣮૷͢Δ w 3JNBHFGPP 6**NBHF SFTPVSDFGPP  w 3JNBHFGPP

    6**NBHF SFTPVSDFGPP  w 6**NBHF SFTPVSDF3JNBHFGPP 6**NBHF SFTPVSDFGPP  w 6**NBHF SFTPVSDF3JNBHFGPP 6**NBHF SFTPVSDFGPP  w *NBHF 3JNBHFGPP *NBHF GPP  w *NBHF VJ*NBHF3JNBHFGPP  *NBHF GPP  w *NBHF VJ*NBHF6**NBHF SFTPVSDF3JNBHFGPP  *NBHF GPP
  10. ΍Δ͜ͱ w ύλʔϯຖʹରԠͨ͠ม׵ॲཧ3FXSJUFSΛ࣮૷ͯ͠࠶ؼతʹݺͼग़͢ w 3JNBHFGPP 3JNBHFGPP 6**NBHF SFTPVSDFGPP  w

    6**NBHF SFTPVSDF3JNBHFGPP 6**NBHF SFTPVSDF3JNBHFGPP  6**NBHF SFTPVSDFGPP  w *NBHF 3JNBHFGPP *NBHF GPP  w *NBHF VJ*NBHF3JNBHFGPP  *NBHF VJ*NBHF6**NBHF SFTPVSDF 3JNBHFGPP  *NBHF GPP
  11. 3JNBHFGPP 6**NBHF SFTPVSDFGPP final class RswiftResourceRewriter: SyntaxRewriter { private let

    rewritableAssets = [ "image": "UIImage", "color": "UIColor" ] override func visit(_ node: FunctionCallExprSyntax) -> ExprSyntax { if let base = node.calledExpression.as(MemberAccessExprSyntax.self), let expr = visit(base).as(MemberAccessExprSyntax.self), base != expr, let assetType = base.base?.as(MemberAccessExprSyntax.self)?.declName.baseName.text, let convertedType = rewritableAssets[assetType] { // return `UIImage(resource: .expr)` or `UIColor(resource: .expr)` syntax } }
  12. 3JNBHFGPP 6**NBHF SFTPVSDFGPP 3JNBHFGPPGPP override func visit(_ node: MemberAccessExprSyntax) ->

    ExprSyntax { if let base = node.base?.as(MemberAccessExprSyntax.self), base.base?.as(DeclReferenceExprSyntax.self)?.baseName.text == "R" { let resourceName = node.declName.baseName.text if rewritableAssets.keys.contains(base.declName.baseName.text) { return ExprSyntax( MemberAccessExprSyntax( leadingTrivia: node.leadingTrivia, period: .periodToken(), name: .identifier(resourceName.camelized), trailingTrivia: node.trailingTrivia ) ) } } return super.visit(node) }
  13. 3JNBHFGPP 6**NBHF SFTPVSDFGPP 3JNBHFGPP 3JNBHFGPP override func visit(_ token: ForceUnwrapExprSyntax)

    -> ExprSyntax { if let expr = token.expression.as(FunctionCallExprSyntax.self), let converted = visit(expr).as(FunctionCallExprSyntax.self), expr != converted { return ExprSyntax(converted) } return super.visit(token) }
  14. 6**NBHFΛ௚઀ม׵ final class UIImageRewriter: SyntaxRewriter { private let typeName =

    "UIImage" override func visit(_ node: FunctionCallExprSyntax) -> ExprSyntax { if case typeName = node.calledExpression.as(DeclReferenceExprSyntax.self)?.baseName.text, let argument = node.arguments.first, argument.label?.text == "resource" { let newArgument = rswiftResourceRewriter.visit(argument) return ExprSyntax(node.with(\.arguments, [newArgument])) } if let member = node.calledExpression.as(MemberAccessExprSyntax.self), case "init" = member.declName.baseName.text, let argument = node.arguments.first, argument.label?.text == "resource" { let newArgument = rswiftResourceRewriter.visit(argument) return ExprSyntax(node.with(\.arguments, [newArgument])) } return super.visit(node) }
  15. 6**NBHFΛ௚઀ม׵ 6**NBHF SFTPVSDF3JNBHFGPP 6**NBHF SFTPVSDFGPP final class UIImageRewriter: SyntaxRewriter {

    private let typeName = "UIImage" override func visit(_ node: FunctionCallExprSyntax) -> ExprSyntax { if case typeName = node.calledExpression.as(DeclReferenceExprSyntax.self)?.baseName.text, let argument = node.arguments.first, argument.label?.text == "resource" { let newArgument = rswiftResourceRewriter.visit(argument) return ExprSyntax(node.with(\.arguments, [newArgument])) } if let member = node.calledExpression.as(MemberAccessExprSyntax.self), case "init" = member.declName.baseName.text, let argument = node.arguments.first, argument.label?.text == "resource" { let newArgument = rswiftResourceRewriter.visit(argument) return ExprSyntax(node.with(\.arguments, [newArgument])) } return super.visit(node) }
  16. 6**NBHFΛ௚઀ม׵ JOJU SFTPVSDF3JNBHFGPP 6**NBHF SFTPVSDFGPP final class UIImageRewriter: SyntaxRewriter {

    private let typeName = "UIImage" override func visit(_ node: FunctionCallExprSyntax) -> ExprSyntax { if case typeName = node.calledExpression.as(DeclReferenceExprSyntax.self)?.baseName.text, let argument = node.arguments.first, argument.label?.text == "resource" { let newArgument = rswiftResourceRewriter.visit(argument) return ExprSyntax(node.with(\.arguments, [newArgument])) } if let member = node.calledExpression.as(MemberAccessExprSyntax.self), case "init" = member.declName.baseName.text, let argument = node.arguments.first, argument.label?.text == "resource" { let newArgument = rswiftResourceRewriter.visit(argument) return ExprSyntax(node.with(\.arguments, [newArgument])) } return super.visit(node) }