This is an automated email from the ASF dual-hosted git repository. gregdove pushed a commit to branch improvements/Language in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
commit beac5c6040697c971ab371d5018fe13c59ec1895 Author: greg-dove <[email protected]> AuthorDate: Thu May 23 18:22:36 2019 +1200 Vector improvements and optimizations (runtime performance, output footprint) --- .../royale/org/apache/royale/utils/Language.as | 298 ++++++++++++++------- .../language/LanguageTesterTestVector.as | 61 +++++ .../flexUnitTests/xml/XMLTesterGeneralTest.as | 2 +- 3 files changed, 263 insertions(+), 98 deletions(-) diff --git a/frameworks/projects/Language/src/main/royale/org/apache/royale/utils/Language.as b/frameworks/projects/Language/src/main/royale/org/apache/royale/utils/Language.as index f21cfce..796cdc6 100644 --- a/frameworks/projects/Language/src/main/royale/org/apache/royale/utils/Language.as +++ b/frameworks/projects/Language/src/main/royale/org/apache/royale/utils/Language.as @@ -36,6 +36,7 @@ package org.apache.royale.utils /** * @royaleignoreimport goog.bind * @royaleignoreimport goog.global + * @royalesuppressexport */ COMPILE::JS public class Language @@ -88,8 +89,8 @@ package org.apache.royale.utils if (leftOperand == null) { return null; } - const leftType:String = leftOperand.ROYALE_CLASS_INFO ? leftOperand.ROYALE_CLASS_INFO.names[0].qName : String(leftOperand); - const rightType:String = rightOperand.prototype && rightOperand.prototype.ROYALE_CLASS_INFO ? rightOperand.prototype.ROYALE_CLASS_INFO.names[0].qName: String(rightOperand); + const leftType:String = '' + (leftOperand.ROYALE_CLASS_INFO ? leftOperand.ROYALE_CLASS_INFO.names[0].qName : String(leftOperand)); + const rightType:String = '' + (rightOperand.prototype && rightOperand.prototype.ROYALE_CLASS_INFO ? rightOperand.prototype.ROYALE_CLASS_INFO.names[0].qName: String(rightOperand)); throw new TypeError('Error #1034: Type Coercion failed: cannot convert ' + leftType + ' to ' + rightType); } @@ -225,9 +226,9 @@ package org.apache.royale.utils return false; } - /** + /*/!** * Implementation of "classDef is Class" - */ + *!/ public function isClass(classDef:*):Boolean { return typeof classDef === 'function' @@ -235,13 +236,13 @@ package org.apache.royale.utils && classDef.prototype.constructor === classDef; } - /** + /!** * Implementation of "classDef as Class" - */ + *!/ public function asClass(classDef:*):Class { return isClass(classDef) ? classDef : null; - } + }*/ /** * @royaledebug @@ -458,7 +459,12 @@ package org.apache.royale.utils } return 0; } - + + + /** + * no export (allow dead code elimination): + * @royalesuppressexport + */ public static function resolveUncertain(val:*):* { if (val) { @@ -469,12 +475,20 @@ package org.apache.royale.utils } private static var _synthType:Class; + /** + * @royalesuppressexport + */ public static const SYNTH_TAG_FIELD:String = goog.DEBUG ? '_synthType' : '_s'; + /** + * @royalesuppressexport + */ public static const CHECK_INDEX:String = goog.DEBUG ? 'chkIdx' : '_ci'; /** * * @royalesuppressresolveuncertain true, _synthType + * no export (allow dead code elimination): + * @royalesuppressexport */ public static function synthType(typeName:String, newDefinition:*):Class { @@ -525,6 +539,8 @@ package org.apache.royale.utils /** * @royaleignorecoercion Array + * no export (allow dead code elimination): + * @royalesuppressexport */ public static function synthVector(elementType:String):Class { @@ -543,7 +559,7 @@ package org.apache.royale.utils instance = a[--l]; fixed = l == 2 ? a[--l] : false; size = l == 1 ? a[0] : 0; - instance[VectorSupport.ELEMENT_TYPE] = elementType; + //instance[VectorSupport.ELEMENT_TYPE] = elementType; instance['type'] = typeName; instance[VectorSupport.FIXED_LEN] = fixed ? size : -1; return VectorSupport.arrayVector([], size, elementType, fixed, instance); @@ -565,7 +581,7 @@ package org.apache.royale.utils }, 'noWrap': true }); - VectorSupport.vectorElementCoercion(elementType, type); + VectorSupport.vectorElementCoercion(elementType, type, false); VectorSupport.vectorElementDefault(elementType, type); type.prototype = Object.create(type.prototype); const baseVectorOverrides:Object = VectorSupport.getBaseOverrides(); @@ -585,7 +601,9 @@ package org.apache.royale.utils 'constructor': { value:type } }; localOverrides[Language.CHECK_INDEX] = {value:baseVectorOverrides[Language.CHECK_INDEX]}; - localOverrides[VectorSupport.COERCE_ELEMENT] = { value: type[VectorSupport.COERCE_ELEMENT] }; + localOverrides[VectorSupport.ELEMENT_TYPE] = { value: elementType }; + localOverrides['type'] = { value: typeName }; + localOverrides[VectorSupport.COERCE_ELEMENT] = { value: type[VectorSupport.COERCE_ELEMENT], configurable: true}; localOverrides[VectorSupport.DEFAULT_VALUE] = { value: type[VectorSupport.DEFAULT_VALUE] }; Object.defineProperties(type.prototype, localOverrides) @@ -600,6 +618,8 @@ package org.apache.royale.utils * This could be used to create and return a Vector instance * * @royaleignorecoercion Array + * no export (allow dead code elimination): + * @royalesuppressexport */ public static function Vector(size:int = 0, baseType:String = null, fixed:Boolean = false):* { @@ -615,27 +635,51 @@ import goog.DEBUG; import goog.global; COMPILE::JS +/** + * @royalesuppressexport + */ class VectorSupport { //Warning : code in this class is very dependent on non-generation of closures and possibly other 'quirks' //If you make any changes, please verify this against Vector unit tests, across different targets + /** + * @royalesuppressexport + */ public static const fixedRangeError:String = 'Error #1126: Cannot change the length of a fixed Vector'; + /** + * @royalesuppressexport + */ public static const nonConstructorError:String = 'Error #1007: Instantiation attempted on a non-constructor.'; - + /** + * @royalesuppressexport + */ public static var langSynthType:Object; + /** + * @royalesuppressexport + */ public static const COERCE_ELEMENT:String = goog.DEBUG ? 'coerceElement' : 'cE'; + /** + * @royalesuppressexport + */ public static const DEFAULT_VALUE:String = goog.DEBUG ? 'defaultValue' : 'dV'; + /** + * @royalesuppressexport + */ public static const ELEMENT_TYPE:String = goog.DEBUG ? 'elementType' : 'eT'; - + /** + * @royalesuppressexport + */ public static const FIXED_LEN:String = goog.DEBUG ? 'fixedLen' : 'fL'; private static function indexRangerError(index:Number, limit:uint):String{ return 'Error #1125: The index ' + index + ' is out of range ' + limit; } - + /** + * @royalesuppressexport + */ public static function checkIsVector(v:Array, typeName:String):Boolean { const base:Boolean = v && Language.SYNTH_TAG_FIELD in v; @@ -647,7 +691,9 @@ class VectorSupport { } return ret; } - + /** + * @royalesuppressexport + */ public static function vectorElementDefault(elementType:String, synthVectorClass:Object ):Object { if (synthVectorClass[VectorSupport.DEFAULT_VALUE] !== undefined) return synthVectorClass[VectorSupport.DEFAULT_VALUE]; const standardDefaults:Object = { @@ -667,9 +713,10 @@ class VectorSupport { /** * - * @royaleignorecoercion Function + * @royaleignorecoercion Function + * @royalesuppressexport */ - public static function vectorElementCoercion(elementType:String, synthVectorClass:Object ):Function{ + public static function vectorElementCoercion(elementType:String, synthVectorClass:Object, deferred:Boolean):Function{ if (synthVectorClass[VectorSupport.COERCE_ELEMENT]) return synthVectorClass[VectorSupport.COERCE_ELEMENT] as Function; const identity:Function = function(v:*):Object{return v === undefined ? null : v}; const standardCoercions:Object = { @@ -686,17 +733,29 @@ class VectorSupport { if (elementType.indexOf('Vector.<') == 0) { coercion = function(v:Object):Object{ if (!(v === null || Language.synthVector(elementType.slice(8,-1))['checkIs'](v))) {throw new TypeError('Error #1034: Type Coercion failed: cannot convert ' + v + ' to '+ elementType)} else return v }; } else { + var defer:Boolean = false; var parts:Array = elementType.split('.'); var n:int = parts.length; var o:Class = goog.global; for (var i:int = 0; i < n; i++) { o = o && o[parts[i]]; - if (!o) throw new TypeError('missing dependency ' + elementType ); + if (!o) { + if (deferred) throw new TypeError('missing dependency ' + elementType ); + defer = true; + break; + } } - coercion = function(v:Object):Object{ return Language.as(v,o,true)}; + if (defer) { + coercion = null; + } + else coercion = function(v:Object):Object{ return Language.as(v,o,true)}; } } synthVectorClass[VectorSupport.COERCE_ELEMENT] = coercion; + if (deferred) { + //patch the prototype + Object.defineProperty(synthVectorClass.prototype, VectorSupport.COERCE_ELEMENT, {value: coercion}) + } return coercion; } @@ -704,7 +763,10 @@ class VectorSupport { * @royaleignorecoercion Function */ private static function coerceElements(arr:Array, size:uint, tag:Object):Error{ - const coercion:Function = tag[COERCE_ELEMENT] as Function; + var coercion:Function = tag[COERCE_ELEMENT] as Function; + if (coercion == null) { + coercion = VectorSupport.vectorElementCoercion(tag[ELEMENT_TYPE], tag.constructor, true); + } var err:Error; for (var i:int = 0; i < size; i++) { @@ -726,13 +788,16 @@ class VectorSupport { /** * @royaleignorecoercion Function + * @royalesuppressexport */ - public static function arrayVector(arr:Array, size:int = 0, basetype:String = null, fixed:Boolean = false, tag:Object = null, construct:Boolean = true):Array + public static function arrayVector(arr:Array, size:int, basetype:String,fixed:Boolean , tag:Object, construct:Boolean = true):Array { - if (basetype === null) + size = size >>>0; + if (basetype == null) { throw new TypeError(nonConstructorError); } + tagVectorArray(arr, basetype, fixed, tag); if (!tag) tag = arr[Language.SYNTH_TAG_FIELD]; if (size) @@ -750,7 +815,10 @@ class VectorSupport { } return arr; } - + /** + * @royalesuppressexport + * @royalesuppressclosure + */ public static function tagVectorArray(array:Array, elementType:String, fixed:Boolean, inst:Object):Array { const vectorType:String ='Vector.<' + elementType + '>'; @@ -763,7 +831,12 @@ class VectorSupport { const props:Object = { 'fixed': { 'get' : function():Boolean{return inst[FIXED_LEN] > -1}, - 'set' : function(v:Boolean):void{ inst[FIXED_LEN]= (v ? array.length : -1)} + 'set' : function(v:Boolean):void{ + if (inst[FIXED_LEN] > -1 != v) { + inst[FIXED_LEN]= (v ? array.length : -1); + Object.defineProperties(array,getMutationTypeSafetyOverrides(v)); + } + } }, 'splice': { value: inst.splice @@ -793,21 +866,7 @@ class VectorSupport { props[Language.SYNTH_TAG_FIELD] = { value: inst }; - blend(props, getMainTypeSafetyOverrides()); - //possible future runtime performance tuning based on compilation 'define' setting tweaks - /* if (Language.runtimeVectorSafety) { - blend(props, getMainTypeSafetyOverrides()) - } else { - blend(props, { - 'insertAt':{ - value: inst.insertAt - }, - 'removeAt':{ - value: inst.removeAt - } - }) - }*/ - + blend(props, getMutationTypeSafetyOverrides(fixed)); Object.defineProperties (array, props); return array; } @@ -816,7 +875,7 @@ class VectorSupport { /** * Fills the array from a start point (defaults to zero) to its end with the specified value */ - public static function array_fill(arr:Array, value:Object, start:uint):Array{ + private static function array_fill(arr:Array, value:Object, start:uint):Array{ if (arr['fill']) { return arr['fill'](value, start); } else { @@ -832,68 +891,102 @@ class VectorSupport { } //The instance methods of this class are primarily a source for runtime patching of 'Vector-like' Arrays - //The class uses some indirection to avoid the royale compiler generating closures and therefore references to 'this' + //The class uses @royalesuppressclosure to avoid the royale compiler generating closures and therefore references to 'this' //in the local methods can become references to the Array instance itself in its patched methods //with the exception of the get_len and set_len methods where 'this' refers to the instance of the 'synthType' tag //attached to the Array that is considered 'Vector-like' private static var _instance:VectorSupport; private static var _baseObject:Object; + /** + * @royalesuppressexport + * prevent closure generation for the method references: + * @royalesuppressclosure + */ public static function getBaseOverrides():Object{ if (_baseObject) return _baseObject; _instance = new VectorSupport(); _baseObject = {}; - _baseObject.toString = _instance['toString']; - _baseObject.map = _instance['map']; - _baseObject.splice = _instance['splice']; - _baseObject.slice = _instance['slice']; - _baseObject.concat = _instance['concat']; - _baseObject.filter = _instance['filter']; - _baseObject.uncheckedInsertAt = _instance['uncheckedInsertAt']; - _baseObject.uncheckedRemoveAt = _instance['uncheckedRemoveAt']; - _baseObject.get_len = _instance['get_len']; - _baseObject.set_len = _instance['set_len']; - _baseObject[Language.CHECK_INDEX] = _instance['chkIdx']; + var inst:VectorSupport = _instance; + _baseObject.toString = inst.toString; + _baseObject.map = inst.map; + _baseObject.splice = inst.splice; + _baseObject.slice = inst.slice; + _baseObject.concat = inst.concat; + _baseObject.filter = inst.filter; + _baseObject.uncheckedInsertAt = inst.uncheckedInsertAt; + _baseObject.uncheckedRemoveAt = inst.uncheckedRemoveAt; + _baseObject.get_len = inst.get_len; + _baseObject.set_len = inst.set_len; + _baseObject[Language.CHECK_INDEX] = inst.chkIdx; return _baseObject; } - private static var _fixedLenObject:Object; - public static function getMainTypeSafetyOverrides():Object{ - if (_fixedLenObject) return _fixedLenObject; - _fixedLenObject = { + private static var _nonFixedTypeSafetyOverrides:Object; + private static var _fixedTypeSafetyOverrides:Object; + /** + * @royalesuppressexport + * @royalesuppressclosure + */ + public static function getMutationTypeSafetyOverrides(fixed:Boolean):Object{ + if (_nonFixedTypeSafetyOverrides) return fixed ? _fixedTypeSafetyOverrides : _nonFixedTypeSafetyOverrides; + var inst:VectorSupport = _instance; + _nonFixedTypeSafetyOverrides = { 'pop': { - value:_instance['pop'] + value:Array.prototype.pop, + configurable: true }, 'push': { - value:_instance['push'] + value:inst.push, + configurable: true }, 'shift': { - value:_instance['shift'] + value:Array.prototype.shift, + configurable: true }, 'unshift': { - value:_instance['unshift'] + value:inst.unshift, + configurable: true }, 'insertAt': { - value:_instance['insertAt'] + value:inst.insertAt, + configurable: true }, 'removeAt': { - value:_instance['removeAt'] + value:inst.removeAt, + configurable: true } }; - return _fixedLenObject; + const error:Object = { + value:inst.throwRangeError, + configurable: true + }; + _fixedTypeSafetyOverrides ={ + 'pop': error, + 'push': error, + 'shift': error, + 'unshift': error, + 'insertAt': error, + 'removeAt': error + }; + return fixed ? _fixedTypeSafetyOverrides : _nonFixedTypeSafetyOverrides; } - + /** + * @royalesuppressexport + */ public function toString():String{ return Array.prototype.map.call(this, String).toString(); } /** * @royaleignorecoercion Array + * @royalesuppressexport */ public function map(callback:Function):* { var inst:Object= this[Language.SYNTH_TAG_FIELD]; return tagVectorArray(Array.prototype.map.call(this, function(item:Object, index:int, source:*):Object{return inst[COERCE_ELEMENT](callback(item,index,source))}) as Array, inst[ELEMENT_TYPE],false,null); } /** * @royaleignorecoercion Array + * @royalesuppressexport */ public function splice():* { var a:Array = Array.prototype.slice.call(arguments) as Array;var inst:Object= this[Language.SYNTH_TAG_FIELD]; var ret:Array = Array.prototype.splice.apply(this, a) as Array; if (inst[FIXED_LEN] > -1) inst[FIXED_LEN] = this['length']; return tagVectorArray(ret, inst[ELEMENT_TYPE], false, null); @@ -901,6 +994,7 @@ class VectorSupport { /** * @royaleignorecoercion Array + * @royalesuppressexport */ public function slice():* { var a:Array = Array.prototype.slice.call(arguments) as Array;var inst:Object= this[Language.SYNTH_TAG_FIELD]; var ret:Array = Array.prototype.slice.apply(this, a) as Array; return tagVectorArray(ret, inst[ELEMENT_TYPE], false, null); @@ -908,6 +1002,7 @@ class VectorSupport { /** * @royaleignorecoercion Array + * @royalesuppressexport */ public function filter():* { var a:Array = Array.prototype.slice.call(arguments) as Array;var inst:Object= this[Language.SYNTH_TAG_FIELD]; var ret:Array = Array.prototype.filter.apply(this, a) as Array; return tagVectorArray(ret, inst[ELEMENT_TYPE], false, null); @@ -916,6 +1011,7 @@ class VectorSupport { /** * @royaleignorecoercion Array * @royaleignorecoercion String + * @royalesuppressexport */ public function concat():* { var a:Array = Array.prototype.slice.call(arguments) as Array;var inst:Object = this[Language.SYNTH_TAG_FIELD]; @@ -929,15 +1025,21 @@ class VectorSupport { var ret:Array = Array.prototype.concat.apply(this, a) as Array; return tagVectorArray(ret,inst[ELEMENT_TYPE], false, null); } - + /** + * @royalesuppressexport + */ public function uncheckedInsertAt(index:Number,item:*):* { return Array.prototype.splice.call(this, index, 0, item); } - + /** + * @royalesuppressexport + */ public function uncheckedRemoveAt(index:Number):* { return Array.prototype.splice.call(this, index, 1)[0]; } - + /** + * @royalesuppressexport + */ public function get_len():Number{ //'this' inside here is the synthType instance. It has a value property that refers to the //Array instance that it 'tags' @@ -945,6 +1047,7 @@ class VectorSupport { } /** * @royaleignorecoercion Array + * @royalesuppressexport */ public function set_len(value:Number):void{ //'this' here is the synthType instance. It has a value property that refers to the @@ -961,51 +1064,52 @@ class VectorSupport { } //fixed-length vector-like array overrides - public function pop(v:*):* { - if (this[Language.SYNTH_TAG_FIELD][FIXED_LEN] > -1) {throw new RangeError(fixedRangeError)} else return Array.prototype.pop.call(this) - } - - public function shift(v:*):* { - if (this[Language.SYNTH_TAG_FIELD][FIXED_LEN] > -1) {throw new RangeError(fixedRangeError)} else return Array.prototype.shift.call(this) - } - /** * @royaleignorecoercion Array + * @royalesuppressexport */ public function push(v:*):* { - if (this[Language.SYNTH_TAG_FIELD][FIXED_LEN] > -1) {throw new RangeError(fixedRangeError)} else{ - var a:Array = Array.prototype.slice.call(arguments) as Array; - const err:Error = coerceElements(a, a.length, this[Language.SYNTH_TAG_FIELD]); - var len:uint = Array.prototype.push.apply(this,a); - if (err) throw new (err.constructor)(err.message); - return len; - } + var a:Array = Array.prototype.slice.call(arguments) as Array; + const err:Error = coerceElements(a, a.length, this[Language.SYNTH_TAG_FIELD]); + var len:uint = Array.prototype.push.apply(this,a); + if (err) throw new (err.constructor)(err.message); + return len; } /** * @royaleignorecoercion Array + * @royalesuppressexport */ public function unshift(v:*):* { - if (this[Language.SYNTH_TAG_FIELD][FIXED_LEN] > -1) {throw new RangeError(fixedRangeError)} else{ - var a:Array = Array.prototype.slice.call(arguments) as Array; - const err:Error = coerceElements(a, a.length, this[Language.SYNTH_TAG_FIELD]); - var len:uint = Array.prototype.unshift.apply(this,a); - if (err) throw new (err.constructor)(err.message); - return len; - } + var a:Array = Array.prototype.slice.call(arguments) as Array; + const err:Error = coerceElements(a, a.length, this[Language.SYNTH_TAG_FIELD]); + var len:uint = Array.prototype.unshift.apply(this,a); + if (err) throw new (err.constructor)(err.message); + return len; } - + /** + * @royalesuppressexport + */ public function insertAt(index:int, item:*):void { - if (this[Language.SYNTH_TAG_FIELD][FIXED_LEN] > -1) {throw new RangeError(fixedRangeError)} else this[Language.SYNTH_TAG_FIELD]['insertAt'].call(this,index,item) + this[Language.SYNTH_TAG_FIELD]['insertAt'].call(this,index,item); } - + /** + * @royalesuppressexport + */ public function removeAt(index:int):Object { - if (this[Language.SYNTH_TAG_FIELD][FIXED_LEN] > -1) {throw new RangeError(fixedRangeError)} else { - const idx:int = index < 0 ? Math.max(this['length'] + index, 0) : index; - if (idx >= this['length']) throw new RangeError(indexRangerError(index, this['length'])); - return this[Language.SYNTH_TAG_FIELD]['removeAt'].call(this, idx); - } + const idx:int = index < 0 ? Math.max(this['length'] + index, 0) : index; + if (idx >= this['length']) throw new RangeError(indexRangerError(index, this['length'])); + return this[Language.SYNTH_TAG_FIELD]['removeAt'].call(this, idx); + } + /** + * @royalesuppressexport + */ + public function throwRangeError():void{ + throw new RangeError(fixedRangeError); } + /** + * @royalesuppressexport + */ public function chkIdx(index:Number):Number { var limit:Number = this[Language.SYNTH_TAG_FIELD][FIXED_LEN]; var fail:Boolean = index >>> 0 !== index; //fail if not a uint value (also covers negative value range check) diff --git a/manualtests/UnitTests/src/main/royale/flexUnitTests/language/LanguageTesterTestVector.as b/manualtests/UnitTests/src/main/royale/flexUnitTests/language/LanguageTesterTestVector.as index 19af141..3a14564 100644 --- a/manualtests/UnitTests/src/main/royale/flexUnitTests/language/LanguageTesterTestVector.as +++ b/manualtests/UnitTests/src/main/royale/flexUnitTests/language/LanguageTesterTestVector.as @@ -1208,5 +1208,66 @@ package flexUnitTests.language } + //these accessors/methods etc also serve to visually inspect + //the doc comment '@type' annotation in js-debug + //it should be: @type {Array} + protected function get instGetterTest():Vector.<String> { + return new Vector.<String>(); + } + + protected static function get getterTest():Vector.<String> { + return new Vector.<String>(); + } + + + protected function instGetTestVector():Vector.<String> { + return new Vector.<String>(); + } + + protected static function getTestVector():Vector.<String> { + return new Vector.<String>(); + } + + protected var instMyVec:Vector.<String> = new Vector.<String>() ; + + protected static var myVec:Vector.<String> = new Vector.<String>() ; + + protected static var myVec2:Vector.<TestClass1> = new Vector.<TestClass1>() ; + + [Test] + public function testGetter():void{ + var vString:Vector.<String> = instGetterTest; + + Assert.assertTrue('Unexpected Vector check', vString is Vector.<String>); + Assert.assertFalse('Unexpected Vector check', vString is Array); + + vString = instMyVec; + + Assert.assertTrue('Unexpected Vector check', vString is Vector.<String>); + Assert.assertFalse('Unexpected Vector check', vString is Array); + + vString = instGetTestVector(); + + Assert.assertTrue('Unexpected Vector check', vString is Vector.<String>); + Assert.assertFalse('Unexpected Vector check', vString is Array); + + //static + vString = getterTest; + + Assert.assertTrue('Unexpected Vector check', vString is Vector.<String>); + Assert.assertFalse('Unexpected Vector check', vString is Array); + + vString = getTestVector(); + + Assert.assertTrue('Unexpected Vector check', vString is Vector.<String>); + Assert.assertFalse('Unexpected Vector check', vString is Array); + + vString = myVec; + + Assert.assertTrue('Unexpected Vector check', vString is Vector.<String>); + Assert.assertFalse('Unexpected Vector check', vString is Array); + } + + } } diff --git a/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterGeneralTest.as b/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterGeneralTest.as index 356a024..6b2cf8b 100644 --- a/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterGeneralTest.as +++ b/manualtests/UnitTests/src/main/royale/flexUnitTests/xml/XMLTesterGeneralTest.as @@ -700,7 +700,7 @@ package flexUnitTests.xml XML.ignoreComments = false; var xml:XML = new XML('<root><!-- my test comment --></root>'); Assert.assertEquals('unexpected comment result with XML.ignoreComments = false', 1, xml.children().length()); - RoyaleUnitTestRunner.consoleOut(xml.toXMLString()); + Assert.assertEquals('unexpected toXMLString with XML.ignoreComments = false', '<root>\n' + ' <!-- my test comment -->\n' +
