package com.exanimo.utils { import com.exanimo.utils.IRuntimeType; import flash.utils.describeType; import flash.utils.getQualifiedClassName; /** * * Allows for runtime checking of runtime-defined types. * see * * @langversion ActionScript 3 * @playerversion Flash 9.0.0 * * @author Matthew Tretter * @since 2008.03.17 * */ public class UnionType implements IRuntimeType { private var _types:Array; /** * * */ public function UnionType(...rest:Array) { this._types = []; for each (var type:Object in rest) { this.addType(type); } } // // public methods // /** * * */ public function addType(type:Object):void { // TODO: throw error if type is not class or runtimetype if (this._types.indexOf(type) == -1) { this._types.push(type); } } /** * * * */ public function describes(obj:Object):Boolean { var describes:Boolean = false; for each (var type:Object in this._types) { if (type is Class) { describes = obj is Class; } else if (type is IRuntimeType) { describes = type.describes(obj); } if (describes) break; } return describes; } /** * * */ public function describesType(type:Object):Boolean { var typeName:String = getQualifiedClassName(type); for each (var t:Object in this._types) { if (t is Class) { if (t == type) return true; // Does t extend type? var description:XML = describeType(t); if (description.factory.extendsClass.(attribute('type') == typeName).length()) { return true; } } else if (t is IRuntimeType) { // If the types are equal, return true. if (t.equals(type) || t.describesType(type)) { return true; } } } return false; } /** * * * */ public function equals(obj:Object):Boolean { if (!(obj is UnionType)) return false; if (this._types.length != obj._types.length) return false; for each (var type:Object in this._types) { // TODO: also check .equals and describesType if (obj.types.indexOf(type) == -1) return false; } return true; } } }