1
1
mirror of https://github.com/github/semantic.git synced 2024-12-26 08:25:19 +03:00

Merge remote-tracking branch 'origin/master' into show-empty-space

This commit is contained in:
joshvera 2015-11-03 11:47:29 -05:00
commit 5f43e526c2
10 changed files with 193 additions and 135 deletions

View File

@ -36,6 +36,8 @@
D4413FEF1BB06D4C00E3C3C1 /* Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4413FEE1BB06D4C00E3C3C1 /* Dictionary.swift */; }; D4413FEF1BB06D4C00E3C3C1 /* Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4413FEE1BB06D4C00E3C3C1 /* Dictionary.swift */; };
D4413FF11BB08FDC00E3C3C1 /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4413FF01BB08FDC00E3C3C1 /* JSON.swift */; }; D4413FF11BB08FDC00E3C3C1 /* JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4413FF01BB08FDC00E3C3C1 /* JSON.swift */; };
D45A36C91BBC667D00BE3DDE /* Categorizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D45A36C81BBC667D00BE3DDE /* Categorizable.swift */; }; D45A36C91BBC667D00BE3DDE /* Categorizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D45A36C81BBC667D00BE3DDE /* Categorizable.swift */; };
D46452C71BE7C6C800D7D26E /* Argument.swift in Sources */ = {isa = PBXBuildFile; fileRef = D46452C61BE7C6C800D7D26E /* Argument.swift */; };
D46452C91BE7EB2500D7D26E /* Unified.swift in Sources */ = {isa = PBXBuildFile; fileRef = D46452C81BE7EB2500D7D26E /* Unified.swift */; };
D49FCBC41BBEF98E00C5E9C3 /* Free.swift in Sources */ = {isa = PBXBuildFile; fileRef = D49FCBC31BBEF98E00C5E9C3 /* Free.swift */; }; D49FCBC41BBEF98E00C5E9C3 /* Free.swift in Sources */ = {isa = PBXBuildFile; fileRef = D49FCBC31BBEF98E00C5E9C3 /* Free.swift */; };
D49FCBC61BBF214300C5E9C3 /* Patch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D49FCBC51BBF214300C5E9C3 /* Patch.swift */; }; D49FCBC61BBF214300C5E9C3 /* Patch.swift in Sources */ = {isa = PBXBuildFile; fileRef = D49FCBC51BBF214300C5E9C3 /* Patch.swift */; };
D49FCBC81BBF2C4300C5E9C3 /* Algorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = D49FCBC71BBF2C4300C5E9C3 /* Algorithm.swift */; }; D49FCBC81BBF2C4300C5E9C3 /* Algorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = D49FCBC71BBF2C4300C5E9C3 /* Algorithm.swift */; };
@ -104,6 +106,8 @@
D4413FEE1BB06D4C00E3C3C1 /* Dictionary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Dictionary.swift; sourceTree = "<group>"; }; D4413FEE1BB06D4C00E3C3C1 /* Dictionary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Dictionary.swift; sourceTree = "<group>"; };
D4413FF01BB08FDC00E3C3C1 /* JSON.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSON.swift; sourceTree = "<group>"; }; D4413FF01BB08FDC00E3C3C1 /* JSON.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSON.swift; sourceTree = "<group>"; };
D45A36C81BBC667D00BE3DDE /* Categorizable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Categorizable.swift; sourceTree = "<group>"; }; D45A36C81BBC667D00BE3DDE /* Categorizable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Categorizable.swift; sourceTree = "<group>"; };
D46452C61BE7C6C800D7D26E /* Argument.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Argument.swift; sourceTree = "<group>"; };
D46452C81BE7EB2500D7D26E /* Unified.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Unified.swift; sourceTree = "<group>"; };
D49FCBC31BBEF98E00C5E9C3 /* Free.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Free.swift; sourceTree = "<group>"; }; D49FCBC31BBEF98E00C5E9C3 /* Free.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Free.swift; sourceTree = "<group>"; };
D49FCBC51BBF214300C5E9C3 /* Patch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Patch.swift; sourceTree = "<group>"; }; D49FCBC51BBF214300C5E9C3 /* Patch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Patch.swift; sourceTree = "<group>"; };
D49FCBC71BBF2C4300C5E9C3 /* Algorithm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Algorithm.swift; sourceTree = "<group>"; }; D49FCBC71BBF2C4300C5E9C3 /* Algorithm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Algorithm.swift; sourceTree = "<group>"; };
@ -257,6 +261,8 @@
D4FB2CDB1BDEBCCD00B3CCE0 /* main.swift */, D4FB2CDB1BDEBCCD00B3CCE0 /* main.swift */,
D4FB2D011BE2943A00B3CCE0 /* Info.swift */, D4FB2D011BE2943A00B3CCE0 /* Info.swift */,
D4FB2CF71BE1560400B3CCE0 /* TSNode.swift */, D4FB2CF71BE1560400B3CCE0 /* TSNode.swift */,
D46452C61BE7C6C800D7D26E /* Argument.swift */,
D46452C81BE7EB2500D7D26E /* Unified.swift */,
D4FB2CE51BDEBE7900B3CCE0 /* doubt-difftool-Bridging-Header.h */, D4FB2CE51BDEBE7900B3CCE0 /* doubt-difftool-Bridging-Header.h */,
D4FB2D001BE2936800B3CCE0 /* Parsers */, D4FB2D001BE2936800B3CCE0 /* Parsers */,
D4FB2CDE1BDEBD1C00B3CCE0 /* libruntime.a */, D4FB2CDE1BDEBD1C00B3CCE0 /* libruntime.a */,
@ -481,10 +487,12 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
D46452C71BE7C6C800D7D26E /* Argument.swift in Sources */,
D4FB2CF81BE1560400B3CCE0 /* TSNode.swift in Sources */, D4FB2CF81BE1560400B3CCE0 /* TSNode.swift in Sources */,
D4FB2CFA1BE28F6D00B3CCE0 /* parser.c in Sources */, D4FB2CFA1BE28F6D00B3CCE0 /* parser.c in Sources */,
D4FB2CFC1BE292BB00B3CCE0 /* parser.c in Sources */, D4FB2CFC1BE292BB00B3CCE0 /* parser.c in Sources */,
D4FB2D021BE2943A00B3CCE0 /* Info.swift in Sources */, D4FB2D021BE2943A00B3CCE0 /* Info.swift in Sources */,
D46452C91BE7EB2500D7D26E /* Unified.swift in Sources */,
D4FB2CDC1BDEBCCD00B3CCE0 /* main.swift in Sources */, D4FB2CDC1BDEBCCD00B3CCE0 /* main.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;

View File

@ -48,7 +48,7 @@
launchStyle = "0" launchStyle = "0"
useCustomWorkingDirectory = "NO" useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO" ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES" debugDocumentVersioning = "NO"
debugServiceExtension = "internal" debugServiceExtension = "internal"
allowLocationSimulation = "YES"> allowLocationSimulation = "YES">
<BuildableProductRunnable <BuildableProductRunnable
@ -62,6 +62,10 @@
</BuildableReference> </BuildableReference>
</BuildableProductRunnable> </BuildableProductRunnable>
<CommandLineArguments> <CommandLineArguments>
<CommandLineArgument
argument = "--unified"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument <CommandLineArgument
argument = "https://raw.githubusercontent.com/jquery/jquery/2.1.0/src/effects.js" argument = "https://raw.githubusercontent.com/jquery/jquery/2.1.0/src/effects.js"
isEnabled = "YES"> isEnabled = "YES">

View File

@ -1,105 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D4DF96FA1BC5DF050040F41F"
BuildableName = "doubt-json.app"
BlueprintName = "doubt-json"
ReferencedContainer = "container:Doubt.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D4DF96FA1BC5DF050040F41F"
BuildableName = "doubt-json.app"
BlueprintName = "doubt-json"
ReferencedContainer = "container:Doubt.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D4DF96FA1BC5DF050040F41F"
BuildableName = "doubt-json.app"
BlueprintName = "doubt-json"
ReferencedContainer = "container:Doubt.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<CommandLineArguments>
<CommandLineArgument
argument = "$(SRCROOT)/doubt-json/Fixtures/a.json"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "$(SRCROOT)/doubt-json/Fixtures/b.json"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "$(SRCROOT)/UI/diff.json"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D4DF96FA1BC5DF050040F41F"
BuildableName = "doubt-json.app"
BlueprintName = "doubt-json"
ReferencedContainer = "container:Doubt.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -120,6 +120,15 @@ extension CofreeType {
return (term.extract, term.unwrap) return (term.extract, term.unwrap)
} }
/// Catamorphism over `TermType`s.
///
/// Folds the tree encoded by the receiver into a single value by recurring top-down through the tree, applying `transform` to leaves, then to branches, and so forth.
public func cata<Result>(transform: (Annotation, Syntax<Result, Leaf>) -> Result) -> Result {
return self |> (Self.eliminate >>> { ($0, $1.map { $0.cata(transform) }) } >>> transform)
}
/// Constructs a cofree by coiteration. /// Constructs a cofree by coiteration.
/// ///
/// This is an _anamorphism_ (from the Greek ana, upwards; compare anabolism), a generalization of unfolds over regular trees (and datatypes isomorphic to them). The initial seed is used as the annotation of the returned value. The continuation of the structure is unpacked by applying `annotate` to the seed and mapping the resulting syntaxs values recursively. In this manner, the structure is unfolded bottom-up, starting with `seed` and ending at the leaves. /// This is an _anamorphism_ (from the Greek ana, upwards; compare anabolism), a generalization of unfolds over regular trees (and datatypes isomorphic to them). The initial seed is used as the annotation of the returned value. The continuation of the structure is unpacked by applying `annotate` to the seed and mapping the resulting syntaxs values recursively. In this manner, the structure is unfolded bottom-up, starting with `seed` and ending at the leaves.

View File

@ -56,17 +56,17 @@ public enum Free<Leaf, Annotation, Value>: CustomDebugStringConvertible {
/// While not every function on a given `Free` can be computed using `cata`, these guarantees of termination and complexity, as well as the brevity and focus on the operation being performed n times, make it a desirable scaffolding for any function which can. /// While not every function on a given `Free` can be computed using `cata`, these guarantees of termination and complexity, as well as the brevity and focus on the operation being performed n times, make it a desirable scaffolding for any function which can.
/// ///
/// For a lucid, in-depth tutorial on recursion schemes, I recommend [Patrick Thomson](https://twitter.com/importantshock)s _[An Introduction to Recursion Schemes](http://patrickthomson.ghost.io/an-introduction-to-recursion-schemes/)_ and _[Recursion Schemes, Part 2: A Mob of Morphisms](http://patrickthomson.ghost.io/recursion-schemes-part-2/)_. /// For a lucid, in-depth tutorial on recursion schemes, I recommend [Patrick Thomson](https://twitter.com/importantshock)s _[An Introduction to Recursion Schemes](http://patrickthomson.ghost.io/an-introduction-to-recursion-schemes/)_ and _[Recursion Schemes, Part 2: A Mob of Morphisms](http://patrickthomson.ghost.io/recursion-schemes-part-2/)_.
public func cata(@noescape transform: Syntax<Value, Leaf> throws -> Value) rethrows -> Value { public func cata(@noescape transform: (Annotation, Syntax<Value, Leaf>) throws -> Value) rethrows -> Value {
return try analysis( return try analysis(
ifPure: id, ifPure: id,
ifRoll: { try transform($1.map { try $0.cata(transform) }) }) ifRoll: { try transform($0, $1.map { try $0.cata(transform) }) })
} }
/// Reduces the receiver top-down, left-to-right, starting from an `initial` value, and applying `combine` to successive values. /// Reduces the receiver top-down, left-to-right, starting from an `initial` value, and applying `combine` to successive values.
public func reduce(initial: Value, @noescape combine: (Value, Value) -> Value) -> Value { public func reduce(initial: Value, @noescape combine: (Value, Value) -> Value) -> Value {
return cata { return cata {
switch $0 { switch $1 {
case .Leaf: case .Leaf:
return initial return initial
case let .Indexed(a): case let .Indexed(a):
@ -132,11 +132,11 @@ extension Free where Value: PatchType, Value.Element == Cofree<Leaf, ()> {
public typealias Term = Value.Element public typealias Term = Value.Element
public func merge(@noescape transform: Value -> Term) -> Term { public func merge(@noescape transform: Value -> Term) -> Term {
return map(transform).cata { Cofree((), $0) } return map(transform).cata { Cofree((), $1) }
} }
public func merge(@noescape transform: Value -> Term?) -> Term? { public func merge(@noescape transform: Value -> Term?) -> Term? {
return map(transform).cata(Free.discardNullTerms) return map(transform).cata { Free.discardNullTerms($1) }
} }
private static func discardNullTerms(syntax: Syntax<Term?, Leaf>) -> Term? { private static func discardNullTerms(syntax: Syntax<Term?, Leaf>) -> Term? {

View File

@ -11,7 +11,7 @@ struct UnannotatedTerm {
let keyed = UnannotatedTerm.keyed let keyed = UnannotatedTerm.keyed
let fixed = UnannotatedTerm.fixed let fixed = UnannotatedTerm.fixed
return term.cata { return term.cata {
switch $0 { switch $1 {
case let .Leaf(s): case let .Leaf(s):
return s return s
case let .Indexed(s): case let .Indexed(s):
@ -30,7 +30,7 @@ struct UnannotatedTerm {
let fixed = UnannotatedTerm.fixed let fixed = UnannotatedTerm.fixed
return term.cata { return term.cata {
switch $0 { switch $1 {
case let .Leaf(s): case let .Leaf(s):
return Cofree(0..<s.characters.count, .Leaf(s)) return Cofree(0..<s.characters.count, .Leaf(s))
case let .Indexed(i): case let .Indexed(i):

@ -1 +1 @@
Subproject commit fe6f1b69296bd2cfff734f7dda786fc6743b5665 Subproject commit 434e07a3861698516c438e631d0545c1e1c4ab06

View File

@ -0,0 +1,43 @@
/// A list of arguments for the difftool.
enum Argument {
indirect case OutputFlag(Output, Argument)
case Sources(Source, Source)
var sources: (Source, Source) {
switch self {
case let .Sources(a, b):
return (a, b)
case let .OutputFlag(_, rest):
return rest.sources
}
}
var output: Output {
switch self {
case let .OutputFlag(output, _):
return output
default:
return .Split
}
}
enum Output {
case Unified
case Split
}
}
private let flag: Madness.Parser<[String], Argument.Output>.Function =
const(Argument.Output.Unified) <^> satisfy { $0 == "--unified" }
<|> const(Argument.Output.Split) <^> satisfy { $0 == "--split" }
<|> pure(Argument.Output.Split)
private let source: Madness.Parser<[String], Source>.Function =
{ try! Source($0) } <^> satisfy { !$0.hasPrefix("--") }
let argumentsParser: Madness.Parser<[String], Argument>.Function = any // skip the path to the difftool
*> (curry(Argument.OutputFlag) <^> flag)
<*> (curry(Argument.Sources) <^> source <*> source)
import Madness
import Prelude

View File

@ -0,0 +1,93 @@
private func unified(term: Term, source: String) -> String {
return term.cata { info, syntax -> (String, Range<Int>?) in
switch syntax {
case .Leaf:
return (String(source.utf16[info.range]), info.range)
case let .Indexed(i):
return (unified(info.range, children: i, source: source), info.range)
case let .Fixed(f):
return (unified(info.range, children: f, source: source), info.range)
case let .Keyed(k):
return (unified(info.range, children: k.values.sort(isOrderedBefore), source: source), info.range)
}
}.0
}
private func isOrderedBefore(a: (String, Range<Int>?), _ b: (String, Range<Int>?)) -> Bool {
if let a = a.1, b = b.1 {
return a.startIndex < b.startIndex
}
return false
}
private var isTTY = isatty(STDOUT_FILENO) != 0
private var isDumb = String.fromCString(getenv("TERM")).map { $0.hasPrefix("dumb") } ?? true
private var shouldFormat = isTTY && !isDumb
private struct Attribute {
let colour: Colour
let style: Style
enum Colour: Int {
case Black = 30
case Red
case Green
case Yellow
case Blue
case Purple
case Cyan
case White
}
enum Style: Int {
case Normal = 0
case Bold = 1
case Underline = 4
}
func wrap(string: String) -> String {
return shouldFormat
? "\u{001B}[\(style.rawValue);\(colour.rawValue)m\(string)\u{001B}[0m"
: string
}
}
private func unified(patch: Patch<Term>, before: String, after: String) -> String {
return (patch.state.before.map { Attribute(colour: .Red, style: .Bold).wrap("{-\(unified($0, source: before))-}") } ?? "")
+ (patch.state.after.map { Attribute(colour: .Green, style: .Bold).wrap("{+\(unified($0, source: after))+}") } ?? "")
}
private func range(patch: Patch<Term>) -> Range<Int>? {
return patch.state.after?.extract.range
}
private func unified(range: Range<Int>, children: [(String, Range<Int>?)], source: String) -> String {
var previous = range.startIndex
var out: String = ""
for (string, range) in children {
if let range = range {
out += String(source.utf16[previous..<range.startIndex])
previous = range.endIndex
}
out += string
}
return out + String(source.utf16[previous..<range.endIndex])
}
func unified(diff: Diff, before: String, after: String) -> String {
return diff.map { (unified($0, before: before, after: after), range($0)) }.cata { info, syntax in
switch syntax {
case .Leaf:
return (String(after.utf16[info.1.range]), info.1.range)
case let .Indexed(i):
return (unified(info.1.range, children: i, source: after), info.1.range)
case let .Fixed(f):
return (unified(info.1.range, children: f, source: after), info.1.range)
case let .Keyed(k):
return (unified(info.1.range, children: k.values.sort(isOrderedBefore), source: after), info.1.range)
}
}.0
}
import Doubt

View File

@ -14,6 +14,7 @@ func benchmark<T>(label: String? = nil, _ f: () -> T) -> T {
extension String: ErrorType {} extension String: ErrorType {}
typealias Term = Cofree<String, Info> typealias Term = Cofree<String, Info>
typealias Diff = Free<Term.Leaf, (Term.Annotation, Term.Annotation), Patch<Term>>
typealias Parser = String throws -> Term typealias Parser = String throws -> Term
struct Source { struct Source {
@ -143,9 +144,9 @@ func parserForType(type: String) -> String throws -> Term {
} }
} }
let arguments = BoundsCheckedArray(array: Process.arguments) let parsed = parse(argumentsParser, input: Process.arguments)
guard let aSource = try arguments[1].map(Source.init) else { throw "need source A" } let arguments: Argument = try parsed.either(ifLeft: { throw "\($0)" }, ifRight: { $0 })
guard let bSource = try arguments[2].map(Source.init) else { throw "need source B" } let (aSource, bSource) = arguments.sources
let jsonURL = NSURL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).URLByAppendingPathComponent("diff.json") let jsonURL = NSURL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).URLByAppendingPathComponent("diff.json")
guard let uiPath = NSBundle.mainBundle().infoDictionary?["PathToUISource"] as? String else { throw "need ui path" } guard let uiPath = NSBundle.mainBundle().infoDictionary?["PathToUISource"] as? String else { throw "need ui path" }
guard aSource.type == bSource.type else { throw "cant compare files of different types" } guard aSource.type == bSource.type else { throw "cant compare files of different types" }
@ -154,23 +155,28 @@ let parser = parserForType(aSource.type)
let a = try parser(aSource.contents) let a = try parser(aSource.contents)
let b = try parser(bSource.contents) let b = try parser(bSource.contents)
let diff = Interpreter<Term>(equal: Term.equals(annotation: const(true), leaf: ==), comparable: Interpreter<Term>.comparable { $0.extract.categories }, cost: Free.sum(Patch.sum)).run(a, b) let diff = Interpreter<Term>(equal: Term.equals(annotation: const(true), leaf: ==), comparable: Interpreter<Term>.comparable { $0.extract.categories }, cost: Free.sum(Patch.sum)).run(a, b)
let JSON: Doubt.JSON = [ switch arguments.output {
"before": .String(aSource.contents), case .Split:
"after": .String(bSource.contents), let JSON: Doubt.JSON = [
"diff": diff.JSON(pure: { $0.JSON { $0.JSON(annotation: { $0.range.JSON }, leaf: Doubt.JSON.String) } }, leaf: Doubt.JSON.String, annotation: { "before": .String(aSource.contents),
[ "after": .String(bSource.contents),
"before": $0.range.JSON, "diff": diff.JSON(pure: { $0.JSON { $0.JSON(annotation: { $0.range.JSON }, leaf: Doubt.JSON.String) } }, leaf: Doubt.JSON.String, annotation: {
"after": $1.range.JSON, [
] "before": $0.range.JSON,
}), "after": $1.range.JSON,
] ]
let data = JSON.serialize() }),
try data.writeToURL(jsonURL, options: .DataWritingAtomic) ]
let data = JSON.serialize()
try data.writeToURL(jsonURL, options: .DataWritingAtomic)
let components = NSURLComponents() let components = NSURLComponents()
components.scheme = "file" components.scheme = "file"
components.path = uiPath components.path = uiPath
components.query = jsonURL.absoluteString components.query = jsonURL.absoluteString
if let URL = components.URL { if let URL = components.URL {
NSWorkspace.sharedWorkspace().openURL(URL) NSWorkspace.sharedWorkspace().openURL(URL)
}
case .Unified:
print(benchmark { unified(diff, before: aSource.contents, after: bSource.contents) })
} }