Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Package.resolved
.build/
*.o
*.d
*.swiftdeps
*.swiftdeps*

# CocoaPods
#
Expand Down
3 changes: 2 additions & 1 deletion Examples/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ IPHONEOS_DEPLOYMENT_TARGET = '14.0'

GITHUB_REPOSITORY = ENV['GITHUB_REPOSITORY'] || 'SwiftyLab/MetaCodable'
GITHUB_SERVER_URL = ENV['GITHUB_SERVER_URL'] || 'https://github.com'
METACODABLE_DEV_BRANCH = ENV['GITHUB_HEAD_REF'] || ENV['GITHUB_REF_NAME']
GITHUB_HEAD_REF = ENV['GITHUB_HEAD_REF']
METACODABLE_DEV_BRANCH = GITHUB_HEAD_REF&.empty? ? ENV['GITHUB_REF_NAME'] : GITHUB_HEAD_REF
DEV_SOURCE = METACODABLE_DEV_BRANCH ? { :git => "#{GITHUB_SERVER_URL}/#{GITHUB_REPOSITORY}.git", :branch => METACODABLE_DEV_BRANCH } : { :path => "../" }

def add_metacodable
Expand Down
1 change: 1 addition & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ let package = Package(
name: "PluginCore",
dependencies: [
.product(name: "SwiftSyntax", package: "swift-syntax"),
.product(name: "SwiftOperators", package: "swift-syntax"),
.product(name: "SwiftDiagnostics", package: "swift-syntax"),
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
Expand Down
1 change: 1 addition & 0 deletions Package@swift-5.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ let package = Package(
name: "PluginCore",
dependencies: [
.product(name: "SwiftSyntax", package: "swift-syntax"),
.product(name: "SwiftOperators", package: "swift-syntax"),
.product(name: "SwiftDiagnostics", package: "swift-syntax"),
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
Expand Down
9 changes: 5 additions & 4 deletions Sources/PluginCore/Diagnostics/MetaCodableMessage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,11 @@ struct MetaCodableMessage: Error, DiagnosticMessage, FixItMessage {
message: String, id: MessageID
) -> MetaCodableMessage {
return .init(
macro: macro,
message: message,
messageID: id,
severity: .warning
macro: macro, message: message, messageID: id, severity: .warning
)
}
}

#if !canImport(SwiftSyntax600)
extension MetaCodableMessage: @unchecked Sendable {}
#endif
13 changes: 12 additions & 1 deletion Sources/PluginCore/Expansion/AttributeExpander.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,22 @@ struct AttributeExpander {
let decodable = variable.protocol(named: dProtocol, in: protocols)
let encodable = variable.protocol(named: eProtocol, in: protocols)

return [
var extensions = [
decoding(type: type, conformingTo: decodable, in: context),
encoding(type: type, conformingTo: encodable, in: context),
codingKeys(for: type, confirmingTo: protocols, in: context),
].compactMap { $0 }
for index in extensions.indices {
// attach available attributes from original declaration
// to generated expanded declaration
extensions[index].attributes = AttributeListSyntax {
for attr in options.availableAttributes {
.attribute(attr)
}
extensions[index].attributes
}
}
return extensions
}

/// Provides the `Decodable` extension declaration.
Expand Down
14 changes: 14 additions & 0 deletions Sources/PluginCore/Expansion/Options/Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ extension AttributeExpander {
/// The list of modifiers generator for
/// conformance implementation declarations.
let modifiersGenerator: DeclModifiersGenerator
/// The list of `@available` attributes attached to
/// original expanded declaration.
let availableAttributes: [AttributeSyntax]

/// Memberwise initialization generator with provided options.
///
Expand All @@ -29,6 +32,17 @@ extension AttributeExpander {
/// - Returns: The newly created options.
init(for decl: some DeclGroupSyntax) {
self.modifiersGenerator = .init(decl: decl)
self.availableAttributes = decl.attributes.compactMap { attribute in
switch attribute {
case .attribute(let attr):
guard
attr.attributeName.trimmed.description == "available"
else { fallthrough }
return attr
default:
return nil
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import SwiftOperators
import SwiftSyntax
import SwiftSyntaxMacros

Expand Down Expand Up @@ -117,7 +118,17 @@ struct BasicEnumCaseVariable: EnumCaseVariable {
let label = SwitchCaseLabelSyntax(
caseItems: .init {
for value in location.values {
let pattern = ExpressionPatternSyntax(expression: value)
let expr =
OperatorTable.standardOperators
.foldAll(value) { _ in }.as(ExprSyntax.self) ?? value
let pattern =
if let asExpr = expr.as(AsExprSyntax.self) {
ExpressionPatternSyntax(
expression: asExpr.expression.trimmed
)
} else {
ExpressionPatternSyntax(expression: expr)
}
SwitchCaseItemSyntax(pattern: pattern)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,10 @@ where Variable: PropertyVariable {
let containerVariable = ContainerVariable(
encodeContainer: encodeContainer, base: output.variable
)
node.register(variable: containerVariable, keyPath: keys)
node.register(
variable: containerVariable, keyPath: keys,
immutableEncodeContainer: true
)
self.node = node
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,17 @@ extension EnumSwitcherVariable {
let label = SwitchCaseLabelSyntax {
.init(pattern: pattern, whereClause: whereClause)
}
let caseSyntax = CodeBlockItemListSyntax {
preSyntax("\(value.encodeExprs.first!)")
generated.code.combined()
}

let generatedCode = generated.code.combined()
SwitchCaseSyntax(label: .case(label)) {
!caseSyntax.isEmpty ? caseSyntax : "break"
if !generatedCode.isEmpty {
CodeBlockItemListSyntax {
preSyntax("\(value.encodeExprs.first!)")
generatedCode
}
} else {
"break"
}
}
}
if `default` || !allEncodable || anyEncodeCondition {
Expand Down
Loading
Loading