SwiftSyntax without the boilerplate

Overview

SwiftSyntaxSimplified

SwiftSyntax without the boilerplate.

Setup

Choose a version

This library uses a compound version number, with two parts separated by a dash -.

  • The first part is a standard three-part semantic version number X.Y.Z.
  • The second part is the version of SwiftSyntax that it is compatible with.

For example: 1.0.1-0.50300.0 is the 1.0.1 version compatible with the 0.503000.0 version of SwiftSyntax.

Add as a Swift Package Manager dependency

Update your Package.swift, replacing <version number> with the version you chose above.

Package(
    ...,
    dependencies: [
        ...,
        .package(
            name: "SwiftSyntaxSimplified",
            url: "https://github.com/Sunlace/swift-syntax-simplified.git",
            .exact("<version number>")
        ),
    ],
    targets: [
        ...,
        .target(
            ...,
            dependencies: [
                ...,
                .product(name: "SwiftSyntaxSimplified", package: "SwiftSyntaxSimplified"),
            ]
        ),
    ]
)

Import in your code

This library does not replace all the functionality of SwiftSyntax, so do not remove your existing imports of SwiftSyntax.

import SwiftSyntax
import SwiftSyntaxSimplified

Usage

Convert easily between typed and type-erased objects

SwiftSyntax has both typed and type-erased views of all Syntax objects, used throughout its API. With SwiftSyntaxSimplified, you can convert between them on demand.

For example, many of the SyntaxVisitor APIs pass typed arguments but expect type-erased return values:

override func visit(_ node: IfStmtSyntax) -> StmtSyntax {
    return node.withConditions(<conditions>).typeErased
}

Other APIs return type-erased values that must be converted to typed before anything useful can be done:

override func visit(_ node: OptionalChainingExprSyntax) -> ExprSyntax {
    switch node.expression.typed {
    case let stringLiteral as StringLiteralExprSyntax: <action>
    case let functionCall as FunctionCallExprSyntax: <action>
    ...
    }
}

Use the simplified factory methods

SwiftSyntax defines extremely verbose factory methods for creating syntax objects. With SwiftSyntaxSimplified, you can call the same methods that you would normally call, but with less boilerplate.

This:

SyntaxFactory.Simplified.makeFunctionCallExpr(
    calledExpression: <expression>,
    arguments: [
        SyntaxFactory.Simplified.makeTupleExprElement(
            expression:<expression>
        ),
        SyntaxFactory.Simplified.makeTupleExprElement(
            label: <token>,
            expression: <expression>
        ),
    ]
)

Instead of this:

SyntaxFactory.makeFunctionCallExpr(
    calledExpression: <expression>,
    leftParen: SyntaxFactory.makeLeftParenToken(),
    argumentList: SyntaxFactory.makeTupleExprElementList([
        SyntaxFactory.makeTupleExprElement(
            label: nil,
            colon: nil,
            expression: <expression>,
            trailingComma: SyntaxFactory.makeCommaToken()
        ),
        SyntaxFactory.makeTupleExprElement(
            label: <token>,
            colon: SyntaxFactory.makeColonToken(),
            expression: <expression>,
            trailingComma: nil
        )
    ]),
    rightParen: SyntaxFactory.makeRightParenToken(),
    trailingClosure: nil,
    additionalTrailingClosures: nil
)

Factory Method Simplifications

This library duplicates SyntaxFactory.make<X>(...) methods as SyntaxFactory.Simplified.make<X>(...)

For each duplicated method, it applies the following interface simplifications, in order. If no simplifications can be made, the method is not duplicated.

Steps

  1. If a method contains an Optional<TokenSyntax> parameter named trailing<X> that must always be a specific token or nil, depending on the position of the returned object in a list object (i.e. whether it is the last item in that list)
    • remove the parameter
    • duplicate the object definition <X>Syntax as SyntaxFactory.Simplified.<X>Syntax, with fields matching the SyntaxFactory.Simplified.make<X>(...) parameters (including all modifications)
    • return an instance of SyntaxFactory.Simplified.<X>Syntax instead of <X>Syntax.
  2. If a parameter is an Array<X> where X is a type that was duplicated in an above step
    • replace the parameter type Array<X> with Array<SyntaxFactory.Simplified.X>
  3. If a parameter is a TokenSyntax and must always be a specific token
    • remove the parameter
  4. If a parameter is an Optional<TokenSyntax> and must always be a specific token or nil:
    • replace the Optional<TokenSyntax> parameter type with Bool
    • prepend include to the parameter name
    • specify a default value of false
  5. If a parameter is a TokenSyntax and must always be one of a specific set of tokens
    • create a <X>Token enum to represent the options
    • replace the TokenSyntax parameter type with <X>Token>
  6. If a parameter is a Optional<TokenSyntax> and must always be one of a specific set of tokens or nil
    • create a <X>Token enum to represent the non-nil options
    • replace the Optional<TokenSyntax> parameter type with Optional<<X>Token>
  7. If a parameter is an Optional
    • specify a default value of nil
  8. If a parameter is an Array
    • specify a default value of []
  9. If a parameter is of a type that has a SyntaxFactory.Simplified.make<X>(...) method which, after modifications, has zero parameters:
    • remove the parameter
  10. If a parameter is of a type that has a SyntaxFactory.Simplified.make<X>(...) method which, after modifications, has one parameter:
    • replace the parameter type with the parameter type of the SyntaxFactory.Simplified.make<X>(...) method
    • append the parameter name of the SyntaxFactory.Simplified.make<X>(...) method to the parameter name
  11. If an object may be constructed in two different ways that both result in valid Swift
    • add a new parameter <Z> of type Bool where true corresponds to the more verbose option
    • specify a default value of false
  12. If a parameter must be a specific value if another parameter of type Optional<Y> is nil:
    • remove the parameter
    • create a new model object SyntaxFactory.Simplified.<Z>GroupSyntax
    • create a new SyntaxFactory.Simplified.make<Z>Group(...) method with:
      • a copy of the parameter
      • a copy of the other parameter, but with the non-Optional type <Y>
    • replace the other parameter's parameter type Optional<Y> with Optional<SyntaxFactory.Simplified.<Z>GroupSyntax>

Contributing

This library is incomplete, and contributions are welcome! We are actively reviewing PRs, and will merge any that:

  • adds new methods making the improvements described in the Philosphy section
  • fixes issues in the existing code

If you have ideas for other improvements, please open an issue or a PR. However, consistency across the API is our top concern, so any architectural changes should include equivalent changes to all existing code and, if appropriate, a new major version number.

Issues
  • Test

    Test

    Test

    opened by liambutler-lawrence 0
Releases(2.0.0-0.50300)
Eliminate your Core Data boilerplate code

SSDataKit There is a lot of boilerplate code required to write a Core Data application. This is annoying. In pretty much everything I've written since

Sam Soffes 457 Oct 2, 2021
100% Swift Simple Boilerplate Free Core Data Stack. NSPersistentContainer

DATAStack helps you to alleviate the Core Data boilerplate. Now you can go to your AppDelegate remove all the Core Data related code and replace it wi

Nes 217 Nov 21, 2021
A minimalistic, thread safe, non-boilerplate and super easy to use version of Active Record on Core Data. Simply all you need for doing Core Data. Swift flavour.

Skopelos A minimalistic, thread-safe, non-boilerplate and super easy to use version of Active Record on Core Data. Simply all you need for doing Core

Alberto De Bortoli 234 Nov 17, 2021
The easiest Future and Promises framework in Swift. No magic. No boilerplate.

Promis The easiest Future and Promises framework in Swift. No magic. No boilerplate. Overview While starting from the Objective-C implementation of Ju

Alberto De Bortoli 110 Jul 9, 2021
Boilerplate-free mocking framework for Swift!

Cuckoo Mock your Swift objects! Introduction Cuckoo was created due to lack of a proper Swift mocking framework. We built the DSL to be very similar t

Brightify 1.4k Nov 23, 2021
Meta-programming for Swift, stop writing boilerplate code.

Sourcery is a code generator for Swift language, built on top of Apple's own SwiftSyntax. It extends the language abstractions to allow you to generat

Krzysztof Zabłocki 6.3k Nov 26, 2021
Featureful iOS Boilerplate

Amaro Crush & Lovely's iOS boilerplate. Changelog Say what now? We want to hit the ground running. Xcode and the iOS ecosystem don't make that easy. E

Crush & Lovely 386 Jun 27, 2021
Animate in Xcode without code

Canvas is a project to simplify iOS development for both designers and developers. It had been difficult for designers to get hands on building the pr

null 5.3k Nov 11, 2021
Swifty TVML template manager with or without client-server

TVMLKitchen ?? ?? TVMLKitchen helps to manage your TVML with or without additional client-server. Requirements Swift3.0 tvOS 9.0+ Use 0.9.6 for Swift2

Toshihiro Suzuki 81 Dec 27, 2020
Ethereum Wallet Toolkit for iOS - You can implement an Ethereum wallet without a server and blockchain knowledge.

Introduction EtherWalletKit is an Ethereum Wallet Toolkit for iOS. I hope cryptocurrency and decentralized token economy become more widely adapted. H

Sung Woo Chang 112 Nov 17, 2021
Find memory issues & leaks in your iOS app without instruments

HeapInspector Find memory issues & leaks in your iOS app HeapInspector is a debug tool that monitors the memory heap with backtrace recording in your

Christian Menschel 1.8k Nov 11, 2021
Commit fully-formatted Objective-C as a team without even trying.

[ Space Commander] [ Space Commander] provides tools which enable a team of iOS developers to commit Objective-C code to a git repository using a unif

Square 1.1k Nov 10, 2021
Find common xib and storyboard-related problems without running your app or writing unit tests.

IBAnalyzer Find common xib and storyboard-related problems without running your app or writing unit tests. Usage Pass a path to your project to ibanal

Arek Holko 957 Oct 29, 2021
Retrieving InfoPlist without Jailbreaking on iOS Devices

⚠️ WARNING This project is no longer under maintenance. Since iOS 11 has removed some sensitive APIs, this project isn't working on it anymore. Goodby

Ying Zhong 1000 Nov 12, 2021
GitHub iOS client written in Swift using MVVM architecture with Router (without Rx and Interface Builder).

GitHubSearch GitHub iOS client written in Swift using MVVM architecture with Router (without Rx and Interface Builder). Features Searching for reposit

Eugene Karambirov 30 Nov 2, 2021
Create gradients and blur gradients without a single line of code

EZYGradientView is a different and unique take on creating gradients and gradients with blur on the iOS platform. The default CAGradientLayer implemen

Shashank Pali 381 Oct 25, 2021
PeekView supports peek, pop and preview actions for iOS devices without 3D Touch capibility

PeekView When implementing peek, pop and preview actions with 3D Touch, you may want to support such features for users accessing your app from older

Huong Do 123 Jun 19, 2021
Fast Swift Views layouting without auto layout. No magic, pure code, full control and blazing fast. Concise syntax, intuitive, readable & chainable. [iOS/macOS/tvOS/CALayer]

Extremely Fast views layouting without auto layout. No magic, pure code, full control and blazing fast. Concise syntax, intuitive, readable & chainabl

layoutBox 1.8k Nov 12, 2021
Will Powell 1.2k Nov 25, 2021
Automate box any value! Print log without any format control symbol! Change debug habit thoroughly!

LxDBAnything Automate box any value! Print log without any format control symbol! Change debug habit thoroughly! Installation You only need drag LxD

DeveloperLx 436 Nov 11, 2021
Mathias Köhnke 1.1k Nov 21, 2021
Valet lets you securely store data in the iOS, tvOS, or macOS Keychain without knowing a thing about how the Keychain works. It’s easy. We promise.

Valet Valet lets you securely store data in the iOS, tvOS, watchOS, or macOS Keychain without knowing a thing about how the Keychain works. It’s easy.

Square 3.7k Nov 23, 2021
A UICollectionViewLayout subclass that adds custom transitions/animations to the UICollectionView without effecting your existing code.

AnimatedCollectionViewLayout Normally a UICollectionView has no transition effects when you scroll from one item to another. There are lots of ways to

Jin Wang 4.3k Nov 17, 2021
Display Apple system-like self-hiding status alerts. It is well suited for notifying user without interrupting user flow in iOS-like way.

StatusAlert is being sponsored by the following tool; please help to support us by takin a look and signing up to a free trial. Dependency managers Fe

Yehor Miroshnychenko 825 Nov 12, 2021
A fully customisable subclass of the native UIControl which allows you to create beautiful buttons without writing any line of code.

A fully customisable subclass of the native UIControl which allows you to create beautiful buttons without writing any line of code. Preview You'll be

Lorenzo Greco 2.2k Nov 18, 2021
A fully customisable swift subclass on UIButton which allows you to create beautiful buttons without writing any line of code.

JSButton Demo $ pod try JSButton ...or clone this repo and build and run/test the JSButton project in Xcode to see JSButton in action. If you don't ha

Jogendra 11 Feb 25, 2019
CrownControl is a tiny accessory that makes scrolling through scrollable content possible without lifting your thumb.

CrownControl Overview Features Example Project Requirements Installation Usage Quick Usage Crown Attributes Scroll Axis Anchor Position Spin Direction

Daniel Huri 88 Jul 22, 2021
Tweak your iOS app without recompiling!

SwiftTweaks Adjust your iOS app on the fly without waiting to re-compile! Your users won’t see your animation study, Sketch comps, or prototypes. What

Khan Academy 1.3k Nov 14, 2021
An auto-layout base UITextView subclass which automatically grows with user input and can be constrained by maximal and minimal height - all without a single line of code

Deprecated This library is no longer maintained and is deprecated. The repository might be removed at any point in the future. MBAutoGrowingTextView A

Matej Balantič 126 Apr 16, 2021