Hi Greg, Indeed, supporting describeType() is exactly why I made this change.
>From my commit message: > Fixes issue where describeType() could not be used on file-internal > classes because the reflection info was missing I discovered this issue when trying to get the framework's RoyaleUnit tests to run in JS with the <royaleunit> Ant task. RoyaleUnit uses reflection to detect metadata on classes. In the tests that RoyaleUnit runs on itself, I created some mock test classes that are file-internal: https://github.com/apache/royale-asjs/blob/develop/frameworks/projects/RoyaleUnit/src/test/royale/tests/BeforeAndAfterTests.as Without this reflection data, the app crashes in JS because ROYALE_REFLECTION_DATA is missing. This code has been working fine in SWF for a while now, so I had no reason to believe it would break when I finally got around to building the same app for JS. - Josh On 2019/05/22 22:10:54, Greg Dove <greg.d...@gmail.com> wrote: > Actually there is one exception I thought of, and verified .... > > describeType works in avm if the private class is exposed via the public > class > new TestClass().getPrivateClass() > > But getDefinitionByName > and ApplicationDomain.currentDomain.getQualifiedDefinitionNames() do not > seem to know about it. > > Anyway, keen to hear more. If it's needed so be it (in which case my > original attempt to optimize was invalid). > > > > On Thu, May 23, 2019 at 9:58 AM Greg Dove <greg.d...@gmail.com> wrote: > > > > > I just did a quick test using Adobe animate: > > trace(ApplicationDomain.currentDomain.getQualifiedDefinitionNames()) > > > > The private internal classes are not available generally. > > > > If I add a public member to the public class in the file that has a type > > corresponding to a file private class, the string name of the private class > > is represented via describeType. But it throws an error if I try to use > > that subsequently via getDefinitionByName. Maybe there is something extra I > > need to do to somehow make it work, but so far, on the face of it, it seems > > that reflection data should not be needed for 'file private' or 'file > > internal' classes. > > > > > > > > On Thu, May 23, 2019 at 9:35 AM Greg Dove <greg.d...@gmail.com> wrote: > > > >> > >> Hi Josh, > >> > >> Is that change necessary? As part of the work I did previously on > >> reflection I actually removed reflection data from private internal classes > >> as an optimization, because I did not expect there would not be a need to > >> reflect into file 'private' classes. > >> I don't think this is possible in avm? (Might be wrong, but I have > >> certainly never knowingly done it) > >> > >> > >> > >> On Thu, May 23, 2019 at 9:04 AM <joshtynj...@apache.org> wrote: > >> > >>> This is an automated email from the ASF dual-hosted git repository. > >>> > >>> joshtynjala pushed a commit to branch develop > >>> in repository https://gitbox.apache.org/repos/asf/royale-compiler.git > >>> > >>> > >>> The following commit(s) were added to refs/heads/develop by this push: > >>> new b533c38 PackageFooterEmitter: added missing > >>> ROYALE_REFLECTION_INFO for file-internal classes > >>> b533c38 is described below > >>> > >>> commit b533c389d9335ce1a17b2fd1241dc1e5e6016bda > >>> Author: Josh Tynjala <joshtynj...@apache.org> > >>> AuthorDate: Wed May 22 14:04:27 2019 -0700 > >>> > >>> PackageFooterEmitter: added missing ROYALE_REFLECTION_INFO for > >>> file-internal classes > >>> > >>> Fixes issue where describeType() could not be used on file-internal > >>> classes because the reflection info was missing > >>> --- > >>> .../codegen/js/jx/PackageFooterEmitter.java | 19 ++- > >>> .../codegen/js/royale/TestRoyalePackage.java | 156 > >>> ++++++++++++++++++++- > >>> .../royale/projects/internal/MainClass_result.js | 29 ++++ > >>> 3 files changed, 188 insertions(+), 16 deletions(-) > >>> > >>> diff --git > >>> a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/PackageFooterEmitter.java > >>> b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/PackageFooterEmitter.java > >>> index fec56eb..7c151ac 100644 > >>> --- > >>> a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/PackageFooterEmitter.java > >>> +++ > >>> b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/PackageFooterEmitter.java > >>> @@ -80,7 +80,6 @@ public class PackageFooterEmitter extends JSSubEmitter > >>> implements > >>> { > >>> boolean isInterface = tnode instanceof > >>> IInterfaceNode; > >>> boolean isDynamic = tnode instanceof IClassNode > >>> && tnode.hasModifier(ASModifier.DYNAMIC); > >>> - boolean isInternalClass = !isInterface && tnode > >>> instanceof IClassNode && > >>> getEmitter().getModel().isInternalClass(tnode.getQualifiedName()); > >>> /* > >>> * Metadata > >>> * > >>> @@ -199,17 +198,15 @@ public class PackageFooterEmitter extends > >>> JSSubEmitter implements > >>> > >>> String typeName = > >>> getEmitter().formatQualifiedName(tnode.getQualifiedName()); > >>> > >>> - if (!isInternalClass) { > >>> - emitReflectionData( > >>> - typeName, > >>> - reflectionKind, > >>> - varData, > >>> - accessorData, > >>> - methodData, > >>> - metadata); > >>> - } > >>> + emitReflectionData( > >>> + typeName, > >>> + reflectionKind, > >>> + varData, > >>> + accessorData, > >>> + methodData, > >>> + metadata); > >>> > >>> - if (!isInterface && !isInternalClass) { > >>> + if (!isInterface) { > >>> > >>> emitReflectionRegisterInitialStaticFields(typeName, (ClassDefinition) > >>> tnode.getDefinition()); > >>> } > >>> > >>> diff --git > >>> a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyalePackage.java > >>> b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyalePackage.java > >>> index 488954a..2d9166c 100644 > >>> --- > >>> a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyalePackage.java > >>> +++ > >>> b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyalePackage.java > >>> @@ -531,7 +531,32 @@ public class TestRoyalePackage extends > >>> TestGoogPackage > >>> " *\n" + > >>> " * @type {Object.<string, > >>> Array.<Object>>}\n" + > >>> " */\n" + > >>> - > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ > >>> name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' > >>> }] };" > >>> + > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ > >>> name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' > >>> }] };\n" + > >>> + "\n" + > >>> + "\n" + > >>> + "\n" + > >>> + "/**\n" + > >>> + " * Reflection\n" + > >>> + " *\n" + > >>> + " * @return {Object.<string, > >>> Function>}\n" + > >>> + " */\n" + > >>> + > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO = function > >>> () {\n" + > >>> + " return {\n" + > >>> + " variables: function () {return > >>> {};},\n" + > >>> + " accessors: function () {return > >>> {};},\n" + > >>> + " methods: function () {\n" + > >>> + " return {\n" + > >>> + " 'InternalClass': { type: '', > >>> declaredBy: 'foo.bar.baz.A.InternalClass'}\n" + > >>> + " };\n" + > >>> + " }\n" + > >>> + " };\n" + > >>> + "};\n" + > >>> + "/**\n" + > >>> + " * @export\n" + > >>> + " * @const\n" + > >>> + " * @type {number}\n" + > >>> + " */\n" + > >>> + > >>> > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO.compileFlags > >>> = 15;\n" > >>> ); > >>> } > >>> > >>> @@ -815,7 +840,45 @@ public class TestRoyalePackage extends > >>> TestGoogPackage > >>> " *\n" + > >>> " * @type {Object.<string, > >>> Array.<Object>>}\n" + > >>> " */\n" + > >>> - > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ > >>> name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' > >>> }] };" > >>> + > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ > >>> name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' > >>> }] };\n" + > >>> + "\n" + > >>> + "\n" + > >>> + "\n" + > >>> + "/**\n" + > >>> + " * Reflection\n" + > >>> + " *\n" + > >>> + " * @return {Object.<string, > >>> Function>}\n" + > >>> + " */\n" + > >>> + > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO = function > >>> () {\n" + > >>> + " return {\n" + > >>> + " variables: function () {\n" + > >>> + " return {\n" + > >>> + " '|someString': { type: > >>> 'String', get_set: function (/** * */ v) {return v !== undefined ? > >>> foo.bar.baz.A.InternalClass.someString = v : > >>> foo.bar.baz.A.InternalClass.someString;}}\n" + > >>> + " };\n" + > >>> + " },\n" + > >>> + " accessors: function () {return > >>> {};},\n" + > >>> + " methods: function () {\n" + > >>> + " return {\n" + > >>> + " 'InternalClass': { type: '', > >>> declaredBy: 'foo.bar.baz.A.InternalClass'},\n" + > >>> + " '|someStaticFunction': { type: > >>> 'String', declaredBy: 'foo.bar.baz.A.InternalClass'},\n" + > >>> + " 'someMethod': { type: 'String', > >>> declaredBy: 'foo.bar.baz.A.InternalClass'}\n" + > >>> + " };\n" + > >>> + " }\n" + > >>> + " };\n" + > >>> + "};\n" + > >>> + "/**\n" + > >>> + " * @export\n" + > >>> + " * @const\n" + > >>> + " * @type {number}\n" + > >>> + " */\n" + > >>> + > >>> > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO.compileFlags > >>> = 15;\n" + > >>> + "/**\n" + > >>> + " * Provide reflection support for > >>> distinguishing dynamic fields on class object (static)\n" + > >>> + " * @export\n" + > >>> + " * @const\n" + > >>> + " * @type {Array<string>}\n" + > >>> + " */\n" + > >>> + > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO.statics = > >>> Object.keys(foo.bar.baz.A.InternalClass);\n" > >>> ); > >>> } > >>> > >>> @@ -966,7 +1029,36 @@ public class TestRoyalePackage extends > >>> TestGoogPackage > >>> " *\n" + > >>> " * @type {Object.<string, > >>> Array.<Object>>}\n" + > >>> " */\n" + > >>> - > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ > >>> name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' > >>> }] };" > >>> + > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ > >>> name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' > >>> }] };\n" + > >>> + "\n" + > >>> + "\n" + > >>> + "\n" + > >>> + "/**\n" + > >>> + " * Reflection\n" + > >>> + " *\n" + > >>> + " * @return {Object.<string, > >>> Function>}\n" + > >>> + " */\n" + > >>> + > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO = function > >>> () {\n" + > >>> + " return {\n" + > >>> + " variables: function () {return > >>> {};},\n" + > >>> + " accessors: function () {\n" + > >>> + " return {\n" + > >>> + " 'someString': { type: 'String', > >>> access: 'readwrite', declaredBy: 'foo.bar.baz.A.InternalClass'}\n" + > >>> + " };\n" + > >>> + " },\n" + > >>> + " methods: function () {\n" + > >>> + " return {\n" + > >>> + " 'InternalClass': { type: '', > >>> declaredBy: 'foo.bar.baz.A.InternalClass'}\n" + > >>> + " };\n" + > >>> + " }\n" + > >>> + " };\n" + > >>> + "};\n" + > >>> + "/**\n" + > >>> + " * @export\n" + > >>> + " * @const\n" + > >>> + " * @type {number}\n" + > >>> + " */\n" + > >>> + > >>> > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO.compileFlags > >>> = 15;\n" > >>> ); > >>> } > >>> > >>> @@ -1126,7 +1218,33 @@ public class TestRoyalePackage extends > >>> TestGoogPackage > >>> " *\n" + > >>> " * @type {Object.<string, > >>> Array.<Object>>}\n" + > >>> " */\n" + > >>> - > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ > >>> name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' > >>> }], interfaces: [foo.bar.baz.A.ITestInterface] };" > >>> + > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ > >>> name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' > >>> }], interfaces: [foo.bar.baz.A.ITestInterface] };\n" + > >>> + "\n" + > >>> + "\n" + > >>> + "\n" + > >>> + "/**\n" + > >>> + " * Reflection\n" + > >>> + " *\n" + > >>> + " * @return {Object.<string, > >>> Function>}\n" + > >>> + " */\n" + > >>> + > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO = function > >>> () {\n" + > >>> + " return {\n" + > >>> + " variables: function () {return > >>> {};},\n" + > >>> + " accessors: function () {return > >>> {};},\n" + > >>> + " methods: function () {\n" + > >>> + " return {\n" + > >>> + " 'InternalClass': { type: '', > >>> declaredBy: 'foo.bar.baz.A.InternalClass'},\n" + > >>> + " 'test': { type: 'void', > >>> declaredBy: 'foo.bar.baz.A.InternalClass'}\n" + > >>> + " };\n" + > >>> + " }\n" + > >>> + " };\n" + > >>> + "};\n" + > >>> + "/**\n" + > >>> + " * @export\n" + > >>> + " * @const\n" + > >>> + " * @type {number}\n" + > >>> + " */\n" + > >>> + > >>> > >>> "foo.bar.baz.A.InternalClass.prototype.ROYALE_REFLECTION_INFO.compileFlags > >>> = 15;\n" > >>> ); > >>> } > >>> > >>> @@ -1189,7 +1307,35 @@ public class TestRoyalePackage extends > >>> TestGoogPackage > >>> " *\n" + > >>> " * @type {Object.<string, > >>> Array.<Object>>}\n" + > >>> " */\n" + > >>> - > >>> "foo.bar.A.Internal.prototype.ROYALE_CLASS_INFO = { names: [{ name: > >>> 'Internal', qName: 'foo.bar.A.Internal', kind: 'class' }] };" > >>> + > >>> "foo.bar.A.Internal.prototype.ROYALE_CLASS_INFO = { names: [{ name: > >>> 'Internal', qName: 'foo.bar.A.Internal', kind: 'class' }] };\n" + > >>> + "\n" + > >>> + "\n" + > >>> + "\n" + > >>> + "/**\n" + > >>> + " * Reflection\n" + > >>> + " *\n" + > >>> + " * @return {Object.<string, > >>> Function>}\n" + > >>> + " */\n" + > >>> + > >>> "foo.bar.A.Internal.prototype.ROYALE_REFLECTION_INFO = function () {\n" + > >>> + " return {\n" + > >>> + " variables: function () {return > >>> {};},\n" + > >>> + " accessors: function () {return > >>> {};},\n" + > >>> + " methods: function () {return > >>> {};}\n" + > >>> + " };\n" + > >>> + "};\n" + > >>> + "/**\n" + > >>> + " * @export\n" + > >>> + " * @const\n" + > >>> + " * @type {number}\n" + > >>> + " */\n" + > >>> + > >>> "foo.bar.A.Internal.prototype.ROYALE_REFLECTION_INFO.compileFlags = > >>> 15;\n" > >>> + > >>> + "/**\n" + > >>> + " * Provide reflection support for > >>> distinguishing dynamic fields on class object (static)\n" + > >>> + " * @export\n" + > >>> + " * @const\n" + > >>> + " * @type {Array<string>}\n" + > >>> + " */\n" + > >>> + > >>> "foo.bar.A.Internal.prototype.ROYALE_REFLECTION_INFO.statics = > >>> Object.keys(foo.bar.A.Internal);\n" > >>> ); > >>> } > >>> > >>> diff --git > >>> a/compiler-jx/src/test/resources/royale/projects/internal/MainClass_result.js > >>> b/compiler-jx/src/test/resources/royale/projects/internal/MainClass_result.js > >>> index f2bff9f..d403d5f 100644 > >>> --- > >>> a/compiler-jx/src/test/resources/royale/projects/internal/MainClass_result.js > >>> +++ > >>> b/compiler-jx/src/test/resources/royale/projects/internal/MainClass_result.js > >>> @@ -100,3 +100,32 @@ MainClass.InternalClass.prototype.foo = null; > >>> * @type {Object.<string, Array.<Object>>} > >>> */ > >>> MainClass.InternalClass.prototype.ROYALE_CLASS_INFO = { names: [{ name: > >>> 'InternalClass', qName: 'MainClass.InternalClass', kind: 'class' }] }; > >>> + > >>> + > >>> + > >>> +/** > >>> + * Reflection > >>> + * > >>> + * @return {Object.<string, Function>} > >>> + */ > >>> +MainClass.InternalClass.prototype.ROYALE_REFLECTION_INFO = function () { > >>> + return { > >>> + variables: function () { > >>> + return { > >>> + 'foo': { type: 'OtherClass', get_set: function (/** > >>> MainClass.InternalClass */ inst, /** * */ v) {return v !== undefined ? > >>> inst.foo = v : inst.foo;}} > >>> + }; > >>> + }, > >>> + accessors: function () {return {};}, > >>> + methods: function () { > >>> + return { > >>> + 'InternalClass': { type: '', declaredBy: > >>> 'MainClass.InternalClass'} > >>> + }; > >>> + } > >>> + }; > >>> +}; > >>> +/** > >>> + * @export > >>> + * @const > >>> + * @type {number} > >>> + */ > >>> +MainClass.InternalClass.prototype.ROYALE_REFLECTION_INFO.compileFlags = > >>> 9; > >>> \ No newline at end of file > >>> > >>> >