Skip to content

Conversation

@davdroman
Copy link
Contributor

@davdroman davdroman commented Nov 26, 2025

  • Introduced the new @DecodingDefault, @EncodingDefault, and @CodingDefault peer macros (Sources/ReerCodable/MacroDeclarations/DefaultValue.swift) with runtime + macro-expansion coverage (Tests/ReerCodableTests/DefaultValueTests.swift, MacroExpandTests.swift) and wired them through PropertyInfo/TypeInfo so synthesized decoders/encoders automatically apply explicit fallbacks across base64/custom/flat code paths.
  • Added repo plumbing that was missing on main: .editorconfig, a refreshed CI workflow (matrixed Linux builds, skip support, weekly runs), and expanded Package.swift/Package.resolved with swift-macro-testing + compatible swift-syntax constraints so we can exercise macro expansions with MacroTesting.
  • Stabilized @CodingCase output by tracking per-case matchOrder, updated processEnumCases to return ordered arrays, and ensured the decoder walks non-string matchers before string ones—macro expansion snapshots now match deterministically.

@davdroman davdroman changed the title Default value macros Add default-value macros, deterministic enum handling, and CI Nov 26, 2025
@davdroman davdroman marked this pull request as draft November 26, 2025 22:39
@Asura19
Copy link
Member

Asura19 commented Nov 27, 2025

Thanks for your contribution!
This is so exciting because I also wanted to add the Default Macro yesterday. My motivation is as follows:
As you know, in ReerCodable, default values can be added through assignment expressions. However, if the property is defined as let, it cannot be reassigned. Therefore, I want to solve this issue by adding a Default Macro.
CleanShot 2025-11-27 at 11 35 17@2x

Next, let's discuss this pull request:

  1. I found you have removed the jobs on Linux, I am not very familiar with GitHub CI, does matrixed Linux builds mean it can still perform continuous integration on Linux?
  2. ReerCodable use some new feature of swift-syntax, so 600.0.0 version at least
.package(url: "https://github.com/swiftlang/swift-syntax", "600.0.0"..<"603.0.0")
  1. Expect test code of the three macros for let property
  2. When both the default macro and the assignment expression exist at the same time, it is expected that the macro will generate a warning to indicate that the assignment expression will not take effect.
@Codable
private struct CodingDefaultsModel: Equatable {
    @CodingDefault(["seed": 1]) // expect a warning here
    var metadata: [String: Int]? = [:]
}

I haven't carefully reviewed the modified code yet, and I will find time later to do in-depth research.

@davdroman
Copy link
Contributor Author

However, if the property is defined as let, it cannot be reassigned.

This was exactly my motivation as well.

  1. I found you have removed the jobs on Linux, I am not very familiar with GitHub CI, does matrixed Linux builds mean it can still perform continuous integration on Linux?

I was experiencing some issues with testing on Linux, I've now fixed those issues and restored testing on Linux.

2. ReerCodable use some new feature of swift-syntax, so 600.0.0 version at least

That's fine. In that case I suggest you bump the Package.swift version to 6.0 as well. Since Apple is no longer supporting Swift 5.x officially it's fair to bump. I've committed the bump too.

3. Expect test code of the three macros for let property

Good point. I've added those.

4. When both the default macro and the assignment expression exist at the same time, it is expected that the macro will generate a warning to indicate that the assignment expression will not take effect.

I'm not sure about this one. I think one might want to have different default values especially if generating a memberwise init e.g. for stubbing. Although rare, this could be a legitimate use case. And @CodableDefault is explicit enough that it's understood it applies to codability only.

@davdroman davdroman marked this pull request as ready for review November 27, 2025 11:04
@Asura19
Copy link
Member

Asura19 commented Nov 28, 2025

@davdroman Only one question left: I can not build test target, I've tried different computers, different versions of XCode, and clearing the cache, but it still fails.
CleanShot 2025-11-28 at 11 15 29@2x

I found that if I comment out the entire content of MacroExpandTests.swift, it can compile successfully.
Maybe it's some bug of XCode.

I haven't deeply explored macro expansion testing yet. The few test cases
I added previously were mainly for debugging purposes. I'm curious about
whether introducing MacroTesting would be beneficial in our case. Would
SwiftSyntaxMacrosTestSupport be sufficient for our testing needs, or are
there specific advantages to MacroTesting that I should consider?

I'd appreciate your insights on this.

@Asura19
Copy link
Member

Asura19 commented Dec 3, 2025

Let's ignore the compilation issues with the test target for now, merge this PR first, and then decide whether to introduce MacroTesting based on actual usage.

@Asura19 Asura19 merged commit 34fc36a into reers:main Dec 3, 2025
2 checks passed
@davdroman davdroman deleted the default-values branch December 3, 2025 10:43
@davdroman
Copy link
Contributor Author

davdroman commented Dec 3, 2025

Sorry it took me so long to respond.

I found that if I comment out the entire content of MacroExpandTests.swift, it can compile successfully.
Maybe it's some bug of XCode.

It's fixed here. #29

It's some sort of Swift Syntax error caused by the new prebuilts feature. Very annoying, but easy to fix.

Would
SwiftSyntaxMacrosTestSupport be sufficient for our testing needs, or are
there specific advantages to MacroTesting that I should consider?

I believe MacroTesting to be such an improvement over the bare SwiftSyntaxMacrosTestSupport that it should be part of every macro test suite everywhere. You can read more about the benefits here: https://www.pointfree.co/blog/posts/114-a-new-tool-for-testing-macros-in-swift (tldr: much better developer experience when writing macro expansion tests).

Point-Free have an impeccable track record shipping key libraries that fill massive gaps in the Swift ecosystem. I swear by their work and use one or multiple of their libraries in all my open source projects and at work.

@Asura19
Copy link
Member

Asura19 commented Dec 3, 2025

I've read the blog about MacroTesting, surprisingly, it can automatically complete the expansion!!! It is truly an amazing framework.

But I have temporarily removed MacroTesting for the following reason:

  • When parsing a package dependency for a certain project, it also pulls in the package dependencies of testTarget, even if they do not participate in compilation. This affects loading speed, especially in regions with network access restrictions to github. Therefore, I tend to: maintain the principle of minimal introduction unless it is absolutely necessary.

Later, if there is a need for a large number of macro expansion tests, I will consider referencing MacroTesting.

Additionally, I found that SPM could previously set testDependencies, but it was temporarily removed. If this feature is restored later, I will no longer have any concerns about introducing MacroTesting.

Point-Free is really great. I'll try some of their libraries in the future.

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