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
20 changes: 19 additions & 1 deletion Sources/TSCodeModule/Basic/PrettyPrinter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ extension PrettyPrintable {
}
}

public enum BlockScope {
case global
case function
case `class`
case interface
}

public final class PrettyPrinter {
private var level: Int = 0

Expand All @@ -19,9 +26,13 @@ public final class PrettyPrinter {

public private(set) var line: Int = 1

public private(set) var blockScope: BlockScope

public var smallNumber: Int = 3

public init() {}
public init(initialScope: BlockScope = .global) {
blockScope = initialScope
}

public func write(_ text: String) {
indentIfStartOfLine()
Expand Down Expand Up @@ -62,6 +73,13 @@ public final class PrettyPrinter {
return try f()
}

public func with<R>(blockScope: BlockScope, _ f: () throws -> R) rethrows -> R {
let prev = self.blockScope
defer { self.blockScope = prev }
self.blockScope = blockScope
return try f()
}

private func indentIfStartOfLine() {
guard isStartOfLine else { return }
isStartOfLine = false
Expand Down
9 changes: 6 additions & 3 deletions Sources/TSCodeModule/Code/TSBlockItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,13 @@ extension [TSBlockItem] {
public func print(printer: PrettyPrinter) {
for (index, item) in enumerated() {
if index > 0,
let decl = self[index - 1].decl,
decl.wantsTrailingNewline
let prevDecl = self[index - 1].decl,
let itemDecl = item.decl
{
printer.writeLine("")
let isSame = isSameKind(lhs: prevDecl, rhs: itemDecl)
if !isSame || itemDecl.wantsNewlineBetweenSiblingDecl(scope: printer.blockScope) {
printer.writeLine("")
}
}

item.print(printer: printer)
Expand Down
4 changes: 3 additions & 1 deletion Sources/TSCodeModule/Code/TSCode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public struct TSCode: PrettyPrintable {
public var items: [TSBlockItem]

public func print(printer: PrettyPrinter) {
items.print(printer: printer)
printer.with(blockScope: .global) {
items.print(printer: printer)
}
}
}
8 changes: 4 additions & 4 deletions Sources/TSCodeModule/Decl/TSClassDecl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ public struct TSClassDecl: PrettyPrintable {
}
printer.writeUnlessStartOfLine(" ")
printer.writeLine("{")

printer.nest {
items.print(printer: printer)
printer.with(blockScope: .class) {
printer.nest {
items.print(printer: printer)
}
}

printer.writeLine("}")
}
}
70 changes: 60 additions & 10 deletions Sources/TSCodeModule/Decl/TSDecl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,41 @@ public enum TSDecl: PrettyPrintable {
case .method(let d): d.print(printer: r)
case .namespace(let d): d.print(printer: r)
case .type(let d): d.print(printer: r)
case .var(let d): d.print(printer: r)
case .`var`(let d): d.print(printer: r)
case .custom(let d): d.print(printer: r)
}
}

public var wantsTrailingNewline: Bool {
public func wantsNewlineBetweenSiblingDecl(scope: BlockScope) -> Bool {
switch self {
case .`var`(let d): return d.wantsTrailingNewline
case .custom: return false
default: return true
case .class:
return true
case .field:
return false
case .import:
return false
case .interface:
return true
case .method, .function:
switch scope {
case .interface:
return false
default:
return true
}
case .namespace:
return true
case .type:
return true
case .var:
switch scope {
case .global:
return true
default:
return false
}
case .custom:
return true
}
}

Expand All @@ -51,20 +76,45 @@ public enum TSDecl: PrettyPrintable {
kind: String,
name: String,
type: TSType? = nil,
initializer: TSExpr? = nil,
wantsTrailingNewline: Bool = false
initializer: TSExpr? = nil
) -> TSDecl {
.var(TSVarDecl(
.`var`(TSVarDecl(
export: export,
kind: kind,
name: name,
type: type,
initializer: initializer,
wantsTrailingNewline: wantsTrailingNewline
initializer: initializer
))
}

public static func custom(_ text: String) -> TSDecl {
.custom(TSCustomDecl(text))
}
}

public func isSameKind(lhs: TSDecl, rhs: TSDecl) -> Bool {
switch (lhs, rhs) {
case (.`class`, .`class`):
return true
case (.field, .field):
return true
case (.function, .function):
return true
case (.`import`, .`import`):
return true
case (.interface, .interface):
return true
case (.method, .method):
return true
case (.namespace, .namespace):
return true
case (.type, .type):
return true
case (.`var`, .`var`):
return true
case (.custom, .custom):
return false
default:
return false
}
}
6 changes: 4 additions & 2 deletions Sources/TSCodeModule/Decl/TSFunctionDecl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ public struct TSFunctionDecl: PrettyPrintable {
}

printer.writeLine(" {")
printer.nest {
items.print(printer: printer)
printer.with(blockScope: .function) {
printer.nest {
items.print(printer: printer)
}
}
printer.writeLine("}")
}
Expand Down
23 changes: 15 additions & 8 deletions Sources/TSCodeModule/Decl/TSImportDecl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,23 @@ public struct TSImportDecl: PrettyPrintable {
public var from: String

public func print(printer: PrettyPrinter) {
printer.writeLine("import {")
printer.nest {
for (i, name) in names.enumerated() {
printer.write(name)
if i < names.count - 1 {
printer.write(",")
let isBig = names.count > printer.smallNumber
if isBig {
printer.writeLine("import {")
printer.nest {
for (i, name) in names.enumerated() {
printer.write(name)
if i < names.count - 1 {
printer.write(",")
}
printer.writeLine("")
}
printer.writeLine("")
}
printer.writeLine("} from \"\(from)\";")
} else {
printer.write("import { ")
printer.write(names.joined(separator: ", "))
printer.writeLine(" } from \"\(from)\";")
}
printer.writeLine("} from \"\(from)\";")
}
}
6 changes: 4 additions & 2 deletions Sources/TSCodeModule/Decl/TSInterfaceDecl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ public struct TSInterfaceDecl: PrettyPrintable {
}
printer.writeUnlessStartOfLine(" ")
printer.writeLine("{")
printer.nest {
decls.map { TSBlockItem.decl($0) }.print(printer: printer)
printer.with(blockScope: .interface) {
printer.nest {
decls.map { TSBlockItem.decl($0) }.print(printer: printer)
}
}
printer.writeLine("}")
}
Expand Down
6 changes: 4 additions & 2 deletions Sources/TSCodeModule/Decl/TSMethodDecl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ public struct TSMethodDecl: PrettyPrintable {

if let items {
printer.writeLine(" {")
printer.nest {
items.print(printer: printer)
printer.with(blockScope: .function) {
printer.nest {
items.print(printer: printer)
}
}
printer.writeLine("}")
} else {
Expand Down
5 changes: 1 addition & 4 deletions Sources/TSCodeModule/Decl/TSVarDecl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,19 @@ public struct TSVarDecl: PrettyPrintable {
public var name: String
public var type: TSType?
public var initializer: TSExpr?
public var wantsTrailingNewline: Bool

public init(
export: Bool = false,
kind: String,
name: String,
type: TSType? = nil,
initializer: TSExpr? = nil,
wantsTrailingNewline: Bool = false
initializer: TSExpr? = nil
) {
self.export = export
self.kind = kind
self.name = name
self.type = type
self.initializer = initializer
self.wantsTrailingNewline = wantsTrailingNewline
}

public func print(printer: PrettyPrinter) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,7 @@ enum R<T> {
}
""",
expecteds: ["""
import {
E,
E_JSON,
E_decode
} from "..";
import { E, E_JSON, E_decode } from "..";
""", """
export type R<T> = {
kind: "s";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,7 @@ struct C {
""",
typeSelector: .name("C"),
expecteds: ["""
import {
A_B
} from "..";
import { A_B } from "..";
""", """
export type C = {
b: A_B;
Expand Down
Loading