Skip to content

Commit

Permalink
Merge pull request #10 from robb/swift-syntax
Browse files Browse the repository at this point in the history
Use SwiftSyntax to build tag functions
  • Loading branch information
robb committed Sep 4, 2020
2 parents 17483ad + e52e275 commit 80a3ad2
Show file tree
Hide file tree
Showing 8 changed files with 690 additions and 670 deletions.
9 changes: 9 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
"revision": "f6ac7b8118ff5d1bc0faee7f37bf6f8fd8f95602",
"version": "0.0.1"
}
},
{
"package": "SwiftSyntax",
"repositoryURL": "https://github.com/apple/swift-syntax.git",
"state": {
"branch": null,
"revision": "0688b9cfc4c3dd234e4f55f1f056b2affc849873",
"version": "0.50200.0"
}
}
]
},
Expand Down
3 changes: 2 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ let package = Package(
targets: ["Generator"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-syntax.git", .exact("0.50200.0")),
.package(url: "https://github.com/apple/swift-argument-parser", from: "0.0.1"),
],
targets: [
Expand All @@ -26,6 +27,6 @@ let package = Package(
dependencies: ["HTML"]),
.target(
name: "Generator",
dependencies: ["ArgumentParser"]),
dependencies: ["ArgumentParser", "SwiftSyntax"]),
]
)
2 changes: 0 additions & 2 deletions Sources/Generator/Attribute+Definitions.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import Foundation

extension Attribute {
static let acceptCharset = Attribute(
name: "accept-charset",
Expand Down
116 changes: 41 additions & 75 deletions Sources/Generator/Attribute.swift
Original file line number Diff line number Diff line change
@@ -1,28 +1,20 @@
import Foundation
import SwiftSyntax

enum AttributeType: Hashable {
case boolean
case optionalOfString
case custom(String)


var typeDeclaration: String {
switch self {
case .boolean:
return "Bool"
case .optionalOfString:
return "String?"
case .custom(let string):
return string
}
}
}

extension AttributeType: ExpressibleByStringLiteral {
init(stringLiteral value: String) {
self = .custom(value)
}
}

struct Attribute: Hashable {
var name: String

Expand All @@ -48,81 +40,55 @@ struct Attribute: Hashable {
}

extension Attribute {
var parameterDeclaration: ParameterDeclaration {
ParameterDeclaration(localParameterName: name, typeAnnotation: attributeType, defaultValue: defaultValue)
func buildParameter(_ format: Format) -> FunctionParameterSyntax {
FunctionParameterSyntax {
$0.useSecondName(SyntaxFactory.makeIdentifier(name.escapedIfNeeded))
$0.useColon(SyntaxFactory.makeColonToken(leadingTrivia: .zero, trailingTrivia: .spaces(1)))
$0.useType(attributeType.buildType(format))
$0.useDefaultArgument(InitializerClauseSyntax{
$0.useEqual(SyntaxFactory.makeEqualToken(leadingTrivia: .spaces(1), trailingTrivia: .spaces(1)))
$0.useValue(attributeType.buildDefaultValue(format))
})
}
}

var parameterAssignment: ParameterAssignment {
ParameterAssignment(dictionaryKey: name, localParameterName: name, attributeType: attributeType)
func buildValueExpression(_ format: Format) -> ExprSyntax {
let identifier = SyntaxFactory.makeIdentifier(name.escapedIfNeeded)
switch attributeType {
case .boolean:
return ExprSyntax(TernaryExprSyntax {
$0.useConditionExpression(ExprSyntax(SyntaxFactory.makeIdentifierExpr(identifier: identifier, declNameArguments: nil)))
$0.useQuestionMark(SyntaxFactory.makeInfixQuestionMarkToken(leadingTrivia: .spaces(1), trailingTrivia: .spaces(1)))
$0.useFirstChoice(ExprSyntax(SyntaxFactory.makeStringLiteralExpr("")))
$0.useColonMark(SyntaxFactory.makeColonToken(leadingTrivia: .spaces(1), trailingTrivia: .spaces(1)))
$0.useSecondChoice(ExprSyntax(SyntaxFactory.makeNilLiteralExpr(nilKeyword: SyntaxFactory.makeNilKeyword())))
})
case .optionalOfString:
return ExprSyntax(SyntaxFactory.makeIdentifierExpr(identifier: identifier, declNameArguments: nil))
}
}
}

/// The declaration of a function parameter.
struct ParameterDeclaration {
var annotation: String? = nil

var externalParameterName: String? = nil

var localParameterName: String

var typeAnnotation: AttributeType

var defaultValue: String? = nil
}

extension ParameterDeclaration: TextOutputStreamable {
func write<Target>(to target: inout Target) where Target : TextOutputStream {
if let annotation = annotation {
target.write(annotation)
target.write(" ")
extension AttributeType {
func buildType(_ format: Format) -> TypeSyntax {
let type = SimpleTypeIdentifierSyntax {
switch self {
case .boolean:
$0.useName(SyntaxFactory.makeIdentifier("Bool"))
case .optionalOfString:
$0.useName(SyntaxFactory.makeIdentifier("String?"))
}
}

if let externalParameterName = externalParameterName {
target.write(externalParameterName)
target.write(" ")
}

target.write(localParameterName.escapedIfNeeded)
target.write(": ")
target.write(typeAnnotation.typeDeclaration)

if let defaultValue = defaultValue {
target.write(" = ")
target.write(defaultValue)
}
return TypeSyntax(type)
}
}

/// The assignment of a function parameter to a key in the attributes
/// dictionary.
struct ParameterAssignment {
let dictionaryName = "attributes"

var dictionaryKey: String

var localParameterName: String

var attributeType: AttributeType
}

extension ParameterAssignment: TextOutputStreamable {
func write<Target>(to target: inout Target) where Target : TextOutputStream {
target.write(dictionaryName)
target.write("[\"")
target.write(dictionaryKey)
target.write("\"]")

target.write(" = ")

switch attributeType {
func buildDefaultValue(_ format: Format) -> ExprSyntax {
switch self {
case .boolean:
target.write(localParameterName.escapedIfNeeded)
target.write(" ? ")
target.write("\"\"")
target.write(" : ")
target.write("nil")
default:
target.write(localParameterName.escapedIfNeeded)
return ExprSyntax(SyntaxFactory.makeBooleanLiteralExpr(booleanLiteral: SyntaxFactory.makeFalseKeyword()))
case .optionalOfString:
return ExprSyntax(SyntaxFactory.makeNilLiteralExpr(nilKeyword: SyntaxFactory.makeNilKeyword()))
}
}
}
2 changes: 0 additions & 2 deletions Sources/Generator/String+Keywords.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import Foundation

private let keywords: Set<String> = [
"Any", "as", "associatedtype", "associativity", "case", "catch", "class",
"continue", "convenience", "default", "defer", "deinit", "didSet", "do",
Expand Down
Loading

0 comments on commit 80a3ad2

Please sign in to comment.