Skip to content

Commit eecfef7

Browse files
committed
Push code
1 parent 9ed614c commit eecfef7

16 files changed

+1092
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,4 @@ fastlane/report.xml
6666
fastlane/Preview.html
6767
fastlane/screenshots/**/*.png
6868
fastlane/test_output
69+
SwiftUsing.xcodeproj

Example/File.swift

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
struct User {
3+
var name: String
4+
var age: Int
5+
}
6+
7+
struct Address {
8+
var street: String
9+
let city: String
10+
}
11+
12+
struct Friend {
13+
// using
14+
let user: User
15+
16+
// using
17+
var home: Address
18+
19+
var friendshipDate: Date
20+
}
21+
22+
// generated
23+
extension Friend {
24+
var name: String {
25+
get {
26+
return user.name
27+
}
28+
}
29+
var age: Int {
30+
get {
31+
return user.age
32+
}
33+
}
34+
}
35+
// generated
36+
extension Friend {
37+
var street: String {
38+
get {
39+
return home.street
40+
}
41+
set {
42+
home.street = newValue
43+
}
44+
}
45+
var city: String {
46+
get {
47+
return home.city
48+
}
49+
}
50+
}

Makefile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
INSTALL_PATH = /usr/local/bin/swiftusing
2+
3+
build:
4+
swift package update
5+
swift build -c release -Xswiftc -static-stdlib
6+
7+
install: build
8+
cp -f .build/release/swiftusing $(INSTALL_PATH)
9+
10+
clean:
11+
rm -rf .build
12+
13+
uninstall:
14+
rm -f $(INSTALL_PATH)
15+
16+
xcode:
17+
swift package generate-xcodeproj
18+
xed .

Package.resolved

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"object": {
3+
"pins": [
4+
{
5+
"package": "SnapshotTesting",
6+
"repositoryURL": "https://github.com/pointfreeco/swift-snapshot-testing.git",
7+
"state": {
8+
"branch": null,
9+
"revision": "883f0b0623ae55f41f42e2399dab428017896448",
10+
"version": "1.5.0"
11+
}
12+
},
13+
{
14+
"package": "SwiftSyntax",
15+
"repositoryURL": "https://github.com/apple/swift-syntax.git",
16+
"state": {
17+
"branch": null,
18+
"revision": "43aa4a19b8105a803d8149ad2a86aa53a77efef3",
19+
"version": "0.50000.0"
20+
}
21+
},
22+
{
23+
"package": "Yaap",
24+
"repositoryURL": "https://github.com/hartbit/Yaap.git",
25+
"state": {
26+
"branch": "master",
27+
"revision": "7e205f99ad86ac5eac50253d2d5848cf7c9c579a",
28+
"version": null
29+
}
30+
}
31+
]
32+
},
33+
"version": 1
34+
}

Package.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// swift-tools-version:4.0
2+
3+
import PackageDescription
4+
5+
let package = Package(
6+
name: "SwiftUsing",
7+
dependencies: [
8+
.package(url: "https://github.com/apple/swift-syntax.git", .exact("0.50000.0")),
9+
.package(url: "https://github.com/hartbit/Yaap.git", .branch("master")),
10+
.package(url: "https://github.com/pointfreeco/swift-snapshot-testing.git", from: "1.5.0"),
11+
],
12+
targets: [
13+
.target(
14+
name: "swiftusing",
15+
dependencies: ["SwiftUsingCore", "Yaap"]),
16+
.target(
17+
name: "SwiftUsingCore",
18+
dependencies: ["SwiftSyntax"]),
19+
.testTarget(
20+
name: "SwiftUsingTests",
21+
dependencies: ["SwiftUsingCore", "SnapshotTesting"])
22+
]
23+
)

Sources/SwiftUsing/main.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* SwiftUsing
3+
* Copyright (c) Alejandro Martínez 2019
4+
* Licensed under the MIT license. See LICENSE file.
5+
*/
6+
7+
import SwiftUsingCore
8+
import Foundation
9+
import Yaap
10+
11+
class GenerateCommand: Command {
12+
let name = "Generate"
13+
14+
let path = Argument<String>(documentation: "Path to the file to execute the code generation on.")
15+
16+
func run(outputStream: inout TextOutputStream, errorStream: inout TextOutputStream) throws {
17+
outputStream.write("Generating code...\n")
18+
19+
let file = URL(fileURLWithPath: path.value)
20+
21+
let generator = SwiftUsing(file: file)
22+
try generator.generate()
23+
}
24+
}
25+
26+
GenerateCommand().parseAndRun()
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import SwiftSyntax
2+
import Foundation
3+
4+
public class SwiftUsing {
5+
6+
let file: URL
7+
8+
public init(file: URL) {
9+
self.file = file
10+
}
11+
12+
public func generate() throws {
13+
// Parse file
14+
let tree = try SyntaxTreeParser.parse(file)
15+
16+
// File -> UsingFinder Visitor -> (types + using)
17+
let (types, using) = find(tree)
18+
19+
// (types + using) -> Maker -> [ExtensionDeclSyntax]
20+
let generated = make(types: types, using: using)
21+
22+
// Tree + [ExtensionDeclSyntax] -> Rewritter -> new Tree
23+
let newTree = rewritte(tree, generated: generated)
24+
25+
// Overwrite file
26+
try "\(newTree)".write(to: file, atomically: true, encoding: .utf8)
27+
}
28+
29+
func find(_ tree: SourceFileSyntax) -> (
30+
types: [StructDeclSyntax],
31+
using: [VariableDeclSyntax]
32+
) {
33+
let visitor = UsingFinder()
34+
tree.walk(visitor)
35+
36+
return (
37+
visitor.types,
38+
visitor.using
39+
)
40+
}
41+
42+
func make(
43+
types: [StructDeclSyntax],
44+
using: [VariableDeclSyntax]
45+
) -> [ExtensionDeclSyntax] {
46+
let maker = UsingMaker(types: types, using: using)
47+
return maker.generateUsingCode()
48+
}
49+
50+
func rewritte(_ tree: SourceFileSyntax, generated: [ExtensionDeclSyntax]) -> SourceFileSyntax {
51+
let rewriter = UsingRewriter(generated: generated)
52+
let final = rewriter.rewrite(tree)
53+
return final
54+
}
55+
56+
}

0 commit comments

Comments
 (0)