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

R.swift to Asset Symbols

Avatar for 417.72KI 417.72KI
September 26, 2023

R.swift to Asset Symbols

Avatar for 417.72KI

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) }