mirror of
https://github.com/github/semantic.git
synced 2024-11-25 11:04:00 +03:00
Merge branch 'master' into diff-ui-shows-original-sources-for-unchanged-ranges-as-well
Conflicts: prototype/Doubt/Syntax.swift
This commit is contained in:
commit
9041ebafa1
@ -139,6 +139,8 @@ extension CofreeType {
|
||||
return Cofree(annotations, .Leaf(b))
|
||||
case let (.Indexed(a), .Indexed(b)):
|
||||
return Cofree(annotations, .Indexed(Swift.zip(a, b).flatMap(zip)))
|
||||
case let (.Fixed(a), .Fixed(b)):
|
||||
return Cofree(annotations, .Fixed(Swift.zip(a, b).flatMap(zip)))
|
||||
case let (.Keyed(a), .Keyed(b)):
|
||||
return Cofree(annotations, .Keyed(Dictionary(elements: b.keys.flatMap { key in zip(a[key]!, b[key]!).map { (key, $0) } })))
|
||||
default:
|
||||
|
@ -71,6 +71,8 @@ public enum Free<Leaf, Annotation, Value>: CustomDebugStringConvertible {
|
||||
return initial
|
||||
case let .Indexed(a):
|
||||
return a.reduce(initial, combine: combine)
|
||||
case let .Fixed(a):
|
||||
return a.reduce(initial, combine: combine)
|
||||
case let .Keyed(a):
|
||||
return a.values.reduce(initial, combine: combine)
|
||||
}
|
||||
@ -143,6 +145,8 @@ extension Free where Value: PatchType, Value.Element == Cofree<Leaf, ()> {
|
||||
return Cofree((), .Leaf(a))
|
||||
case let .Indexed(a):
|
||||
return Cofree((), .Indexed(a.flatMap(id)))
|
||||
case let .Fixed(a):
|
||||
return Cofree((), .Fixed(a.flatMap(id)))
|
||||
case let .Keyed(a):
|
||||
return Cofree((), .Keyed(Dictionary(elements: a.flatMap { k, v in v.map { (k, $0) } })))
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ public struct Interpreter<Term: CofreeType> {
|
||||
|
||||
let algorithm: Algorithm<Term, Diff>
|
||||
let annotations = (a.extract, b.extract)
|
||||
|
||||
switch (a.unwrap, b.unwrap) {
|
||||
case let (.Leaf, .Leaf(leaf)) where equal(a, b):
|
||||
return .Roll(annotations, .Leaf(leaf))
|
||||
@ -57,6 +58,8 @@ public struct Interpreter<Term: CofreeType> {
|
||||
algorithm = .Roll(.ByKey(a, b, Syntax.Keyed >>> Diff.Introduce(annotations) >>> Algorithm.Pure))
|
||||
case let (.Indexed(a), .Indexed(b)):
|
||||
algorithm = .Roll(.ByIndex(a, b, Syntax.Indexed >>> Diff.Introduce(annotations) >>> Algorithm.Pure))
|
||||
case (.Fixed(_), .Fixed(_)):
|
||||
fallthrough
|
||||
default:
|
||||
algorithm = .Roll(.Recursive(a, b, Algorithm.Pure))
|
||||
}
|
||||
@ -74,6 +77,8 @@ public struct Interpreter<Term: CofreeType> {
|
||||
switch (a.unwrap, b.unwrap) {
|
||||
case let (.Indexed(a), .Indexed(b)) where a.count == b.count:
|
||||
return recur(f(.Roll(annotations, .Indexed(zip(a, b).map(run)))))
|
||||
case let (.Fixed(a), .Fixed(b)) where a.count == b.count:
|
||||
return recur(f(.Roll(annotations, .Fixed(zip(a, b).map(run)))))
|
||||
|
||||
case let (.Keyed(a), .Keyed(b)) where Array(a.keys) == Array(b.keys):
|
||||
return recur(f(.Roll(annotations, .Keyed(Dictionary(elements: b.keys.map { ($0, self.run(a[$0]!, b[$0]!)) })))))
|
||||
|
@ -2,6 +2,7 @@
|
||||
public enum Syntax<Recur, A>: CustomDebugStringConvertible {
|
||||
case Leaf(A)
|
||||
case Indexed([Recur])
|
||||
case Fixed([Recur])
|
||||
case Keyed([String:Recur])
|
||||
|
||||
|
||||
@ -13,6 +14,8 @@ public enum Syntax<Recur, A>: CustomDebugStringConvertible {
|
||||
return .Leaf(n)
|
||||
case let .Indexed(x):
|
||||
return .Indexed(x.map(transform))
|
||||
case let .Fixed(x):
|
||||
return .Fixed(x.map(transform))
|
||||
case let .Keyed(d):
|
||||
return .Keyed(Dictionary(elements: d.map { ($0, transform($1)) }))
|
||||
}
|
||||
@ -27,6 +30,8 @@ public enum Syntax<Recur, A>: CustomDebugStringConvertible {
|
||||
return ".Leaf(\(n))"
|
||||
case let .Indexed(x):
|
||||
return ".Indexed(\(String(reflecting: x)))"
|
||||
case let .Fixed(x):
|
||||
return ".Fixed(\(String(reflecting: x)))"
|
||||
case let .Keyed(d):
|
||||
return ".Keyed(\(String(reflecting: d)))"
|
||||
}
|
||||
@ -108,6 +113,8 @@ extension Syntax {
|
||||
return [ "leaf": leaf(a) ]
|
||||
case let .Indexed(a):
|
||||
return [ "indexed": .Array(a.map(recur)) ]
|
||||
case let .Fixed(a):
|
||||
return [ "fixed": .Array(a.map(recur)) ]
|
||||
case let .Keyed(d):
|
||||
return [ "keyed": .Dictionary(Dictionary(elements: d.map { ($0, recur($1)) })) ]
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ extension TermType {
|
||||
return 1
|
||||
case let .Indexed(i):
|
||||
return i.reduce(1, combine: +)
|
||||
case let .Fixed(i):
|
||||
return i.reduce(1, combine: +)
|
||||
case let .Keyed(k):
|
||||
return k.values.reduce(1, combine: +)
|
||||
}
|
||||
|
@ -3,17 +3,21 @@ struct UnannotatedTerm {
|
||||
let term: Term
|
||||
|
||||
static let indexed = (prefix: "[\n\t", separator: ",\n\t", suffix: "\n]")
|
||||
static let fixed = (prefix: "(\n\t", separator: ",\n\t", suffix: "\n)")
|
||||
static let keyed = (prefix: "[\n\t", separator: ",\n\t", suffix: "\n}")
|
||||
|
||||
var source: String {
|
||||
let indexed = UnannotatedTerm.indexed
|
||||
let keyed = UnannotatedTerm.keyed
|
||||
let fixed = UnannotatedTerm.fixed
|
||||
return term.cata {
|
||||
switch $0 {
|
||||
case let .Leaf(s):
|
||||
return s
|
||||
case let .Indexed(s):
|
||||
return indexed.prefix + s.joinWithSeparator(indexed.separator) + indexed.suffix
|
||||
case let .Fixed(s):
|
||||
return fixed.prefix + s.joinWithSeparator(fixed.separator) + fixed.suffix
|
||||
case let .Keyed(s):
|
||||
return keyed.prefix + s.map { "\"\($0)\": \($1)" }.joinWithSeparator(keyed.separator) + keyed.suffix
|
||||
}
|
||||
@ -23,6 +27,8 @@ struct UnannotatedTerm {
|
||||
var ranged: Cofree<String, Range<Int>> {
|
||||
let indexed = UnannotatedTerm.indexed
|
||||
let keyed = UnannotatedTerm.keyed
|
||||
let fixed = UnannotatedTerm.fixed
|
||||
|
||||
return term.cata {
|
||||
switch $0 {
|
||||
case let .Leaf(s):
|
||||
@ -40,6 +46,19 @@ struct UnannotatedTerm {
|
||||
length += value.extract.count
|
||||
}
|
||||
return Cofree(0..<(length + indexed.suffix.characters.count), .Indexed(results))
|
||||
case let .Fixed(i):
|
||||
var length = fixed.prefix.characters.count
|
||||
var results: [Cofree<String, Range<Int>>] = []
|
||||
for value in i {
|
||||
if results.count > 0 {
|
||||
length += fixed.separator.characters.count
|
||||
}
|
||||
results.append(value.map {
|
||||
($0.startIndex + length)..<($0.endIndex + length)
|
||||
})
|
||||
length += value.extract.count
|
||||
}
|
||||
return Cofree(0..<(length + fixed.suffix.characters.count), .Fixed(results))
|
||||
case let .Keyed(k):
|
||||
var length = keyed.prefix.characters.count
|
||||
var results: [(String, Cofree<String, Range<Int>>)] = []
|
||||
@ -105,6 +124,10 @@ extension UnannotatedTerm: Arbitrary {
|
||||
return Cofree((), .Indexed(i.reduce(true) { $0 && equal($1) }
|
||||
? i.dropLast().map { $1 }
|
||||
: i.map { $1 }))
|
||||
case let .Fixed(i):
|
||||
return Cofree((), .Fixed(i.reduce(true) { $0 && equal($1) }
|
||||
? i.dropLast().map { $1 }
|
||||
: i.map { $1 }))
|
||||
case let .Keyed(k):
|
||||
return Cofree((), .Keyed(Dictionary(elements: k.reduce(true) { $0 && equal($1.1) }
|
||||
? k.dropLast().map { ($0, $1.1) }
|
||||
|
Loading…
Reference in New Issue
Block a user