You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by gr...@apache.org on 2021/12/09 01:30:47 UTC

[royale-asjs] branch develop updated: Refactoring in reflection to add a lightweight getAncestry reflection method (with no TypeDefinition dependency).

This is an automated email from the ASF dual-hosted git repository.

gregdove pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git


The following commit(s) were added to refs/heads/develop by this push:
     new 47ff825  Refactoring in reflection to add a lightweight getAncestry reflection method (with no TypeDefinition dependency).
47ff825 is described below

commit 47ff825812f3792a771c601600801898079dbf2d
Author: greg-dove <gr...@gmail.com>
AuthorDate: Thu Dec 9 14:30:30 2021 +1300

    Refactoring in reflection to add a lightweight getAncestry reflection method (with no TypeDefinition dependency).
---
 .../src/main/royale/ReflectionClasses.as           |   1 +
 .../org/apache/royale/reflection/TypeDefinition.as |  97 +-----------------
 .../org/apache/royale/reflection/describeType.as   |  36 +------
 .../org/apache/royale/reflection/getAncestry.as    |  45 +++++++++
 .../royale/reflection/getAncestryInternal.as       | 108 +++++++++++++++++++++
 .../apache/royale/reflection/getDataInternal.as    |  70 +++++++++++++
 .../reflection/ReflectionTesterTest.as             |  12 +++
 7 files changed, 240 insertions(+), 129 deletions(-)

diff --git a/frameworks/projects/Reflection/src/main/royale/ReflectionClasses.as b/frameworks/projects/Reflection/src/main/royale/ReflectionClasses.as
index 4fa0697..e498a79 100644
--- a/frameworks/projects/Reflection/src/main/royale/ReflectionClasses.as
+++ b/frameworks/projects/Reflection/src/main/royale/ReflectionClasses.as
@@ -46,6 +46,7 @@ internal class ReflectionClasses
 	import org.apache.royale.reflection.getQualifiedSuperclassName; getQualifiedSuperclassName;
 	import org.apache.royale.reflection.registerClassAlias; registerClassAlias;
 	import org.apache.royale.reflection.getClosureQualifiedName; getClosureQualifiedName;
+	import org.apache.royale.reflection.getAncestry; getAncestry;
 	//utils
 	import org.apache.royale.reflection.utils.getMembersWithMetadata; getMembersWithMetadata;
 	import org.apache.royale.reflection.utils.getMembers; getMembers;
diff --git a/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/TypeDefinition.as b/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/TypeDefinition.as
index 70bfb02..f53d5cd 100755
--- a/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/TypeDefinition.as
+++ b/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/TypeDefinition.as
@@ -372,103 +372,8 @@ COMPILE::SWF {
                 }
                 return results;
             }
-            
-            COMPILE::SWF
-            {
-                var xml:XML = rawData as XML;
-                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(TypeDefinition.internalGetDefinition(qname));
-                }
-            }
-            COMPILE::JS
-            {
-                var data:Object = rawData;
-                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 royale 'class'
-                    if (ExtraData.hasData(qname)) {
-                        superClass = ExtraData.getData(qname)['NATIVE_BASE'];
-                    }
-
-                }
-                while (superClass) {
-                    var superData:Object;
-                    var js_native:Boolean = false;
-                    if (superClass.ROYALE_CLASS_INFO !== undefined) {
-                        superData = superClass.ROYALE_CLASS_INFO;
-                    } else {
-                        if (ExtraData.hasData(superClass)) {
-                            superData = ExtraData.getData(getQualifiedClassName(superClass))['ROYALE_CLASS_INFO'];
-                            if (superData) {
-                                js_native = true;
-                            } else {
-                                //exit
-                                superClass = null;
-                            }
-
-
-                        } else {
-                            //exit
-                            superClass = null;
-                            superData = null;
-                        }
-                    }
-                    if (superData) {
-                        qname = superData.names[0].qName;
-                        results.push(TypeDefinition.internalGetDefinition(qname));
-                        if (!js_native) {
-                            def = getDefinitionByName(qname);
-                            superClass = def.superClass_;
-                        } else {
-                            if (ExtraData.hasData(qname)) {
-                                superClass = ExtraData.getData(qname)['NATIVE_BASE']
-                            } else {
-                                superClass = null;
-                            }
-                        }
-                    }
-                }
+            getAncestryInternal(rawData, results, TypeDefinition.internalGetDefinition);
 
-                    /*= superClass.ROYALE_CLASS_INFO !== undefined ? superClass.ROYALE_CLASS_INFO : null;
-                    if (!superData) {
-                        if (ExtraData.hasData(superClass)) {
-
-                        } else {
-                            superClass = null;
-                        }
-
-                    } else {
-                        superClass = def.superClass_;
-                    }
-                    if (superClass.ROYALE_CLASS_INFO !== undefined) {
-                        qname = superClass.ROYALE_CLASS_INFO.names[0].qName;
-                        results.push(TypeDefinition.internalGetDefinition(qname));
-                        def = getDefinitionByName(qname);
-                        superClass = def.superClass_;
-                        //todo: support for when superClass is not a royale 'class'
-
-                    } else {
-                        //todo: support for when superClass is not a royale 'class'
-                        if (ExtraData.hasData(superClass)) {
-                            results.push(TypeDefinition.internalGetDefinition(ExtraData.getData(superClass)[]));
-                            var baseName:String = ExtraData.getData(qname)['NATIVE_BASE'];
-                            if (baseName) {
-                                superClass = getDefinitionByName(baseName);
-                            }
-                        }
-                        superClass = null;
-
-                    }
-                }*/
-            }
-            
             if (_cache) {
                 _baseClasses = results;
                 results = results.slice();
diff --git a/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/describeType.as b/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/describeType.as
index ab1d7af..2eb0f47 100755
--- a/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/describeType.as
+++ b/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/describeType.as
@@ -18,14 +18,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 package org.apache.royale.reflection
 {
-COMPILE::SWF
-{
-    import flash.utils.describeType;
-}
-COMPILE::JS
-{
-    import org.apache.royale.utils.Language;
-}   
 
     /**
      *  The equivalent of flash.utils.describeType.
@@ -41,36 +33,14 @@ COMPILE::JS
 	{
         COMPILE::SWF
         {
-            var untyped:* = value;
-            if (value !== null && untyped !== undefined) {
-                //normalize the query object to the static Class or interface level
-                //numeric values have some specific range quirks:
-                if (value is int && value >= -268435456 && value <= 268435455) value = int;
-                while (value['constructor'] !== Class) {
-                    value = value['constructor'];
-                }
-            }
-            var xml:XML = flash.utils.describeType(value);
-            return TypeDefinition.getDefinition(xml.@name, xml, value as Class);
+            var xml:XML = getDataInternal(value);
+            return TypeDefinition.getDefinition(xml.@name, getDataInternal(value), value as Class);
         }
         COMPILE::JS
         {
             const qname:String = getQualifiedClassName(value);
             var clazz:Class = value ? (value.prototype ? value : value.constructor) as Class : null;
-            var data:Object = value.ROYALE_CLASS_INFO || (value.prototype ? value.prototype.ROYALE_CLASS_INFO : null);
-            if (!data) {
-                if (ExtraData.hasData(qname)) {
-                    data = ExtraData.getData(qname)['ROYALE_CLASS_INFO'];
-                } else {
-                    var key:* = (value.constructor && value.constructor != Function && !Language.isSynthType(value)) ? value.constructor : value;
-                    data = ExtraData.hasData(key) ? ExtraData.getData(key)['ROYALE_CLASS_INFO'] : null; 
-                    if (!data) {
-                        key = getDefinitionByName(qname);
-                        data = ExtraData.hasData(key) ? ExtraData.getData(key)['ROYALE_CLASS_INFO'] : null;
-                    }
-                }
-            }
-            return TypeDefinition.getDefinition(qname, data, clazz);
+            return TypeDefinition.getDefinition(qname, getDataInternal(value, qname), clazz);
         }
     }
 }
diff --git a/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/getAncestry.as b/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/getAncestry.as
new file mode 100644
index 0000000..8bc9b5f
--- /dev/null
+++ b/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/getAncestry.as
@@ -0,0 +1,45 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.royale.reflection
+{
+
+
+    /**
+     *  A utility function to return ancestry (base classes) as a set of qualified names.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2
+     *  @playerversion AIR 2.6
+     *  @productversion Royale 0.9.9
+     *  
+     *  @royaleignorecoercion Class
+     */
+    public function getAncestry(value:Object):Array
+	{
+        COMPILE::SWF
+        {
+            return getAncestryInternal(getDataInternal(value));
+        }
+        COMPILE::JS
+        {
+            const qname:String = getQualifiedClassName(value);
+            return getAncestryInternal(getDataInternal(value, qname));
+        }
+    }
+}
diff --git a/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/getAncestryInternal.as b/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/getAncestryInternal.as
new file mode 100644
index 0000000..81e7905
--- /dev/null
+++ b/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/getAncestryInternal.as
@@ -0,0 +1,108 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.royale.reflection
+{
+COMPILE::SWF
+{
+    import flash.utils.describeType;
+}
+COMPILE::JS
+{
+    import org.apache.royale.utils.Language;
+}   
+
+    /**
+     *  @private
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10.2
+     *  @playerversion AIR 2.6
+     *  @productversion Royale 0.0
+     *
+     */
+    internal function getAncestryInternal(value:Object, into:Array=null, transformer:Function = null):Array
+	{
+        var results:Array = into ? into : [];
+        COMPILE::SWF
+        {
+            var xml:XML = value as XML;
+            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.replace('::','.');
+                var push:Object = transformer != null ? transformer(qname) : qname;
+
+                results.push(push);
+            }
+        }
+        COMPILE::JS
+        {
+            var data:Object = value;
+            var qname:String = data.names[0].qName;
+            var def:Object = getDefinitionByName(qname);
+            var superClass:Object = def.superClass_;
+            if (!superClass) {
+                if (ExtraData.hasData(qname)) {
+                    superClass = ExtraData.getData(qname)['NATIVE_BASE'];
+                }
+
+            }
+            while (superClass) {
+                var superData:Object;
+                var js_native:Boolean = false;
+                if (superClass.ROYALE_CLASS_INFO !== undefined) {
+                    superData = superClass.ROYALE_CLASS_INFO;
+                } else {
+                    if (ExtraData.hasData(superClass)) {
+                        superData = ExtraData.getData(getQualifiedClassName(superClass))['ROYALE_CLASS_INFO'];
+                        if (superData) {
+                            js_native = true;
+                        } else {
+                            //exit
+                            superClass = null;
+                        }
+                    } else {
+                        //exit
+                        superClass = null;
+                        superData = null;
+                    }
+                }
+                if (superData) {
+                    qname = superData.names[0].qName;
+                    var push:Object = transformer != null ? transformer(qname) : qname;
+                    results.push(push);
+                    if (!js_native) {
+                        def = getDefinitionByName(qname);
+                        superClass = def.superClass_;
+                    } else {
+                        if (ExtraData.hasData(qname)) {
+                            superClass = ExtraData.getData(qname)['NATIVE_BASE']
+                        } else {
+                            superClass = null;
+                        }
+                    }
+                }
+            }
+        }
+
+        return results;
+    }
+}
diff --git a/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/getDataInternal.as b/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/getDataInternal.as
new file mode 100644
index 0000000..66ffc05
--- /dev/null
+++ b/frameworks/projects/Reflection/src/main/royale/org/apache/royale/reflection/getDataInternal.as
@@ -0,0 +1,70 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.royale.reflection
+{
+    COMPILE::SWF
+    {
+        import flash.utils.describeType;
+    }
+    COMPILE::JS
+    {
+        import org.apache.royale.utils.Language;
+    }
+
+    /**
+     *  @private
+     *
+     */
+    COMPILE::SWF
+    internal function getDataInternal(value:Object):XML {
+        var untyped:* = value;
+        if (value !== null && untyped !== undefined) {
+            //normalize the query object to the static Class or interface level
+            //numeric values have some specific range quirks:
+            if (value is int && value >= -268435456 && value <= 268435455) value = int;
+            while (value['constructor'] !== Class) {
+                value = value['constructor'];
+            }
+        }
+       return flash.utils.describeType(value);
+    }
+
+    /**
+     *  @private
+     *
+     */
+    COMPILE::JS
+    internal function getDataInternal(value:Object, qName:String):Object {
+        var data:Object = value.ROYALE_CLASS_INFO || (value.prototype ? value.prototype.ROYALE_CLASS_INFO : null);
+        if (!data) {
+            if (ExtraData.hasData(qName)) {
+                data = ExtraData.getData(qName)['ROYALE_CLASS_INFO'];
+            } else {
+                var key:* = (value.constructor && value.constructor != Function && !Language.isSynthType(value)) ? value.constructor : value;
+                data = ExtraData.hasData(key) ? ExtraData.getData(key)['ROYALE_CLASS_INFO'] : null;
+                if (!data) {
+                    key = getDefinitionByName(qName);
+                    data = ExtraData.hasData(key) ? ExtraData.getData(key)['ROYALE_CLASS_INFO'] : null;
+                }
+            }
+        }
+        return data;
+    }
+
+}
diff --git a/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/ReflectionTesterTest.as b/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/ReflectionTesterTest.as
index e57f631..86a3c69 100644
--- a/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/ReflectionTesterTest.as
+++ b/frameworks/projects/Reflection/src/test/royale/flexUnitTests/reflection/ReflectionTesterTest.as
@@ -234,6 +234,18 @@ package flexUnitTests.reflection
             var expected:uint = isJS ? 1 : 3;
             assertEquals( expected, baseClasses.length, "unexpected baseclasses length");
         }
+
+
+        [TestVariance(variance="JS", description="Variance in baseClasses due to current inability for js target to reflect into non-Royale base classes or typedefs")]
+        [Test]
+        public function testGetAncestry():void
+        {
+            //similar to testBaseClasses but with a lighter dependency load if TypeDefinition is not being used
+            var ancestors:Array = getAncestry(TestClass3);
+
+            var expected:uint = isJS ? 2 : 4;
+            assertEquals( expected, ancestors.length, "unexpected ancestry length");
+        }
         
         
         [Test]