mirror of
https://github.com/flynx/diff.js.git
synced 2025-10-29 19:10:11 +00:00
preliminary format pattern complete...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
c2949d3d35
commit
27a9ec0e47
35
diff.js
35
diff.js
@ -251,6 +251,14 @@ var proxy = function(path, func){
|
|||||||
// XXX need to avoid recursion...
|
// XXX need to avoid recursion...
|
||||||
// XXX should we avoid backtracking when pattern matching???
|
// XXX should we avoid backtracking when pattern matching???
|
||||||
// ...specifically when working with IN and OF...
|
// ...specifically when working with IN and OF...
|
||||||
|
// XXX diffing a mismatching pattern should yield the exact position
|
||||||
|
// (sub-pattern/rule) that failed and not just the whole pattern...
|
||||||
|
// ...usually a pattern chain fails, i.e. the nested failing pattern
|
||||||
|
// also fails its parent and so on, so it is not a trivial task
|
||||||
|
// getting the source and probably the whole failed chain...
|
||||||
|
// ...might be a good idea to build a trace failure pattern and
|
||||||
|
// store it in .trace in the diff...
|
||||||
|
//
|
||||||
//
|
//
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
var LogicTypeClassPrototype = {
|
var LogicTypeClassPrototype = {
|
||||||
@ -280,9 +288,9 @@ var LogicTypePrototype = {
|
|||||||
|| (obj != null
|
|| (obj != null
|
||||||
&& obj.__cmp__
|
&& obj.__cmp__
|
||||||
&& obj.__cmp__(this, cmp, cache))
|
&& obj.__cmp__(this, cmp, cache))
|
||||||
c.set(obj, res)
|
c.set(obj, !!res)
|
||||||
|
|
||||||
return res
|
return !!res
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,8 +464,8 @@ module.ARRAY =
|
|||||||
var NOT =
|
var NOT =
|
||||||
module.NOT =
|
module.NOT =
|
||||||
object.makeConstructor('NOT', Object.assign(new LogicType(), {
|
object.makeConstructor('NOT', Object.assign(new LogicType(), {
|
||||||
__cmp__: function(obj, cmp){
|
__cmp__: function(obj, cmp, cache){
|
||||||
return !cmp(this.value, obj) },
|
return !cmp(this.value, obj, cache) },
|
||||||
__init__: function(value){
|
__init__: function(value){
|
||||||
this.value = value
|
this.value = value
|
||||||
},
|
},
|
||||||
@ -468,9 +476,9 @@ object.makeConstructor('NOT', Object.assign(new LogicType(), {
|
|||||||
var OR =
|
var OR =
|
||||||
module.OR =
|
module.OR =
|
||||||
object.makeConstructor('OR', Object.assign(new LogicType(), {
|
object.makeConstructor('OR', Object.assign(new LogicType(), {
|
||||||
__cmp__: function(obj, cmp){
|
__cmp__: function(obj, cmp, cache){
|
||||||
for(var m of this.members){
|
for(var m of this.members){
|
||||||
if(cmp(m, obj)){
|
if(cmp(m, obj, cache)){
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -486,9 +494,9 @@ object.makeConstructor('OR', Object.assign(new LogicType(), {
|
|||||||
var AND =
|
var AND =
|
||||||
module.AND =
|
module.AND =
|
||||||
object.makeConstructor('AND', Object.assign(new LogicType(), {
|
object.makeConstructor('AND', Object.assign(new LogicType(), {
|
||||||
__cmp__: function(obj, cmp){
|
__cmp__: function(obj, cmp, cache){
|
||||||
for(var m of this.members){
|
for(var m of this.members){
|
||||||
if(!cmp(m, obj)){
|
if(!cmp(m, obj, cache)){
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -510,14 +518,14 @@ var IN =
|
|||||||
module.IN =
|
module.IN =
|
||||||
object.makeConstructor('IN', Object.assign(new LogicType(), {
|
object.makeConstructor('IN', Object.assign(new LogicType(), {
|
||||||
// XXX add support for other stuff like sets and maps...
|
// XXX add support for other stuff like sets and maps...
|
||||||
__cmp__: function(obj, cmp){
|
__cmp__: function(obj, cmp, cache){
|
||||||
var p = this.value
|
var p = this.value
|
||||||
// XXX make this a break-on-match and not a go-through-the-whole-thing
|
// XXX make this a break-on-match and not a go-through-the-whole-thing
|
||||||
return typeof(obj) == typeof({})
|
return typeof(obj) == typeof({})
|
||||||
&& (p in obj
|
&& (p in obj
|
||||||
|| obj.reduce(function(res, e){
|
|| obj.reduce(function(res, e){
|
||||||
return res === false ?
|
return res === false ?
|
||||||
cmp(p, e)
|
cmp(p, e, cache)
|
||||||
: res }), false) },
|
: res }), false) },
|
||||||
__init__: function(value){
|
__init__: function(value){
|
||||||
this.value = value
|
this.value = value
|
||||||
@ -538,8 +546,8 @@ object.makeConstructor('IN', Object.assign(new LogicType(), {
|
|||||||
var AT =
|
var AT =
|
||||||
module.AT =
|
module.AT =
|
||||||
object.makeConstructor('AT', Object.assign(new LogicType(), {
|
object.makeConstructor('AT', Object.assign(new LogicType(), {
|
||||||
__cmp__: function(obj, cmp){
|
__cmp__: function(obj, cmp, cache){
|
||||||
if(cmp(obj != null ? obj[this.key] : null, this.value)){
|
if(cmp(obj != null ? obj[this.key] : null, this.value, cache)){
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@ -1033,6 +1041,7 @@ module.Types = {
|
|||||||
// the above.
|
// the above.
|
||||||
//
|
//
|
||||||
// NOTE: array path also supports patterns...
|
// NOTE: array path also supports patterns...
|
||||||
|
// XXX should this use cmp(..) or this.cmp(..)
|
||||||
filter: function(diff, filter){
|
filter: function(diff, filter){
|
||||||
// string filter...
|
// string filter...
|
||||||
filter = typeof(filter) == typeof('str') ?
|
filter = typeof(filter) == typeof('str') ?
|
||||||
@ -1169,10 +1178,10 @@ module.Types = {
|
|||||||
// pass options and cache down.
|
// pass options and cache down.
|
||||||
// see cache setup below...
|
// see cache setup below...
|
||||||
|| (diff(a, b) == null) }
|
|| (diff(a, b) == null) }
|
||||||
|
|
||||||
// cache...
|
// cache...
|
||||||
//cache = this.__cache = cache || this.__cache || new Map()
|
//cache = this.__cache = cache || this.__cache || new Map()
|
||||||
cache = cache || new Map()
|
cache = cache || new Map()
|
||||||
|
// cached diff...
|
||||||
var diff = cache.diff = cache.diff || function(a, b){
|
var diff = cache.diff = cache.diff || function(a, b){
|
||||||
var l2 = cache.get(a) || new Map()
|
var l2 = cache.get(a) || new Map()
|
||||||
var d = l2.get(b) || that.diff(a, b, options, cache)
|
var d = l2.get(b) || that.diff(a, b, options, cache)
|
||||||
|
|||||||
114
format.js
114
format.js
@ -20,9 +20,14 @@ var {
|
|||||||
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
// XXX need better mismatch checking -- ideally stating the exact spot
|
|
||||||
// where we did not match...
|
|
||||||
//
|
//
|
||||||
|
// XXX need better mismatch checking -- ideally stating the exact spot
|
||||||
|
// where we did not match and the path of fails it created...
|
||||||
|
// XXX idea: would be nice to be able to use patterns to extract values
|
||||||
|
// from structures (parsing)...
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Flat diff...
|
||||||
|
|
||||||
var VALUE =
|
var VALUE =
|
||||||
module.VALUE = OR(
|
module.VALUE = OR(
|
||||||
@ -31,39 +36,108 @@ module.VALUE = OR(
|
|||||||
ANY)
|
ANY)
|
||||||
|
|
||||||
|
|
||||||
|
var SIDE_VALUES =
|
||||||
|
module.SIDE_VALUES = OR(
|
||||||
|
// A and B...
|
||||||
|
AND(
|
||||||
|
AT('A', VALUE),
|
||||||
|
AT('B', VALUE)),
|
||||||
|
// only A...
|
||||||
|
AT('A', VALUE),
|
||||||
|
// only B...
|
||||||
|
AT('B', VALUE))
|
||||||
|
|
||||||
var CHANGE =
|
var CHANGE =
|
||||||
module.CHANGE = AND(
|
module.CHANGE = AND(
|
||||||
AT('path', ARRAY),
|
AT('path', ARRAY),
|
||||||
// XXX optional...
|
// XXX optional...
|
||||||
// ...see DIFF_OBJECT's options for description...
|
// ...see DIFF_OBJECT's options for description...
|
||||||
AT('type', OR(STRING, undefined)),
|
AT('type', OR(STRING, undefined)),
|
||||||
OR(
|
SIDE_VALUES)
|
||||||
// A ans B...
|
|
||||||
AND(
|
|
||||||
AT('A', VALUE),
|
|
||||||
AT('B', VALUE)),
|
|
||||||
// only A...
|
|
||||||
AT('A', VALUE),
|
|
||||||
// only B...
|
|
||||||
AT('B', VALUE)))
|
|
||||||
|
|
||||||
|
|
||||||
var DIFF_FORMAT_FLAT =
|
var DIFF_FLAT =
|
||||||
module.DIFF_FORMAT_FLAT = ARRAY(CHANGE)
|
module.DIFF_FLAT = OR(
|
||||||
|
ARRAY(CHANGE),
|
||||||
|
null)
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Tree diff...
|
||||||
|
|
||||||
|
var BASIC_CHANGE =
|
||||||
|
module.BASIC_CHANGE = AND(
|
||||||
|
AT('type', 'Basic'),
|
||||||
|
SIDE_VALUES)
|
||||||
|
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
var OBJECT_ITEM =
|
||||||
|
module.OBJECT_ITEM = OR(
|
||||||
|
[STRING, DIFF_TREE],
|
||||||
|
[STRING, STRING, DIFF_TREE])
|
||||||
|
|
||||||
|
var OBJECT_CHANGE =
|
||||||
|
module.OBJECT_CHANGE = AND(
|
||||||
|
AT('type', 'Object'),
|
||||||
|
AT('items', ARRAY(OBJECT_ITEM)),
|
||||||
|
// XXX
|
||||||
|
AT('item_order', undefined))
|
||||||
|
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
var ARRAY_ITEM =
|
||||||
|
module.ARRAY_ITEM = OR(
|
||||||
|
[ANY, ANY, DIFF_TREE],
|
||||||
|
[[ANY, NUMBER], [ANY, NUMBER], DIFF_TREE])
|
||||||
|
|
||||||
|
var ARRAY_ITEMS =
|
||||||
|
module.ARRAY_ITEMS = AND(
|
||||||
|
AT('length', OR(
|
||||||
|
[NUMBER, NUMBER],
|
||||||
|
undefined)),
|
||||||
|
AT('items', ARRAY(
|
||||||
|
OR(
|
||||||
|
ARRAY_ITEM,
|
||||||
|
OBJECT_ITEM))),
|
||||||
|
// XXX
|
||||||
|
AT('item_order', undefined))
|
||||||
|
|
||||||
|
var ARRAY_CHANGE =
|
||||||
|
module.ARRAY_CHANGE = AND(
|
||||||
|
AT('type', 'Array'),
|
||||||
|
ARRAY_ITEMS)
|
||||||
|
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
var TEXT_CHANGE =
|
||||||
|
module.TEXT_CHANGE = AND(
|
||||||
|
AT('type', 'Text'),
|
||||||
|
ARRAY_ITEMS)
|
||||||
|
|
||||||
// XXX it makes sense to make this a recursive pattern...
|
// XXX it makes sense to make this a recursive pattern...
|
||||||
// ...need to check if we stop on a recursive pattern...
|
// ...need to check if we stop on a recursive pattern...
|
||||||
var DIFF_FORMAT_TREE =
|
// XXX TEST!!!
|
||||||
module.DIFF_FORMAT_TREE = ANY
|
var DIFF_TREE =
|
||||||
|
module.DIFF_TREE = OR(
|
||||||
|
BASIC_CHANGE,
|
||||||
|
OBJECT_CHANGE,
|
||||||
|
ARRAY_CHANGE,
|
||||||
|
TEXT_CHANGE,
|
||||||
|
null)
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Diff...
|
||||||
|
|
||||||
var DIFF_OBJECT =
|
var DIFF_OBJECT =
|
||||||
module.DIFF_OBJECT = AND(
|
module.DIFF_OBJECT = AND(
|
||||||
|
// format metadata...
|
||||||
AT('format', diff.FORMAT_NAME),
|
AT('format', diff.FORMAT_NAME),
|
||||||
//AT('version', STRING(/\d+\.\d+\.\d+/)),
|
//AT('version', STRING(/\d+\.\d+\.\d+/)),
|
||||||
AT('version', diff.FORMAT_VERSION),
|
AT('version', diff.FORMAT_VERSION),
|
||||||
|
|
||||||
|
// instance metadata...
|
||||||
AT('options', AND(
|
AT('options', AND(
|
||||||
AT('tree_diff', OR(BOOL, null)),
|
AT('tree_diff', OR(BOOL, null)),
|
||||||
AT('keep_none', OR(BOOL, null)),
|
AT('keep_none', OR(BOOL, null)),
|
||||||
@ -74,18 +148,20 @@ module.DIFF_OBJECT = AND(
|
|||||||
AT('no_length', OR(BOOL, null)),
|
AT('no_length', OR(BOOL, null)),
|
||||||
AT('cmp', OR(FUNCTION, null)) )),
|
AT('cmp', OR(FUNCTION, null)) )),
|
||||||
AT('placeholders', AND(
|
AT('placeholders', AND(
|
||||||
// XXX would be nice to store these and to use them to test later...
|
// XXX would be nice to store these and to use them to test
|
||||||
|
// deeper stuff (i.e. VALUE)...
|
||||||
AT('NONE', ANY),
|
AT('NONE', ANY),
|
||||||
AT('EMPTY', ANY))),
|
AT('EMPTY', ANY))),
|
||||||
|
|
||||||
AT('timestamp', NUMBER),
|
AT('timestamp', NUMBER),
|
||||||
|
|
||||||
|
// diff...
|
||||||
OR(
|
OR(
|
||||||
AND(
|
AND(
|
||||||
AT('structure', 'flat'),
|
AT('structure', 'flat'),
|
||||||
AT('diff', DIFF_FORMAT_FLAT)),
|
AT('diff', DIFF_FLAT)),
|
||||||
AND(
|
AND(
|
||||||
AT('structure', 'tree'),
|
AT('structure', 'tree'),
|
||||||
AT('diff', DIFF_FORMAT_TREE))) )
|
AT('diff', DIFF_TREE))) )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user