Initial sweep through wide set of Reflection functionality. Currently only verified as compatible between platforms within the FlexJS classes. This update requires corresponding Falcon/FalconJX updates
Project: http://git-wip-us.apache.org/repos/asf/flex-asjs/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-asjs/commit/92c0a8b4 Tree: http://git-wip-us.apache.org/repos/asf/flex-asjs/tree/92c0a8b4 Diff: http://git-wip-us.apache.org/repos/asf/flex-asjs/diff/92c0a8b4 Branch: refs/heads/refactor-sprite Commit: 92c0a8b46b931764376f198d417cf31ae557c35f Parents: fd05c96 Author: greg-dove <[email protected]> Authored: Mon Sep 26 15:16:27 2016 +1300 Committer: greg-dove <[email protected]> Committed: Tue Sep 27 19:52:42 2016 +1300 ---------------------------------------------------------------------- .../flex/reflection/AccessorDefinition.as | 86 ++ .../apache/flex/reflection/DefinitionBase.as | 4 +- .../flex/reflection/DefinitionWithMetaData.as | 46 +- .../flex/reflection/MetaDataArgDefinition.as | 24 +- .../flex/reflection/MetaDataDefinition.as | 66 +- .../apache/flex/reflection/MethodDefinition.as | 105 ++- .../flex/reflection/ParameterDefinition.as | 84 ++ .../apache/flex/reflection/TypeDefinition.as | 823 ++++++++++++++++--- .../flex/reflection/VariableDefinition.as | 36 +- .../org/apache/flex/reflection/describeType.as | 12 +- .../apache/flex/reflection/getAliasByClass.as | 47 ++ .../apache/flex/reflection/getClassByAlias.as | 43 + .../flex/reflection/registerClassAlias.as | 44 + 13 files changed, 1259 insertions(+), 161 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/AccessorDefinition.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/AccessorDefinition.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/AccessorDefinition.as new file mode 100644 index 0000000..e6cf2b4 --- /dev/null +++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/AccessorDefinition.as @@ -0,0 +1,86 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package org.apache.flex.reflection { + /** + * The description of a Class or Interface accessor (get and/or set) + * + * @langversion 3.0 + * @playerversion Flash 10.2 + * @playerversion AIR 2.6 + * @productversion FlexJS 0.0 + */ + public class AccessorDefinition extends VariableDefinition + { + public function AccessorDefinition(name:String, rawData:Object) { + super(name, rawData); + } + /** + * The type that defined this accessor + * This could be an ancestor class of the method's containing TypeDefinition + */ + public function get declaredBy():TypeDefinition + { + COMPILE::SWF{ + var declareBy:String = _rawData.@declaredBy; + } + COMPILE::JS{ + var declareBy:String = _rawData.declaredBy; + } + return TypeDefinition.getDefinition(declareBy); + } + + + private var _access:String; + /** + * The type of access that this accessor has. + * One of: 'readonly', 'writeonly', or 'readwrite' + * Note, these values are all lower case (not camelCase). + */ + public function get access():String + { + if (_access) return _access; + + COMPILE::SWF { + _access=rawData.@access; + } + COMPILE::JS { + _access = rawData.access; + } + + return _access; + } + + /** + * A string representation of this accessor definition + */ + override public function toString():String{ + var s:String = "accessor: '"+name+"' access:"+access+", type:"+type.qualifiedName+", declaredBy:"+declaredBy.qualifiedName; + var meta:Array = metadata; + var i:uint; + var l:uint = meta.length; + if (l) { + s += "\n\tmetadata:"; + for (i=0;i<l;i++) { + s += "\n\t\t" + meta[i].toString().split("\n").join("\n\t\t"); + } + } + return s; + } + } +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionBase.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionBase.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionBase.as index f8bdd82..5868eaf 100755 --- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionBase.as +++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionBase.as @@ -20,7 +20,7 @@ package org.apache.flex.reflection { /** - * The description of a Class or Interface + * The base class for all definition types * * @langversion 3.0 * @playerversion Flash 10.2 @@ -35,7 +35,7 @@ package org.apache.flex.reflection _rawData = rawData; } - private var _name:String; + protected var _name:String; public function get name():String { return _name; http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionWithMetaData.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionWithMetaData.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionWithMetaData.as index b9179fe..e32d597 100755 --- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionWithMetaData.as +++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/DefinitionWithMetaData.as @@ -20,7 +20,8 @@ package org.apache.flex.reflection { /** - * The description of a Class or Interface + * The base class for definition types that can be decorated with metadata in actionscript + * source code * * @langversion 3.0 * @playerversion Flash 10.2 @@ -33,21 +34,29 @@ package org.apache.flex.reflection { super(name, rawData); } - + + COMPILE::SWF + protected var useFactory:Boolean; + + + private var _metaData:Array; + /** + * gets a copy of the metadata collection array + */ public function get metadata():Array { + if (_metaData) return _metaData.slice(); var results:Array = []; - COMPILE::SWF { - var xml:XML = rawData as XML; + var xml:XML = useFactory ? rawData.factory[0] as XML : rawData as XML; var data:XMLList = xml.metadata; var n:int = data.length(); for (var i:int = 0; i < n; i++) { var item:XML = data[i] as XML; - var qname:String = item.@name; - results.push(new MetaDataDefinition(qname, item)); + var metaName:String = item.@name; + results[i] = new MetaDataDefinition(metaName, item); } } COMPILE::JS @@ -67,13 +76,32 @@ package org.apache.flex.reflection var metadatas:Array = rdata.metadata(); if (metadatas) { - var n:int = metadatas.length; - for each (var mdDef:Object in metadatas) - results.push(new MetaDataDefinition(mdDef.name, mdDef)); + var i:uint = 0; + var l:int = metadatas.length; + for (;i<l;i++) { + var mdDef:Object = metadatas[i]; + results[i] = new MetaDataDefinition(mdDef.name, mdDef); + } } } } + _metaData = results.slice(); return results; } + + /** + * A convenience method for retrieving metadatas + * @param name the name of the metadata item to retrieve. + * It can occur more than once, so an array is returned + * @return an array of all MetaDataDefinition items with matching 'name' + * + */ + public function retrieveMetaDataByName(name:String):Array { + var source:Array = _metaData || metadata; + var results:Array = []; + var i:uint=0, l:uint = source.length; + for(;i<l;i++) if (source[i].name == name) results.push(source[i]); + return results; + } } } http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataArgDefinition.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataArgDefinition.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataArgDefinition.as index 1f1366f..2224f52 100755 --- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataArgDefinition.as +++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataArgDefinition.as @@ -36,10 +36,30 @@ package org.apache.flex.reflection } private var _value:String; - + /** + * the 'key' value of a metadata argument + * in [Event(name="boom")] + * the value for the 1st (only) argument + * is 'boom' + */ public function get value():String { return _value; - } + } + + /** + * the 'key' value of a metadata argument + * in [Event(name="boom")] + * the key for the 1st (only) argument + * is 'name' + */ + public function get key():String{ + return _name; + } + + public function toString():String + { + return "arg: key:'"+_name+"', value:'"+_value+"'"; + } } } http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataDefinition.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataDefinition.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataDefinition.as index 48efac8..8805b69 100755 --- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataDefinition.as +++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MetaDataDefinition.as @@ -20,7 +20,7 @@ package org.apache.flex.reflection { /** - * The description of a Class or Interface + * The description of a MetaData tag attached to a class member or a class * * @langversion 3.0 * @playerversion Flash 10.2 @@ -33,11 +33,19 @@ package org.apache.flex.reflection { super(name, rawData); } - + + private var _args:Array; + /** + * The argument pairs (if any) associated with a Metadata tag + * in [Event(name="boom")] + * the args array would be of length 1 + * the array contains MetaDataArgDefinitions + */ public function get args():Array { + if (_args) return _args.slice(); var results:Array = []; - + COMPILE::SWF { var xml:XML = rawData as XML; @@ -59,13 +67,57 @@ package org.apache.flex.reflection var args:Array = rdata.args; if (args) { - var n:int = args.length; - for each (var argDef:Object in args) - results.push(new MetaDataArgDefinition(argDef.key, argDef.value)); + args = args.slice(); + while(args.length) { + var argDef:Object = args.shift(); + results.push(new MetaDataArgDefinition(argDef.key, argDef.value)); + } } } } - return results; + //fully populated, so release rawData ref + _rawData = null; + _args = results.slice(); + return results; + } + + /** + * convenience method for retrieving a set of args with a specific key + * Most often this would be of length 1, but it is possible for there to be + * multiple MetaDataArgDefinitions with the same key + * @param key the key to search for + * @return an array of MetaDataArgDefinitions with the matching key. + */ + public function getArgsByKey(key:String):Array{ + var ret:Array=[]; + var source:Array = _args || args; + var i:uint=0, l:uint=source.length; + for (;i<l;i++) { + var arg:MetaDataArgDefinition = source[i]; + if (arg.key == key) ret.push(arg); + } + return ret; + } + + /** + * Used primarily for debugging purposes, this provides a string representation of this + * MetaDataDefinition + * @return a String representation of this MetaDataDefinition + */ + public function toString():String + { + var s:String="item: '"+_name +"', "; + var args:Array = this.args; + var i:uint; + var l:uint = args.length; + if (!l) s+= "args:{none}"; + else { + s+= "args:"; + for (i=0;i<l;i++) { + s+="\n\t"+args[i].toString(); + } + } + return s; } } } http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MethodDefinition.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MethodDefinition.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MethodDefinition.as index a16c649..b58c7af 100755 --- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MethodDefinition.as +++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/MethodDefinition.as @@ -20,7 +20,7 @@ package org.apache.flex.reflection { /** - * The description of a Class or Interface + * The description of a method inside a class or interface * * @langversion 3.0 * @playerversion Flash 10.2 @@ -29,21 +29,104 @@ package org.apache.flex.reflection */ public class MethodDefinition extends DefinitionWithMetaData { - public function MethodDefinition(name:String, declaredBy:String, rawData:Object = null) + public function MethodDefinition(name:String, rawData:Object) { super(name, rawData); - _declaredBy = declaredBy; } - - private var _declaredBy:String; - private var declaredByDef:TypeDefinition; - + + /** + * The type that defined this method + * This could be an ancestor class of the method's containing TypeDefinition + */ public function get declaredBy():TypeDefinition { - if (declaredByDef == null) - declaredByDef = new TypeDefinition(_declaredBy); - - return declaredByDef; + COMPILE::SWF{ + var declareBy:String = _rawData.@declaredBy; + } + COMPILE::JS{ + var declareBy:String = _rawData.declaredBy; + } + return TypeDefinition.getDefinition(declareBy); + } + + private var _parameters:Array; + /** + * The collection of parameters defined for this method + * each parameter is represented by a ParameterDefinition instance + */ + public function get parameters():Array { + var results:Array; + if (_parameters) { + results = _parameters.slice(); + if (!TypeDefinition.useCache) _parameters = null; + return results; + } + results = []; + COMPILE::SWF { + var xml:XML = rawData as XML; + var data:XMLList = xml.parameter; + var n:int = data.length(); + for (var i:int = 0; i < n; i++) + { + var item:XML = data[i] as XML; + results.push(new ParameterDefinition(uint(item.@index),item)); + } + } + COMPILE::JS { + if (rawData.parameters != null) { + var data:Array = rawData.parameters(); + var n:int = data.length; + for (var i:int = 0; i < n; i++) + { + var item:Object = data[i]; + results.push(new ParameterDefinition(uint(item.index),item)); + } + } + } + + if (TypeDefinition.useCache) _parameters = results; + return results; + } + /** + * The return type for this method + * note: a return type may be "*" or "void" + */ + public function get returnType():TypeDefinition { + COMPILE::SWF{ + var returnType:String = _rawData.@returnType; + } + + COMPILE::JS{ + var returnType:String = _rawData.type; + } + + return TypeDefinition.getDefinition(returnType); + } + + /** + * A string representation of this method definition + */ + public function toString():String{ + var retType:String=returnType.qualifiedName; + if (retType=="") retType ="''"; + var s:String="method: '"+name +"', returnType:"+retType+" declaredBy:"+declaredBy.qualifiedName; + var params:Array = parameters; + var i:uint; + var l:uint = params.length; + if (!l) s+="\n\t{No parameters}"; + else + for (i=0;i<l;i++) { + s+="\n\t"+params[i].toString(); + } + var meta:Array = metadata; + l = meta.length; + if (l) { + s += "\n\tmetadata:"; + for (i=0;i<l;i++) { + s += "\n\t\t" + meta[i].toString().split("\n").join("\n\t\t"); + } + } + return s; } } http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/ParameterDefinition.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/ParameterDefinition.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/ParameterDefinition.as new file mode 100644 index 0000000..b552e33 --- /dev/null +++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/ParameterDefinition.as @@ -0,0 +1,84 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package org.apache.flex.reflection +{ + + /** + * The description of a Function parameter + * + * @langversion 3.0 + * @playerversion Flash 10.2S + * @playerversion AIR 2.6 + * @productversion FlexJS 0.0 + */ + public class ParameterDefinition extends DefinitionBase + { + + public function ParameterDefinition( index:uint, rawData:Object) + { + super("parameter "+index, rawData); + } + + /** + * The type of this parameter + */ + public function get type():TypeDefinition{ + COMPILE::SWF { + return TypeDefinition.getDefinition(_rawData.@type); + } + + COMPILE::JS { + return TypeDefinition.getDefinition(_rawData.type); + } + + } + /** + * Whether this parameter is optional (has a default value) or not + */ + public function get optional():Boolean { + COMPILE::SWF { + return _rawData.@optional == "true"; + } + + COMPILE::JS { + return _rawData.optional; + } + + } + /** + * The 1-based index of this parameter in its owner function/method + */ + public function get index():uint{ + COMPILE::SWF { + return uint(_rawData.@index); + } + + COMPILE::JS { + return _rawData.index; + } + + } + /** + * A string representation of this parameter definition + */ + public function toString():String{ + return _name+", optional:"+optional+", type:"+type.qualifiedName; + } + } +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/TypeDefinition.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/TypeDefinition.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/TypeDefinition.as index cf69bd1..7070e5a 100755 --- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/TypeDefinition.as +++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/TypeDefinition.as @@ -18,6 +18,9 @@ //////////////////////////////////////////////////////////////////////////////// package org.apache.flex.reflection { +COMPILE::SWF { + import flash.utils.describeType; +} /** * The description of a Class or Interface @@ -29,232 +32,802 @@ package org.apache.flex.reflection */ public class TypeDefinition extends DefinitionWithMetaData { + + COMPILE::JS { + //js storage support for class aliases + private static var _aliasMappings:Object={}; + + /** + * @private + * @param aliasName + * @param classObject + */ + internal static function registerClassAlias(aliasName:String, classObject:Class ) :void{ + var info:* = classObject.FLEXJS_CLASS_INFO; + if (info) { + //a class may have more than one alias point to it, but only the most recently registered + //alias is retained for reflection (applying same approach as swf) + var alias:String = info.alias; + if (alias) { + if (alias == aliasName) { + if (_aliasMappings[aliasName] == classObject) return; //nothing to do + } + } + //check for alternate mapping, remove any alternative mapping + //from the other class's FLEXJS_CLASS_INFO + var altClass:Class = _aliasMappings[aliasName]; + if (altClass) { + var altInfo:* = altClass.FLEXJS_CLASS_INFO; + delete altInfo.alias; + } + _aliasMappings[aliasName] = classObject; + info.alias = aliasName; + } else throw new Error("registerClassAlias error: classObject is not Reflectable "+classObject); + } + + /** + * @private + * @param aliasName + * @return + */ + internal static function getClassByAlias(aliasName:String):Class { + return _aliasMappings[aliasName]; + } + + } + + + + //special cases + private static const SC:Array=['void','null','*','']; + + + + private static var _cache:Object; + + public static function get useCache():Boolean{ + return _cache != null; + } + + public static function set useCache(value:Boolean):void{ + if (value) { + if (!_cache) _cache = {}; + } else if (_cache) _cache = null; + } + + + /** + * The static getDefinition method is the primary access to TypeDefinitions. Although the + * constructor does not have a lock to prevent use (for performance reasons), using it directly + * is discouraged. + * @param name the qualified name of the definition, + * @param rawData (optional) the reflection data if already available + * @return a TypeDefinition representing the class or interface represented by the parameters + */ + public static function getDefinition(name:String, rawData:Object = null):TypeDefinition { + return _cache ? (_cache[name] || new TypeDefinition(name, rawData)) : new TypeDefinition(name, rawData); + } + + /** + * The static TypeDefinitions.getDefinition method is the primary access to TypeDefinitions. Although the + * constructor does not have a lock to prevent use (for performance reasons), using it directly + * is discouraged. + * Most of the time you should retrieve TypeDefinitions with org.apache.flex.reflection.describeType() + */ public function TypeDefinition(name:String, rawData:Object = null) { - var c:int = name.indexOf("::"); - if (c > -1) - { - _packageName = name.substring(0, c); - name = name.substring(c+2); - } - else - _packageName = ""; + if (_cache) _cache[name] = this; + + var c:int; + COMPILE::SWF{ + c = name.indexOf("::"); + if (c > -1) + { + _packageName = name.substr(0, c); + name = name.substr(c+2); + } + else + _packageName = ""; + //this definition sets a flag for where to find the metadata: + useFactory = true; + } + COMPILE::JS{ + c = name.lastIndexOf("."); + if (c > -1) + { + _packageName = name.substr(0, c); + name = name.substr(c+1); + } + else + _packageName = ""; + } + _specialCase = _packageName=="" && SC.indexOf(name) != -1; super(name, rawData); } - - private var _packageName:String; - + + protected var _kind:String; + /** + * The type of definition this TypeDefinition describes + * values can be "class", "interface", "unknown" + * This can sometimes be different between swf and js + * targets. + */ + public function get kind():String{ + if (_kind) return _kind; + + COMPILE::SWF { + var xml:XML = rawData as XML; + if (xml) { + //double check we have the uppermost definition + if (xml.@isStatic!="true") _kind = "class"; + var factory:XML = xml.factory[0]; + //all classes have an extends class, except for Object + if (!factory || factory.extendsClass.length() || factory.@type=="Object") _kind="class"; + else _kind="interface"; + } + } + + COMPILE::JS { + var data:Object = rawData; + _kind = data.names[0].kind; + } + + return _kind || "unknown"; + } + + /** + * convenience check for whether this definition + * represents a Class or instance of a Class + */ + public function get isClass():Boolean{ + return (_kind || kind) == "class"; + } + /** + * convenience check for whether this definition + * represents an interface + */ + public function get isInterface():Boolean{ + return (_kind || kind) == "interface"; + } + + + private var _specialCase:Boolean; + + protected var _packageName:String; + /** + * The package name for this TypeDefinition + */ public function get packageName():String { return _packageName; - } - + } + /** + * The qualified name for this TypeDefinition + */ + public function get qualifiedName():String{ + if (_packageName.length) return _packageName + "." + _name; + else return _name; + } + + /** + * @private + */ override protected function get rawData():Object { - if (_rawData == null) - { - var def:Object = getDefinitionByName(packageName + "::" + name); - COMPILE::SWF + var def:Object; + COMPILE::SWF { + if (_rawData == null) { - _rawData = describeType(def); + if (_packageName.length) + def = getDefinitionByName(_packageName + "::" + _name); + else def = getDefinitionByName(_name); + _rawData = flash.utils.describeType(def); + } - COMPILE::JS + } + + COMPILE::JS{ + if (_rawData == null) { + if (_packageName.length) + def = getDefinitionByName(_packageName + "." + _name); + else def = getDefinitionByName(_name); _rawData = def.prototype.FLEXJS_CLASS_INFO; } } return _rawData; } + + /** class specific support */ + + private var _constructorMethod:MethodDefinition; + /** + * A MethodDefinition representing the constructor for a "class" kind TypeDefinition + * For an interface this returns null. + */ + public function get constructorMethod():MethodDefinition{ + if ((_kind || kind) != "class") return null; + COMPILE::SWF { + if (!_constructorMethod) { + var source:XML = rawData.factory.constructor[0];//['constructor'][0]; + var declaredBy:String = _packageName.length? _packageName+"::"+_name : _name; + if (source ==null) { + //constructor with no params + _constructorMethod = + new MethodDefinition(_name, XML('<method name="'+_name+'" declaredBy="'+declaredBy+'" returnType="" />')); + } else { + var params:XMLList = source.parameter; + _constructorMethod=new MethodDefinition(_name, XML('<method name="'+_name+'" declaredBy="'+declaredBy+'" returnType="">'+params.toXMLString()+'</method>')) + } + } + } + + COMPILE::JS { + if (!_constructorMethod) { + var temp:Array = getCollection("methods","instance",false); + var i:int=0, l:int=temp.length; + for (;i<l;i++) { + if (temp[i].name == _name) { + //trace('found constructor '+results[i].toString()); + _constructorMethod = temp[i]; + break; + } + } + } + } + + return _constructorMethod; + } + + + private var _baseClasses:Array; /** + * For a "class" kind TypeDefinition, this returns the TypeDefinitions + * of the base classes (inheritance chain). This may differ between + * javascript and flash platform targets for some classes. * @flexjsignorecoercion XML */ public function get baseClasses():Array { - var results:Array = []; + + var results:Array; + if (_baseClasses) { + results =_baseClasses.slice(); + if (!_cache) _baseClasses = null; + return results; + } + if ((_kind || kind) != "class") return []; + + results = []; + //handle special cases + if (_specialCase) { + if (_cache) { + _baseClasses = results; + results = results.slice(); + } + return results; + } COMPILE::SWF { var xml:XML = rawData as XML; - var data:XMLList = xml.extendsClass; + var data:XMLList = xml.factory.extendsClass; var n:int = data.length(); for (var i:int = 0; i < n; i++) { var item:XML = data[i] as XML; var qname:String = item.@type; - results.push(new TypeDefinition(qname)); + results.push(TypeDefinition.getDefinition(qname)); } } COMPILE::JS { var data:Object = rawData; - var name:String = data.names[0].qName; - var def:Object = getDefinitionByName(name); - var prototype:Object = def.prototype; - while (prototype.FLEXJS_CLASS_INFO !== undefined) + var qname:String = data.names[0].qName; + var def:Object = getDefinitionByName(qname); + var superClass:Object = def.superClass_; + if (!superClass) { + //todo: support for when superClass is not a flexjs 'class' + } else while (superClass) { - name = prototype.FLEXJS_CLASS_INFO.names[0].qName; - results.push(new TypeDefinition(name)); - def = getDefinitionByName(name); - prototype = def.prototype; + if (superClass.FLEXJS_CLASS_INFO !== undefined) { + qname = superClass.FLEXJS_CLASS_INFO.names[0].qName; + results.push(TypeDefinition.getDefinition(qname)); + def = getDefinitionByName(qname); + superClass = def.superClass_; + //todo: support for when superClass is not a flexjs 'class' + + } else { + //todo: support for when superClass is not a flexjs 'class' + superClass = null; + } } } + + if (_cache) { + _baseClasses = results; + results = results.slice(); + } return results; } - + + private var _interfaces:Array; + /** + * returns the full set of interfaces that this class implements or that this + * interface extends, depending on the 'kind' value ("interface" or "class") + */ public function get interfaces():Array { - var results:Array = []; + var results:Array; + if (_interfaces) { + results =_interfaces.slice(); + if (!_cache) _interfaces = null; + return results; + } + results = []; + //handle special cases + if (_specialCase) { + if (_cache) { + _interfaces = results; + results = results.slice(); + } + return results; + } COMPILE::SWF { var xml:XML = rawData as XML; - var data:XMLList = xml.implementsInterface; + var data:XMLList = xml.factory.implementsInterface; var n:int = data.length(); for (var i:int = 0; i < n; i++) { var item:XML = data[i] as XML; var qname:String = item.@type; - results.push(new TypeDefinition(qname)); + results.push(TypeDefinition.getDefinition(qname)); } } COMPILE::JS { var data:* = rawData; - var name:String = data.names[0].qName; - var def:Object = getDefinitionByName(name); - var prototype:Object = def.prototype; - while (data !== undefined) + var i:uint, n:int; + if (data !== undefined) { - var interfaces:Array = data.interfaces; - if (interfaces) - { - var n:int = interfaces.length; - for each (var s:String in interfaces) - results.push(new TypeDefinition(s)); + var collect:Array = data.interfaces || []; + var qname:String = data.names[0].qName; + var def:Object = getDefinitionByName(qname); + if ((_kind || kind) == "interface") { + //collect.length can expand during the loop below + for (i = 0; i < collect.length; i++) { + collect.push.apply(collect, (collect[i].prototype.FLEXJS_CLASS_INFO.interfaces || [])); + } + } else { + var superClass:Object = def.superClass_; + while (superClass && superClass.FLEXJS_CLASS_INFO !== undefined) + { + data = superClass.FLEXJS_CLASS_INFO; + var latest:Array = data.interfaces; + if (latest) { + n = latest.length; + for (i=0;i<n;i++) if (collect.indexOf(latest[i])==-1) collect.push(latest[i]); + } + qname = data.names[0].qName; + def = getDefinitionByName(qname); + superClass = def.superClass_; + } + } + n = collect.length; + for (i=0;i<n;i++) { + var iface:Object = collect[i]; + data = iface.prototype.FLEXJS_CLASS_INFO; + results[i] = TypeDefinition.getDefinition(data.names[0].qName,data); } - name = data.names[0].qName; - results.push(new TypeDefinition(name)); - def = getDefinitionByName(name); - prototype = def.prototype; - data = prototype.FLEXJS_CLASS_INFO; } } + + if (_cache) { + _interfaces = results; + results = results.slice(); + } return results; } - + + + private var _staticVars:Array; + + /** + * The static variables associated with a "class" kind TypeDefinition + * An array of VariableDefinition instances + */ + public function get staticVariables():Array + { + + if ((_kind || kind) != "class") return []; + var results:Array; + if (_staticVars) { + results =_staticVars.slice(); + if (!_cache) _staticVars = null; + return results; + } + COMPILE::SWF { + results = getCollection("variable","static"); + } + COMPILE::JS + { + results = getCollection("variables","static",false); + } + if (_cache) { + _staticVars = results; + results = results.slice(); + } + return results; + } + + private var _staticAccessors:Array; + /** + * The static accessors associated with a "class" kind TypeDefinition + * An array of AccessorDefinition instances + */ + public function get staticAccessors():Array + { + + if ((_kind || kind) != "class") return []; + var results:Array; + if (_staticAccessors) { + results =_staticAccessors.slice(); + if (!_cache) _staticAccessors = null; + return results; + } + COMPILE::SWF { + results = getCollection("accessor","static"); + } + COMPILE::JS + { + results = getCollection("accessors","static",false); + } + if (_cache) { + _staticAccessors = results; + results = results.slice(); + } + return results; + } + + + private var _staticMethods:Array; + /** + * The static methods associated with a "class" kind TypeDefinition + * An array of MethodDefinition instances + */ + public function get staticMethods():Array + { + + if ((_kind || kind) != "class") return []; + var results:Array; + if (_staticMethods) { + results =_staticMethods.slice(); + if (!_cache) _staticMethods = null; + return results; + } + COMPILE::SWF { + results = getCollection("method","static"); + } + COMPILE::JS + { + results = getCollection("methods","static",false); + } + if (_cache) { + _staticMethods = results; + results = results.slice(); + } + return results; + } + + + + + private var _variables:Array; + /** + * The instance variables associated with a "class" kind TypeDefinition + * An array of VariableDefinition instances + */ public function get variables():Array { - var results:Array = []; + + var results:Array; + if (_variables) { + results =_variables.slice(); + if (!_cache) _variables = null; + return results; + } + if ((_kind || kind) != "class") return []; + //handle special cases + if (_specialCase) { + results = []; + if (_cache) { + _variables = results = []; + results = results.slice(); + } + return results; + } COMPILE::SWF { - var xml:XML = rawData as XML; - var data:XMLList = xml.variable; - var n:int = data.length(); - for (var i:int = 0; i < n; i++) - { - var item:XML = data[i] as XML; - var qname:String = item.@name; - results.push(new VariableDefinition(qname, item)); - } + results = getCollection("variable"); } COMPILE::JS { - var data:Object = rawData; - var name:String = data.names[0].qName; - var def:Object = getDefinitionByName(name); - var rdata:* = def.prototype.FLEXJS_REFLECTION_INFO(); - if (rdata !== undefined) - { - var variables:Object = rdata.variables(); - if (variables) - { - for (var v:String in variables) - { - var varDef:Object = variables[v]; - results.push(new VariableDefinition(v, varDef)); - } - } - } + results = getCollection("variables"); + } + if (_cache) { + _variables = results; + results = results.slice(); } return results; } + private var _accessors:Array; + /** + * The instance accessors associated with a "class" kind TypeDefinition + * An array of AccessorDefinition instances + */ public function get accessors():Array { - var results:Array = []; + var results:Array; + if (_accessors) { + results =_accessors.slice(); + if (!_cache) _accessors = null; + return results; + } + + + //handle special cases + if (_packageName=="" && SC.indexOf(name)!=-1) { + results = []; + if (_cache) { + _accessors = results; + results=results.slice(); + } + return results; + } COMPILE::SWF { - var xml:XML = rawData as XML; - var data:XMLList = xml.accessor; - var n:int = data.length(); - for (var i:int = 0; i < n; i++) - { - var item:XML = data[i] as XML; - var qname:String = item.@name; - results.push(new MethodDefinition(qname, item.@declaredBy, item)); - } + results = getCollection("accessor"); } COMPILE::JS { - var data:Object = rawData; - var name:String = data.names[0].qName; - var def:Object = getDefinitionByName(name); - var rdata:* = def.prototype.FLEXJS_REFLECTION_INFO(); - if (rdata !== undefined) - { - var accessors:Object = rdata.accessors(); - if (accessors) - { - for (var prop:String in accessors) - { - var propDef:Object = accessors[prop]; - results.push(new MethodDefinition(prop, propDef.declaredBy, propDef)); - } - } - } + results = getCollection("accessors"); + } + if (_cache) { + _accessors = results; + results = results.slice(); } return results; } + + private var _methods:Array; + /** + * The instance methods associated with a "class" kind TypeDefinition + * An array of MethodDefinition instances + */ public function get methods():Array { - var results:Array = []; + var results:Array; + if (_methods) { + results =_methods.slice(); + if (!_cache) _methods = null; + return results; + } + + + //handle special cases + if (_packageName=="" && SC.indexOf(name)!=-1) { + results = []; + if (_cache) { + + _methods = results; + results=results.slice(); + } + return results; + } COMPILE::SWF { - var xml:XML = rawData as XML; - var data:XMLList = xml.method; - var n:int = data.length(); - for (var i:int = 0; i < n; i++) - { - var item:XML = data[i] as XML; - var qname:String = item.@name; - results.push(new MethodDefinition(qname, item.@declaredBy, item)); - } + results = getCollection("method"); } COMPILE::JS { - var data:Object = rawData; - var name:String = data.names[0].qName; - var def:Object = getDefinitionByName(name); - var rdata:* = def.prototype.FLEXJS_REFLECTION_INFO(); - if (rdata !== undefined) + results = getCollection("methods"); + //special case, remove constructor method: + var i:int=0, l:int=results.length; + for (;i<l;i++) { + if (results[i].name==this.name) { + //trace('found constructor '+results[i].toString()); + _constructorMethod = results[i]; + results.splice(i,1); + break; + } + } + } + if (_cache) { + _methods = results; + results = results.slice(); + } + return results; + } + + + + COMPILE::SWF + protected function getCollection(collection:String, type:String="instance"):Array{ + var lookups:Object = { + variable : VariableDefinition, + accessor : AccessorDefinition, + method : MethodDefinition + }; + var results:Array =[]; + var isStatic:Boolean = type=="static"; + var xml:XML = rawData as XML; + var data:XMLList = isStatic? xml[collection] : xml.factory[collection]; + var n:int = data.length(); + var itemClass:Class = lookups[collection]; + for (var i:int = 0; i < n; i++) + { + var item:XML = data[i] as XML; + var qname:String = item.@name; + results[i]= new itemClass(qname, item); + } + return results; + } + + + COMPILE::JS + protected function getCollection(collection:String, type:String="instance", resolve:Boolean = true):Array{ + var lookups:Object = { + variables : VariableDefinition, + accessors : AccessorDefinition, + methods : MethodDefinition + }; + if (!collection in lookups) throw new Error("ArgumentError: name must be a standard name [variables,accessors,methods]") ; + var isStatic:Boolean = type == "static"; + var results:Array = []; + + var data:Object = rawData; + var qname:String = data.names[0].qName; + var def:Object = getDefinitionByName(qname); + var rdata:* = def.prototype.FLEXJS_REFLECTION_INFO(); + + var itemClass:Class = lookups[collection]; + + var l:int, i:int = 0; + if (resolve) { + if (isStatic) throw new Error("ArgumentError : resolve and static are not compatible"); + //get ancestor items, and record the names for overrides + var oldNames:Array=[]; + var superClass:Object = def.superClass_; + if (superClass) data = superClass.FLEXJS_CLASS_INFO; + else data = null; + + if (data) { + results = TypeDefinition.getDefinition(data.names[0].qName,data)[collection]; + l=results.length; + for (i=0;i<l;i++) oldNames[i]=results[i].name; + } else results=[]; + } + //get the local definitions + if (rdata !== undefined) + { + var items:Object = rdata[collection](); + if (items) { - var methods:Object = rdata.methods(); - if (methods) + for (var item:String in items) { - for (var fn:String in methods) - { - var fnDef:Object = methods[fn]; - results.push(new MethodDefinition(fn, fnDef.declaredBy, fnDef)); + var itemDef:Object = items[item]; + if (isStatic) { + //we are looking for static members only + if ( itemDef.isStatic) results[i++] = new itemClass(item, itemDef); + } else { + //ignore statics here, because this is for instance members: + if (itemDef.isStatic) continue; + //instance member: + var itemClassDef:DefinitionWithMetaData = new itemClass(item, itemDef); + if (resolve) { + //resolve against older versions ("overrides") + var oldIdx:uint = oldNames.indexOf(itemClassDef.name); + if (oldIdx != -1) { + //we have an override of an ancestor's definition, replace it + results[oldIdx] = itemClassDef; + continue; + } + } + //add the new definition item to the collection + results[i++] = itemClassDef; } } } } - return results; + return results; + } + + /** + * Used primarily for debugging purposes, this provides a string representation of this + * TypeDefinition + * @param includeDetail whether to output member definitions and other detailed information + * @return a stringified representation of this TypeDefinition + */ + public function toString(includeDetail:Boolean=false):String + { + var kind:String = this.kind; + var s:String = "Typedefinition: " + qualifiedName + ", kind:"+kind; + if (includeDetail) + { + s += "\n"; + var meta:Array = metadata; + var i:uint; + var l:uint = meta.length; + if (l) { + s += "\tmetadata:"; + for (i=0;i<l;i++) { + s += "\n\t\t" + meta[i].toString().split("\n").join("\n\t\t"); + } + s += "\n"; + } + + var collections:Array; + if (kind == "class") { + var constructorDef:MethodDefinition = constructorMethod; + var construct:Array = constructorDef ? [constructorDef] :[]; + collections = [ "constructor", construct, + "interfaces", interfaces, + "baseClasses", baseClasses, + "variables", variables, + "accessors", accessors, + "methods", methods, + "static variables", staticVariables, + "static accessors", staticAccessors, + "static methods", staticMethods]; + } else { + if (kind == "interface") { + collections = [ "interfaces", interfaces, + "accessors",accessors, + "methods",methods]; + } + } + if (collections) s += stringifyCollections(collections); + else s += "\t{no detail available}" + } + return s; + } + + /** + * utility method to create friendly output of collections, + * primarily for debugging purposes - used via toString(includeDetail=true) + * @param collections array of alternating collection names and collections + * @return stringified representation of the collections + */ + protected function stringifyCollections(collections:Array):String + { + var s:String=""; + while (collections.length) { + var collectionType:String = collections.shift(); + var collection:Array =collections.shift(); + s += collectionType+" :"; + if (!collection || !collection.length) { + s+= "\n\t{none}\n" + } else { + s+="\n"; + var outData:String = "\t"; + var l:uint = collection.length; + while (l) { + l--; + outData += collection.shift().toString(); + if (l) outData += "\n"; + } + outData = outData.replace(/\n/g,"\n\t") + "\n"; + s += outData; + } + } + return s; } - } } http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/VariableDefinition.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/VariableDefinition.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/VariableDefinition.as index 3e87566..c83b02f 100755 --- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/VariableDefinition.as +++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/VariableDefinition.as @@ -20,7 +20,7 @@ package org.apache.flex.reflection { /** - * The description of a Class or Interface + * The description of a Class or Interface variable * * @langversion 3.0 * @playerversion Flash 10.2 @@ -29,9 +29,39 @@ package org.apache.flex.reflection */ public class VariableDefinition extends DefinitionWithMetaData { - public function VariableDefinition(name:String, rawData:Object = null) + public function VariableDefinition(name:String, rawData:Object) { - super(rawData, name); + super(name, rawData); + } + + /** + * A TypeDefinition representing the type of the variable that + * this VariableDefinition represents + */ + public function get type():TypeDefinition { + COMPILE::SWF { + return TypeDefinition.getDefinition(_rawData.@type); + } + + COMPILE::JS { + return TypeDefinition.getDefinition(_rawData.type); + } + } + /** + * A string representation of this variable definition + */ + public function toString():String { + var s:String = "variable: '"+name+"', type:"+type.qualifiedName; + var meta:Array = metadata; + var i:uint; + var l:uint = meta.length; + if (l) { + s+="\n\tmetadata:"; + for (i=0;i<l;i++) { + s += "\n\t\t" + meta[i].toString().split("\n").join("\n\t\t"); + } + } + return s; } } http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/describeType.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/describeType.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/describeType.as index 89b1821..ceb4963 100755 --- a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/describeType.as +++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/describeType.as @@ -35,13 +35,21 @@ COMPILE::SWF { COMPILE::SWF { + + var untyped:* = value; + if (value !== null && untyped !== undefined) { + //normalize the query object to the static Class or interface level + while (value['constructor'] !== Class) { + value = value['constructor']; + } + } var xml:XML = flash.utils.describeType(value); - return new TypeDefinition(xml.@name, xml); + return TypeDefinition.getDefinition(xml.@name, xml); } COMPILE::JS { var qname:String = getQualifiedClassName(value); - return new TypeDefinition(qname, value.FLEXJS_CLASS_INFO); + return TypeDefinition.getDefinition(qname, value.FLEXJS_CLASS_INFO || value.prototype.FLEXJS_CLASS_INFO); } } } http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getAliasByClass.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getAliasByClass.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getAliasByClass.as new file mode 100644 index 0000000..aebb4c6 --- /dev/null +++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getAliasByClass.as @@ -0,0 +1,47 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package org.apache.flex.reflection { + + +COMPILE::SWF { + import flash.utils.describeType; +} +/** + * Retrieves a an alias for a class, based on an alias mapping, previously registered with + * registerClassAlias, or possibly using [RemoteClass(alias='someAlias')] metadata + * + * @param classObject the class to retrieve the alias for + * @return the most recently mapped alias, if found otherwise "" (empty string) + */ + public function getAliasByClass(classObject:Class):String { + var ret:String; + if (classObject == null) throw new TypeError("Parameter classObject must be non-null."); + COMPILE::SWF { + ret= flash.utils.describeType(classObject).@alias; + } + + COMPILE::JS { + var info:* = classObject.FLEXJS_CLASS_INFO; + if (info) { + ret = info.alias || ""; + } else ret=""; + } + return ret; + } +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getClassByAlias.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getClassByAlias.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getClassByAlias.as new file mode 100644 index 0000000..e59a61b --- /dev/null +++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/getClassByAlias.as @@ -0,0 +1,43 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package org.apache.flex.reflection { +COMPILE::SWF { + import flash.net.getClassByAlias; +} +/** + * Retrieves a class based on an alias mapping, previously registered with + * registerClassAlias, or possibly using [RemoteClass(alias='someAlias')] metadata + * + * @param aliasName the alias name to use to look up the class definition + * @return the class definition that has been mapped to by the registered + * alias, or null if no alias mapping exists. + */ + public function getClassByAlias(aliasName:String):Class { + COMPILE::SWF { + return flash.net.getClassByAlias(aliasName); + } + + COMPILE::JS { + if (aliasName == null) throw new TypeError("Parameter aliasName must be non-null."); + var klazz:Class = TypeDefinition.getClassByAlias(aliasName); + if (!klazz) throw new ReferenceError("Class "+aliasName+" could not be found."); + return klazz; + } + } +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/92c0a8b4/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/registerClassAlias.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/registerClassAlias.as b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/registerClassAlias.as new file mode 100644 index 0000000..c06bd42 --- /dev/null +++ b/frameworks/projects/Reflection/src/main/flex/org/apache/flex/reflection/registerClassAlias.as @@ -0,0 +1,44 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package org.apache.flex.reflection { +COMPILE::SWF { + import flash.net.registerClassAlias; +} + /** + * Sets up an alias mapping for serialization/deserialization purposes + * This can be auto-generated by the FlexJS compiler + * when using class level metadata e.g. [RemoteClass(alias='someAlias')] + * + * @param aliasName the alias name to use to look up the class definition + * @param classObject the class to map to the alias name + * + */ + public function registerClassAlias(aliasName:String, classObject:Class):void { + COMPILE::SWF { + + flash.net.registerClassAlias(aliasName,classObject); + } + + COMPILE::JS { + if (classObject == null) throw new TypeError("Parameter classObject must be non-null."); + if (aliasName == null) throw new TypeError("Parameter aliasName must be non-null."); + TypeDefinition.registerClassAlias(aliasName , classObject); + } + } +}
