Browse Source

removed wrapping for Xml nodes, use instead specific compare when comparing two typed nodes (fixed issue #779)

Nicolas Cannasse 13 years ago
parent
commit
ac81c55d9b
4 changed files with 40 additions and 31 deletions
  1. 1 0
      doc/CHANGES.txt
  2. 14 4
      genswf9.ml
  3. 22 27
      std/flash/_std/Xml.hx
  4. 3 0
      tests/unit/TestXML.hx

+ 1 - 0
doc/CHANGES.txt

@@ -7,6 +7,7 @@
 	js/php/flash8 : fixed haxe.Int32.mul overflow on 52 bits
 	js : forbid static 'length' (issue since object is a Function)
 	all : does not allow overriding var/prop
+	flash : removed wrapping for Xml nodes, use instead specific compare when comparing two typed nodes
 
 2012-04-14: 2.09
 	all : optimized const == const and const != const (with different const types)

+ 14 - 4
genswf9.ml

@@ -970,7 +970,7 @@ let rec gen_expr_content ctx retval e =
 		getvar ctx (gen_access ctx e Read);
 		coerce ctx (classify ctx e.etype)
 	| TBinop (op,e1,e2) ->
-		gen_binop ctx retval op e1 e2 e.etype
+		gen_binop ctx retval op e1 e2 e.etype e.epos
 	| TCall (f,el) ->
 		gen_call ctx retval f el e.etype
 	| TNew ({ cl_path = [],"Array" },_,[]) ->
@@ -1511,7 +1511,7 @@ and check_binop ctx e1 e2 =
 	| _ -> false) in
 	if invalid then error "Comparison of Int and UInt might lead to unexpected results" (punion e1.epos e2.epos);
 
-and gen_binop ctx retval op e1 e2 t =
+and gen_binop ctx retval op e1 e2 t p =
 	let write_op op =
 		let iop = (match op with
 			| OpAdd -> Some A3OIAdd
@@ -1553,6 +1553,16 @@ and gen_binop ctx retval op e1 e2 t =
 		gen_expr ctx true e2;
 		write ctx (HOp o)
 	in
+	let gen_eq() =
+		match e1.eexpr, e2.eexpr with
+		| TConst TNull, _  | _ , TConst TNull -> gen_op A3OEq
+		| _ ->
+		match follow e1.etype, follow e2.etype with		
+		| TInst ({ cl_path = [],"Xml" } as c,_) , _ | _ , TInst ({ cl_path = [],"Xml" } as c,_) ->
+			gen_expr ctx true (mk (TCall (mk (TField (mk (TTypeExpr (TClassDecl c)) t_dynamic p,"compare")) t_dynamic p,[e1;e2])) ctx.com.basic.tbool p);
+		| _ ->
+			gen_op A3OEq
+	in
 	match op with
 	| OpAssign ->
 		let acc = gen_access ctx e1 Write in
@@ -1587,9 +1597,9 @@ and gen_binop ctx retval op e1 e2 t =
 		gen_expr ctx true e2;
 		write_op op
 	| OpEq ->
-		gen_op A3OEq
+		gen_eq()
 	| OpNotEq ->
-		gen_op A3OEq;
+		gen_eq();
 		write ctx (HOp A3ONot)
 	| OpGt ->
 		gen_op A3OGt

+ 22 - 27
std/flash/_std/Xml.hx

@@ -44,7 +44,6 @@ enum XmlType {
 	public var nodeValue(getNodeValue,setNodeValue) : String;
 	public var parent(getParent,null) : Xml;
 
-	var _map : flash.utils.Dictionary;
 	var _node : flash.xml.XML;
 
 	public static function parse( str : String ) : Xml {
@@ -66,40 +65,44 @@ enum XmlType {
 					throw e;
 			}
 		}
-		return wrap( null, root, Xml.Document );
+		return wrap( root, Xml.Document );
+	}
+	
+	static function compare( a : Xml, b : Xml ) : Bool {
+		return a == null ? b == null : (b == null ? false : a._node == b._node);
 	}
 
 	private function new() : Void {}
 
 	public static function createElement( name : String ) : Xml {
-		return wrap( null, new flash.xml.XML("<"+name+"/>"), Xml.Element );
+		return wrap( new flash.xml.XML("<"+name+"/>"), Xml.Element );
 	}
 
 	public static function createPCData( data : String ) : Xml {
 		XML.ignoreWhitespace = false;
-		return wrap( null, new flash.xml.XML(data), Xml.PCData );
+		return wrap( new flash.xml.XML(data), Xml.PCData );
 	}
 
 	public static function createCData( data : String ) : Xml {
-		return wrap( null, new flash.xml.XML("<![CDATA["+data+"]]>"), Xml.CData );
+		return wrap( new flash.xml.XML("<![CDATA["+data+"]]>"), Xml.CData );
 	}
 
 	public static function createComment( data : String ) : Xml {
 		XML.ignoreComments = false;
-		return wrap( null, new flash.xml.XML("<!--"+data+"-->"), Xml.Comment );
+		return wrap( new flash.xml.XML("<!--"+data+"-->"), Xml.Comment );
 	}
 
 	public static function createDocType( data : String ) : Xml {
-		return wrap( null, new flash.xml.XML("<!DOCTYPE "+data+">"), Xml.DocType );
+		return wrap( new flash.xml.XML("<!DOCTYPE "+data+">"), Xml.DocType );
 	}
 
 	public static function createProlog( data : String ) : Xml {
 		XML.ignoreProcessingInstructions = false;
-		return wrap( null, new flash.xml.XML("<?"+data+"?>"), Xml.Prolog );
+		return wrap( new flash.xml.XML("<?"+data+"?>"), Xml.Prolog );
 	}
 
 	public static function createDocument() : Xml {
-		return wrap( null, new flash.xml.XML("<__document/>"), Xml.Document );
+		return wrap( new flash.xml.XML("<__document/>"), Xml.Document );
 	}
 
 	private static function getNodeType( node : flash.xml.XML ) : XmlType {
@@ -170,33 +173,25 @@ enum XmlType {
 			untyped __delete__(children, Reflect.fields(children)[i]);
 		}
 		_node = x._node;
-		untyped _map[_node] = this;
 		return v;
 	}
 
 	private function getParent() :Xml {
 		var p = _node.parent();
-		return p == null ? null : wrap( _map, p );
-	}
-
-	private static function wrap( map : flash.utils.Dictionary, node : XML, ?type : XmlType ) : Xml {
-		if( map == null )
-			map = new flash.utils.Dictionary();
-		var x : Xml = untyped map[node];
-		if( x == null ) {
-			x = new Xml();
-			x._node = node;
-			x._map = map;
-			x.nodeType = (type != null) ? type : getNodeType( node );
-			untyped map[node] = x;
-		}
+		return p == null ? null : wrap( p );
+	}
+
+	private static function wrap( node : XML, ?type : XmlType ) : Xml {
+		var x = new Xml();
+		x._node = node;
+		x.nodeType = (type != null) ? type : getNodeType( node );
 		return x;
 	}
 
 	private function wraps( xList : XMLList ) : Array<Xml> {
 		var out = new Array<Xml>();
 		for( i in 0...xList.length() )
-			out.push( wrap(_map,xList[i]) );
+			out.push( wrap(xList[i]) );
 		return out;
 	}
 
@@ -351,7 +346,7 @@ enum XmlType {
 			throw "bad nodetype";
 		if( children.length() == 0 )
 			return null;
-		return wrap( _map, children[0] );
+		return wrap( children[0] );
 	}
 
 	public function firstElement() : Xml {
@@ -360,7 +355,7 @@ enum XmlType {
 			throw "bad nodetype";
 		if( elements.length() == 0 )
 			return null;
-		return wrap( _map, elements[0] );
+		return wrap( elements[0] );
 	}
 
 	public function addChild( x : Xml ) : Void {

+ 3 - 0
tests/unit/TestXML.hx

@@ -13,12 +13,15 @@ class TestXML extends Test {
 	function testBasic() {
 		var x = Xml.parse('<a href="hello">World<b/></a>');
 
+		t( x.firstChild() == x.firstChild() );
+		
 		eq( x.nodeType, Xml.Document );
 		checkExc(x);
 
 		x = x.firstChild();
 		eq( x.nodeType, Xml.Element );
 
+		
 		// nodeName
 		eq( x.nodeName, "a" );
 		x.nodeName = "b";