Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

- some progress

  • Loading branch information...
commit 930bbbe829465b031fb57a29e65a02ea07e9b76c 1 parent 5fb41af
@SamuraiJack authored
Showing with 92 additions and 52 deletions.
  1. +2 −0  MANIFEST
  2. +65 −45 lib/Data/Visitor.js
  3. +25 −7 t/010_basics.t.js
View
2  MANIFEST
@@ -1,4 +1,6 @@
Changes
+doc/html/Data/Visitor.html
+doc/mmd/Data/Visitor.txt
inc/Module/Build/Functions.pm
inc/Module/Build/Functions/DSL.pm
inc/Module/Build/JSAN.pm
View
110 lib/Data/Visitor.js
@@ -1,6 +1,5 @@
Class('Data.Visitor', {
-
has : {
seen : Joose.I.Object
},
@@ -8,97 +7,114 @@ Class('Data.Visitor', {
methods : {
+ getClassNameFor : function (object) {
+ if (Joose.O.isInstance(object)) return object.meta.name
+
+ return Object.prototype.toString.call(object).replace(/^\[object /, '').replace(/\]$/, '')
+ },
+
+
visit : function () {
var seen = this.seen
- Joose.A.each(arguments, function (value) {
+ var res = Joose.A.map(arguments, function (value) {
if (value && typeof value == 'object' || typeof value == 'function') {
- var ref = value.__ID__
-
- if (!ref) ref = value.__ID__ = this.my.getRefAddr()
+ var ref = value.__REFADR__
- if (seen[ref])
- this.visitSeen(value)
- else
- this.visitNotSeenObject(value)
+ if (ref != null && seen[ ref ])
+ return this.visitSeen(value, seen[ ref ])
+ else
+ return this.visitNotSeen(value)
} else
- this.visitValue(value)
+ return this.visitValue(value)
}, this)
+
+ return res.length > 1 ? res : res[0]
},
visitValue : function (value) {
+ return value
+ },
+
+
+ visitSeen : function (value, seenResult) {
+ return seenResult
},
- visitSeen : function (value, result) {
+ markSeen : function (object) {
+ this.seen[ object.__REFADR__ ] = object
},
- // XXX also handle RegExp, Date
- visitNotSeenObject : function (value) {
- this.seen[ value.__ID__ ] = value
-
- if (Joose.O.isInstance(value))
- this.visitInstance(value)
- else
- if (value instanceof Array)
- this.visitArray(value)
- else
- if (typeof value == 'function')
- this.visitFunction(value)
- else
- this.visitGenericObject(value)
+ visitNotSeen : function (object) {
+ var className = this.getClassNameFor(object)
+
+ if (!object.__REFADR__) object.__REFADR__ = this.getRefAdrFor(object)
+
+ var REFADR = object.__REFADR__
+
+ this.markSeen(object)
+
+
+ if (Joose.O.isInstance(object)) return this.seen[ REFADR ] = this.visitJooseInstance(object, className)
+
+
+ var methodName = 'visit' + className
+
+ if (!this.meta.hasMethod(methodName)) methodName = 'visitObject'
+
+ return this.seen[ REFADR ] = this[ methodName ](object, className)
},
- visitArray : function (array) {
+ visitArray : function (array, className) {
Joose.A.each(array, function (value, index) {
this.visitArrayEntry(value, index, array)
}, this)
+
+ return array
},
visitArrayEntry : function (value, index, array) {
- this.visit(value)
+ return this.visit(value)
},
- visitGenericObject : function (object) {
+ visitObject : function (object, className) {
Joose.O.eachOwn(object, function (value, key) {
- if (key != '__ID__') {
+ if (key != '__REFADR__' && key != '__ID__') {
this.visitObjectKey(key, value, object)
this.visitObjectValue(value, key, object)
}
}, this)
+
+ return object
},
- visitInstance : function (value) {
- this.visitGenericObject(value)
+ visitJooseInstance : function (value, className) {
+ return this.visitObject(value, className)
},
visitObjectKey : function (key, value, object) {
- this.visitValue(key)
+ return this.visitValue(key)
},
visitObjectValue : function (value, key, object) {
- this.visit(value)
- },
-
-
- visitFunction : function (value) {
- this.visitGenericObject(value)
+ return this.visit(value)
}
},
@@ -106,9 +122,18 @@ Class('Data.Visitor', {
body : function () {
- var ID = 0
+ var REF = 0
this.meta.extend({
+
+ methods : {
+
+ getRefAdrFor : function (object) {
+ return REF++
+ }
+ },
+
+
my : {
has : {
@@ -118,13 +143,8 @@ body : function () {
methods : {
- getRefAddr : function () {
- return ID++
- },
-
-
visit : function () {
- var visitor = new this.HOST()
+ var visitor = new this.HOST()
return visitor.visit.apply(visitor, arguments)
}
View
32 t/010_basics.t.js
@@ -1,6 +1,6 @@
StartTest(function(t) {
- t.plan(1)
+ t.plan(15)
var async0 = t.beginAsync()
@@ -11,6 +11,27 @@ StartTest(function(t) {
t.ok(Data.Visitor, "Data.Visitor is here")
+ var data1 = {}
+ var data2 = []
+ var data3 = 10
+ var data4 = true
+
+ t.ok(data1 === Data.Visitor.my.visit(data1), "Visiting don't modify the data #1")
+ t.ok(data2 === Data.Visitor.my.visit(data2), "Visiting don't modify the data #2")
+ t.ok(data3 === Data.Visitor.my.visit(data3), "Visiting don't modify the data #3")
+ t.ok(data4 === Data.Visitor.my.visit(data4), "Visiting don't modify the data #4")
+
+
+ //======================================================================================================================================================================================================================================================
+ t.diag('N-arity')
+
+ var res = Data.Visitor.my.visit(data1, data2, data3, data4)
+
+ t.ok(data1 === res[0], "Visiting don't modify the data #1")
+ t.ok(data2 === res[1], "Visiting don't modify the data #2")
+ t.ok(data3 === res[2], "Visiting don't modify the data #3")
+ t.ok(data4 === res[3], "Visiting don't modify the data #4")
+
//======================================================================================================================================================================================================================================================
t.diag('Composite structures')
@@ -36,12 +57,9 @@ StartTest(function(t) {
},
- visitArray : function () { arrayCounter++ },
-
- visitInstance : function () { instanceCounter++ },
-
- visitNotSeenObject : function () { objectCounter++ }
-
+ visitArray : function () { arrayCounter++ },
+ visitJooseInstance : function () { instanceCounter++ },
+ visitNotSeen : function () { objectCounter++ }
}
})
Please sign in to comment.
Something went wrong with that request. Please try again.