Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] 1. Default value by InitializerClauseSyntax 2. Add GroupedDefault for multiple bindings 3. Some builtin type infer #70

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

SouHanaQiao
Copy link

This is an amazing project about swift macros.

In the past, some implementations I needed could only be achieved by customizing official codecs such as JSONDecoder/JSONEncoder. I want to make a small contribution to the improvement of this project. For example, the following features provide discussion.

1. Default value by InitializerClauseSyntax

Provide default value by InitializerClauseSyntax (decl.binding.initializer?.value).

Example:

struct Example {
    @Default(10)
    let int: Int   /// defaul value is 10
    var int2: Int = 10 /// default value is 10
    @Default(10)
    var int3: Int = 20 /// default value is 10 when apply `Default` attribute
    var int4: Int = 4, int5: Int = 5 /// `int4` default value is 4, `int5` default value is 5
}

2. Add GroupedDefault for multiple bindings

I add a GroupedDefault member attribute like Default but attach to multiple bindings:

@attached(peer)
@available(swift 5.9)
public macro GroupedDefault<each T>(_ defaults: repeat each T) =
    #externalMacro(module: "MacroPlugin", type: "GroupedDefault")

Using Example:

struct Student {
    @GroupedDefault("Simon", 22)
    let name: String, age: Int
    @Default(60)
    let grade: Int
}

3. We can infer some types like Int, Bool, String, Float, Double with var age = 10, var string = "hello"refer to MemberwiseInit project.

struct SomeInferTest {
    var int = 10 /// Int
    var float = 0.1 as Float /// Float
    var double = 0.11 /// Double
    var string = "hello" /// String
    var bool = Bool() /// Bool
    var date = Date() /// Date
}

So we can add default value like this:

struct Student {
    var name = "unknown", age = 0
    var grade = 60
}

Same as:

struct Student {
    var name: String = "unknown", age: Int = 0
    var grade: Int = 60
}

and

struct Student {
    @GroupedDefault("unknown", 0)
    let name: String, age: Int
    @Default(60)
    let grade: Int
}

4.Just generate one init function.

@MemberInit
struct Student {
    let name: String, age: Int
    @Default(60)
    let grade: Int
    var isBoy: Bool = false 
    var isGirl: Bool = true
}

Generate 4 init function in past like this:

init(name: String, age: Int, grade: Int = 60) {
    self.name = name
    self.age = age
    self.grade = grade
}

init(name: String, age: Int, grade: Int = 60, isBoy: Bool) {
    self.name = name
    self.age = age
    self.grade = grade
    self.isBoy = isBoy
}

init(name: String, age: Int, grade: Int = 60, isGirl: Bool) {
    self.name = name
    self.age = age
    self.grade = grade
    self.isGirl = isGirl
}

init(name: String, age: Int, grade: Int = 60, isBoy: Bool, isGirl: Bool) {
    self.name = name
    self.age = age
    self.grade = grade
    self.isBoy = isBoy
    self.isGirl = isGirl
}

But now expand 1 init function like this:

init(name: String, age: Int, grade: Int = 60, isBoy: Bool = false, isGirl: Bool = true) {
    self.name = name
    self.age = age
    self.grade = grade
    self.isBoy = isBoy
    self.isGirl = isGirl
}

2. Add `GroupedDefault` member attribute to multiple bindings declaration.
3. Just generate one init function.
@soumyamahunt
Copy link
Contributor

Thanks @SouHanaQiao for this contribution. Please create separate PRs for each feature contribution, this will help in reviewing PRs and also auto changelog generation happens per PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants