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]