2015-09-23 23:37:22 +03:00
|
|
|
import Doubt
|
|
|
|
import SourceKittenFramework
|
|
|
|
|
2015-09-23 23:34:07 +03:00
|
|
|
let arguments = BoundsCheckedArray(array: Process.arguments)
|
|
|
|
|
2015-09-30 22:08:19 +03:00
|
|
|
public protocol StringConvertible {
|
|
|
|
init(string: String)
|
|
|
|
}
|
|
|
|
|
|
|
|
extension String: StringConvertible {
|
|
|
|
public init(string: String) {
|
|
|
|
self = string
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-07 03:38:00 +03:00
|
|
|
extension Info: StringConvertible {
|
|
|
|
public init(string: String) {
|
|
|
|
self = .Literal(string, [])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-30 22:08:19 +03:00
|
|
|
private struct Bail: ErrorType {}
|
|
|
|
|
2015-10-07 03:39:57 +03:00
|
|
|
extension Fix where A: StringConvertible {
|
2015-09-30 22:08:19 +03:00
|
|
|
/// Constructs a Term representing `JSON`.
|
|
|
|
init?(JSON: Doubt.JSON) {
|
|
|
|
func bail<B>() throws -> B {
|
|
|
|
throw Bail()
|
|
|
|
}
|
|
|
|
do {
|
|
|
|
switch JSON {
|
|
|
|
case let .Dictionary(d) where d["key.name"] != nil:
|
|
|
|
let name = d["key.name"]?.string ?? ""
|
|
|
|
let substructure = d["key.substructure"]?.array ?? []
|
|
|
|
let kind = d["key.kind"]?.string
|
|
|
|
switch kind {
|
|
|
|
case
|
|
|
|
.Some("source.lang.swift.decl.class"),
|
|
|
|
.Some("source.lang.swift.decl.extension"),
|
|
|
|
.Some("source.lang.swift.decl.enum"),
|
|
|
|
.Some("source.lang.swift.decl.struct"):
|
2015-10-07 03:43:02 +03:00
|
|
|
self = .In(.Branch([ .In(.Leaf(A(string: name))), .In(.Branch(try substructure.map { try Fix(JSON: $0) ?? bail() })) ]))
|
2015-09-30 22:08:19 +03:00
|
|
|
|
|
|
|
case .Some("source.lang.swift.decl.enumelement"):
|
|
|
|
fallthrough
|
|
|
|
case
|
|
|
|
.Some("source.lang.swift.decl.function.method.instance"),
|
|
|
|
.Some("source.lang.swift.decl.function.free"):
|
2015-10-07 03:43:02 +03:00
|
|
|
self = .In(.Branch([ .In(.Leaf(A(string: name))), .In(.Branch(try substructure.map { try Fix(JSON: $0) ?? bail() })) ]))
|
2015-09-30 22:08:19 +03:00
|
|
|
|
|
|
|
case
|
|
|
|
.Some("source.lang.swift.decl.var.instance"),
|
|
|
|
.Some("source.lang.swift.decl.var.static"):
|
2015-10-07 03:43:02 +03:00
|
|
|
self = .In(.Leaf(A(string: name)))
|
2015-09-30 22:08:19 +03:00
|
|
|
|
|
|
|
default:
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
case let .Dictionary(d) where d["key.kind"]?.string == "source.lang.swift.decl.enumcase" && d["key.substructure"]?.array?.count == 1:
|
|
|
|
let substructure = d["key.substructure"]?.array ?? []
|
2015-10-07 03:39:57 +03:00
|
|
|
self = try Fix(JSON: substructure[0]) ?? bail()
|
2015-09-30 22:08:19 +03:00
|
|
|
|
|
|
|
case let .Dictionary(d) where d["key.kind"]?.string == "source.lang.swift.syntaxtype.comment.mark":
|
2015-10-07 03:43:23 +03:00
|
|
|
self = .In(.Leaf(A(string: "mark")))
|
2015-09-30 22:08:19 +03:00
|
|
|
|
|
|
|
case .Null:
|
|
|
|
self = .Empty
|
|
|
|
|
|
|
|
default:
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
} catch _ {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Constructs a Term representing the `JSON` in a file at `path`.
|
|
|
|
init?(path: String, JSON: Doubt.JSON) {
|
|
|
|
func bail<B>() throws -> B {
|
|
|
|
throw Bail()
|
|
|
|
}
|
|
|
|
do {
|
|
|
|
switch JSON.dictionary?["key.substructure"] {
|
|
|
|
case let .Some(.Array(a)):
|
2015-10-07 03:39:57 +03:00
|
|
|
self = .Roll(.Branch(try a.map { try Fix(JSON: $0) ?? bail() }))
|
2015-09-30 22:08:19 +03:00
|
|
|
default:
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
} catch _ {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-23 23:37:22 +03:00
|
|
|
init?(path: String) {
|
2015-09-24 00:01:09 +03:00
|
|
|
guard path != "/dev/null" else {
|
|
|
|
self = .Empty
|
|
|
|
return
|
|
|
|
}
|
2015-09-23 23:37:22 +03:00
|
|
|
guard let term = File(path: path)
|
|
|
|
.map(Structure.init)
|
|
|
|
.map({ $0.dictionary })
|
|
|
|
.map(toAnyObject)
|
2015-10-07 03:39:57 +03:00
|
|
|
.flatMap({ JSON(object: $0).flatMap { Fix(path: path, JSON: $0) } }) else { return nil }
|
2015-09-23 23:37:22 +03:00
|
|
|
self = term
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-07 03:39:51 +03:00
|
|
|
if let a = arguments[1].flatMap({ Fix<Info>(path: $0) }), b = arguments[2].flatMap({ Fix<Info>(path: $0) }) {
|
2015-10-07 03:39:37 +03:00
|
|
|
print(String(reflecting: FreeAlgorithm<Info, Free<Info, Patch<Info>>>(a, b)))
|
2015-09-23 23:37:22 +03:00
|
|
|
}
|