| /* |
| * |
| * 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.compiler.internal.codegen.js.royale; |
| |
| import java.util.ArrayList; |
| |
| import org.apache.royale.compiler.driver.IBackend; |
| import org.apache.royale.compiler.internal.codegen.js.goog.TestGoogPackage; |
| import org.apache.royale.compiler.internal.driver.js.royale.RoyaleBackend; |
| import org.apache.royale.compiler.internal.driver.js.goog.JSGoogConfiguration; |
| import org.apache.royale.compiler.internal.projects.RoyaleJSProject; |
| import org.apache.royale.compiler.tree.as.IFileNode; |
| import org.junit.Test; |
| |
| /** |
| * @author Erik de Bruin |
| */ |
| public class TestRoyalePackage extends TestGoogPackage |
| { |
| @Override |
| public void setUp() |
| { |
| backend = createBackend(); |
| project = new RoyaleJSProject(workspace, backend); |
| JSGoogConfiguration config = new JSGoogConfiguration(); |
| ArrayList<String> values = new ArrayList<String>(); |
| values.add("Event"); |
| values.add("Before"); |
| config.setCompilerKeepAs3Metadata(null, values); |
| ArrayList<String> values2 = new ArrayList<String>(); |
| values2.add("Before"); |
| config.setCompilerKeepCodeWithMetadata(null, values2); |
| ((RoyaleJSProject)project).config = config; |
| super.setUp(); |
| } |
| |
| @Override |
| @Test |
| public void testPackageSimple_Class() |
| { |
| // does JS need a implicit constructor function? ... always? |
| // All class nodes in AST get either an implicit or explicit constructor |
| // this is an implicit and the way I have the before/after handler working |
| // with block disallows implicit blocks from getting { } |
| |
| // (erikdebruin) the constuctor IS the class definition, in 'goog' JS, |
| // therefor we need to write out implicit constructors |
| // (if I understand the term correctly) |
| |
| IFileNode node = compileAS("package {public class A{}}"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n" + |
| " * A\n" + |
| " *\n" + |
| " * @fileoverview\n" + |
| " *\n" + |
| " * @suppress {checkTypes|accessControls}\n" + |
| " */\n" + |
| "\n" + |
| "goog.provide('A');\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "A = function() {\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\n" + |
| " * @type {Object.<string, Array.<Object>>}\n" + |
| " */\n" + |
| "A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'A', kind: 'class' }] };\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Reflection\n" + |
| " *\n" + |
| " * @return {Object.<string, Function>}\n" + |
| " */\n" + |
| "A.prototype.ROYALE_REFLECTION_INFO = function () {\n" + |
| " return {};\n" + |
| "};\n"+ |
| "/**\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "A.prototype.ROYALE_COMPILE_FLAGS = 15;\n"); |
| } |
| |
| @Override |
| @Test |
| public void testPackageQualified_Class() |
| { |
| IFileNode node = compileAS("package foo.bar.baz {public class A{}}"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n" + |
| " * foo.bar.baz.A\n" + |
| " *\n" + |
| " * @fileoverview\n" + |
| " *\n" + |
| " * @suppress {checkTypes|accessControls}\n" + |
| " */\n" + |
| "\n" + |
| "goog.provide('foo.bar.baz.A');\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "foo.bar.baz.A = function() {\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\n" + |
| " * @type {Object.<string, Array.<Object>>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Reflection\n" + |
| " *\n" + |
| " * @return {Object.<string, Function>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" + |
| " return {};\n" + |
| "};\n"+ |
| "/**\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_COMPILE_FLAGS = 15;\n"); |
| } |
| |
| @Override |
| @Test |
| public void testPackageQualified_ClassBody() |
| { |
| IFileNode node = compileAS("package foo.bar.baz {public class A{public function A(){}}}"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n" + |
| " * foo.bar.baz.A\n" + |
| " *\n" + |
| " * @fileoverview\n" + |
| " *\n" + |
| " * @suppress {checkTypes|accessControls}\n" + |
| " */\n" + |
| "\n" + |
| "goog.provide('foo.bar.baz.A');\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "foo.bar.baz.A = function() {\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\n" + |
| " * @type {Object.<string, Array.<Object>>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Reflection\n" + |
| " *\n" + |
| " * @return {Object.<string, Function>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" + |
| " return {\n" + |
| " methods: function () {\n" + |
| " return {\n" + |
| " 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" + |
| " };\n" + |
| " }\n" + |
| " };\n" + |
| "};\n" + |
| "/**\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_COMPILE_FLAGS = 15;\n" |
| |
| ); |
| } |
| |
| @Override |
| @Test |
| public void testPackageQualified_ClassBodyMethodContents() |
| { |
| IFileNode node = compileAS("package foo.bar.baz {public class A{public function A(){if (a){for (var i:Object in obj){doit();}}}}}"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n" + |
| " * foo.bar.baz.A\n" + |
| " *\n" + |
| " * @fileoverview\n" + |
| " *\n" + |
| " * @suppress {checkTypes|accessControls}\n" + |
| " */\n" + |
| "\n" + |
| "goog.provide('foo.bar.baz.A');\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "foo.bar.baz.A = function() {\n" + |
| " if (a) {\n" + |
| " for (var /** @type {Object} */ i in obj) {\n" + |
| " doit();\n" + |
| " }\n" + |
| " }\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\n" + |
| " * @type {Object.<string, Array.<Object>>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Reflection\n" + |
| " *\n" + |
| " * @return {Object.<string, Function>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" + |
| " return {\n" + |
| " methods: function () {\n" + |
| " return {\n" + |
| " 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" + |
| " };\n" + |
| " }\n" + |
| " };\n" + |
| "};\n" + |
| "/**\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_COMPILE_FLAGS = 15;\n"); |
| } |
| |
| @Test |
| public void testPackageQualified_ClassBodyMetaData() |
| { |
| IFileNode node = compileAS("package foo.bar.baz {[Event(name='add', type='mx.events.FlexEvent')]\npublic class A{public function A(){}}}"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n" + |
| " * foo.bar.baz.A\n" + |
| " *\n" + |
| " * @fileoverview\n" + |
| " *\n" + |
| " * @suppress {checkTypes|accessControls}\n" + |
| " */\n" + |
| "\n" + |
| "goog.provide('foo.bar.baz.A');\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "foo.bar.baz.A = function() {\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\n" + |
| " * @type {Object.<string, Array.<Object>>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Reflection\n" + |
| " *\n" + |
| " * @return {Object.<string, Function>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" + |
| " return {\n" + |
| " methods: function () {\n" + |
| " return {\n" + |
| " 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" + |
| " };\n" + |
| " },\n" + |
| " metadata: function () { return [ { name: 'Event', args: [ { key: 'name', value: 'add' }, { key: 'type', value: 'mx.events.FlexEvent' } ] } ]; }\n" + |
| " };\n" + |
| "};\n" + |
| "/**\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_COMPILE_FLAGS = 15;\n"); |
| } |
| |
| @Test |
| public void testPackageQualified_ExportPropertyForMetadata() |
| { |
| IFileNode node = compileAS("package foo.bar.baz {[Event(name='add', type='mx.events.FlexEvent')]\npublic class A{public function A(){}\n[Before]\npublic function foo() {}}}"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n" + |
| " * foo.bar.baz.A\n" + |
| " *\n" + |
| " * @fileoverview\n" + |
| " *\n" + |
| " * @suppress {checkTypes|accessControls}\n" + |
| " */\n" + |
| "\n" + |
| "goog.provide('foo.bar.baz.A');\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "foo.bar.baz.A = function() {\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.foo = function() {\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\n" + |
| " * @type {Object.<string, Array.<Object>>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Reflection\n" + |
| " *\n" + |
| " * @return {Object.<string, Function>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" + |
| " return {\n" + |
| " methods: function () {\n" + |
| " return {\n" + |
| " 'A': { type: '', declaredBy: 'foo.bar.baz.A'},\n" + |
| " 'foo': { type: '', declaredBy: 'foo.bar.baz.A', metadata: function () { return [ { name: 'Before' } ]; }}\n" + |
| " };\n" + |
| " },\n" + |
| " metadata: function () { return [ { name: 'Event', args: [ { key: 'name', value: 'add' }, { key: 'type', value: 'mx.events.FlexEvent' } ] } ]; }\n" + |
| " };\n" + |
| "};\n" + |
| "/**\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_COMPILE_FLAGS = 15;\n" + |
| "goog.exportProperty(foo.bar.baz.A.prototype, 'foo', foo.bar.baz.A.prototype.foo);\n" ); |
| } |
| |
| @Test |
| public void testPackageQualified_ClassAndInternalClass() |
| { |
| IFileNode node = compileAS("package foo.bar.baz {\n" + |
| "public class A {\n" + |
| "public function A(){\n" + |
| "var internalClass:InternalClass = new InternalClass();\n" + |
| "}}}\n" + |
| "class InternalClass {\n" + |
| "public function InternalClass(){}\n" + |
| "}"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n" + |
| " * foo.bar.baz.A\n" + |
| " *\n" + |
| " * @fileoverview\n" + |
| " *\n" + |
| " * @suppress {checkTypes|accessControls}\n" + |
| " */\n" + |
| "\n" + |
| "goog.provide('foo.bar.baz.A');\n" + |
| "goog.provide('foo.bar.baz.A.InternalClass');\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "foo.bar.baz.A = function() {\n" + |
| " var /** @type {foo.bar.baz.A.InternalClass} */ internalClass = new foo.bar.baz.A.InternalClass();\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\n" + |
| " * @type {Object.<string, Array.<Object>>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Reflection\n" + |
| " *\n" + |
| " * @return {Object.<string, Function>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" + |
| " return {\n" + |
| " methods: function () {\n" + |
| " return {\n" + |
| " 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" + |
| " };\n" + |
| " }\n" + |
| " };\n" + |
| "};\n" + |
| "/**\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_COMPILE_FLAGS = 15;\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "foo.bar.baz.A.InternalClass = function() {\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\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' }] };\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" + |
| " methods: function () {\n" + |
| " return {\n" + |
| " 'InternalClass': { type: '', declaredBy: 'foo.bar.baz.A.InternalClass'}\n" + |
| " };\n" + |
| " }\n" + |
| " };\n" + |
| "};\n" + |
| "/**\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.InternalClass.prototype.ROYALE_COMPILE_FLAGS = 15;\n" |
| ); |
| } |
| |
| @Test |
| public void testPackageQualified_ClassAndInternalFunction() |
| { |
| IFileNode node = compileAS("package foo.bar.baz {\n" + |
| "public class A {\n" + |
| "public function A(){\n" + |
| "internalFunction();\n" + |
| "}}}\n" + |
| "function internalFunction(){}"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n" + |
| " * foo.bar.baz.A\n" + |
| " *\n" + |
| " * @fileoverview\n" + |
| " *\n" + |
| " * @suppress {checkTypes|accessControls}\n" + |
| " */\n" + |
| "\n" + |
| "goog.provide('foo.bar.baz.A');\n" + |
| "goog.provide('foo.bar.baz.A.internalFunction');\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "foo.bar.baz.A = function() {\n" + |
| " foo.bar.baz.A.internalFunction();\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\n" + |
| " * @type {Object.<string, Array.<Object>>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Reflection\n" + |
| " *\n" + |
| " * @return {Object.<string, Function>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" + |
| " return {\n" + |
| " methods: function () {\n" + |
| " return {\n" + |
| " 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" + |
| " };\n" + |
| " }\n" + |
| " };\n" + |
| "};\n" + |
| "/**\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_COMPILE_FLAGS = 15;\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "foo.bar.baz.A.internalFunction = function() {\n" + |
| "}"); |
| } |
| |
| @Test |
| public void testPackageQualified_ClassAndInternalVariable() |
| { |
| IFileNode node = compileAS("package foo.bar.baz {\n" + |
| "public class A {\n" + |
| "public function A(){\n" + |
| "internalVar = 3;\n" + |
| "}}}\n" + |
| "var internalVar:Number = 2;"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n" + |
| " * foo.bar.baz.A\n" + |
| " *\n" + |
| " * @fileoverview\n" + |
| " *\n" + |
| " * @suppress {checkTypes|accessControls}\n" + |
| " */\n" + |
| "\n" + |
| "goog.provide('foo.bar.baz.A');\n" + |
| "goog.provide('foo.bar.baz.A.internalVar');\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "foo.bar.baz.A = function() {\n" + |
| " foo.bar.baz.A.internalVar = 3;\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\n" + |
| " * @type {Object.<string, Array.<Object>>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Reflection\n" + |
| " *\n" + |
| " * @return {Object.<string, Function>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" + |
| " return {\n" + |
| " methods: function () {\n" + |
| " return {\n" + |
| " 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" + |
| " };\n" + |
| " }\n" + |
| " };\n" + |
| "};\n" + |
| "/**\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_COMPILE_FLAGS = 15;\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @package\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.internalVar = 2" |
| ); |
| } |
| |
| @Test |
| public void testPackageQualified_ClassAndInternalClassMethods() |
| { |
| IFileNode node = compileAS("package foo.bar.baz {\n" + |
| "public class A {\n" + |
| "public function A(){\n" + |
| "var internalClass:InternalClass = new InternalClass();\n" + |
| "var myString:String = InternalClass.someString;\n" + |
| "myString = InternalClass.someStaticFunction();\n" + |
| "myString = internalClass.someMethod();\n" + |
| "}}}\n" + |
| "class InternalClass {\n" + |
| "public function InternalClass(){\n" + |
| "}\n" + |
| "public static var someString:String = \"foo\";\n" + |
| "public static function someStaticFunction():String { return \"bar\";}\n" + |
| "public function someMethod():String { return \"baz\";}\n" + |
| "}"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n" + |
| " * foo.bar.baz.A\n" + |
| " *\n" + |
| " * @fileoverview\n" + |
| " *\n" + |
| " * @suppress {checkTypes|accessControls}\n" + |
| " */\n" + |
| "\n" + |
| "goog.provide('foo.bar.baz.A');\n" + |
| "goog.provide('foo.bar.baz.A.InternalClass');\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "foo.bar.baz.A = function() {\n" + |
| " var /** @type {foo.bar.baz.A.InternalClass} */ internalClass = new foo.bar.baz.A.InternalClass();\n" + |
| " var /** @type {string} */ myString = foo.bar.baz.A.InternalClass.someString;\n" + |
| " myString = foo.bar.baz.A.InternalClass.someStaticFunction();\n" + |
| " myString = internalClass.someMethod();\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\n" + |
| " * @type {Object.<string, Array.<Object>>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Reflection\n" + |
| " *\n" + |
| " * @return {Object.<string, Function>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" + |
| " return {\n" + |
| " methods: function () {\n" + |
| " return {\n" + |
| " 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" + |
| " };\n" + |
| " }\n" + |
| " };\n" + |
| "};\n" + |
| "/**\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_COMPILE_FLAGS = 15;\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "foo.bar.baz.A.InternalClass = function() {\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @nocollapse\n" + |
| " * @type {string}\n" + |
| " */\n" + |
| "foo.bar.baz.A.InternalClass.someString = \"foo\";\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @nocollapse\n" + |
| " * @return {string}\n" + |
| " */\n" + |
| "foo.bar.baz.A.InternalClass.someStaticFunction = function() {\n" + |
| " return \"bar\";\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @return {string}\n" + |
| " */\n" + |
| "foo.bar.baz.A.InternalClass.prototype.someMethod = function() {\n" + |
| " return \"baz\";\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\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' }] };\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" + |
| " 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" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.InternalClass.prototype.ROYALE_COMPILE_FLAGS = 15;\n" + |
| "/**\n" + |
| " * Provide reflection support for distinguishing dynamic fields on class object (static)\n" + |
| " * @const\n" + |
| " * @type {Array<string>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.InternalClass.prototype.ROYALE_INITIAL_STATICS = Object.keys(foo.bar.baz.A.InternalClass);\n" |
| ); |
| } |
| |
| @Test |
| public void testPackageQualified_ClassAndInternalGettersAndSetters() |
| { |
| IFileNode node = compileAS("package foo.bar.baz {\n" + |
| "public class A {\n" + |
| "public function A(){\n" + |
| "var internalClass:InternalClass = new InternalClass();\n" + |
| "myString = internalClass.someString;\n" + |
| "internalClass.someString = myString;\n" + |
| "}\n" + |
| "public function get myString():String {\n" + |
| " return null;\n" + |
| "}\n" + |
| "public function set myString(value:String):void {}\n" + |
| "}}\n" + |
| "class InternalClass {\n" + |
| "public function InternalClass(){\n" + |
| "}\n" + |
| "public function get someString():String {\n" + |
| " return null;\n" + |
| "}\n" + |
| "public function set someString(value:String):void {}\n" + |
| "}"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n" + |
| " * foo.bar.baz.A\n" + |
| " *\n" + |
| " * @fileoverview\n" + |
| " *\n" + |
| " * @suppress {checkTypes|accessControls}\n" + |
| " */\n" + |
| "\n" + |
| "goog.provide('foo.bar.baz.A');\n" + |
| "goog.provide('foo.bar.baz.A.InternalClass');\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "foo.bar.baz.A = function() {\n" + |
| " var /** @type {foo.bar.baz.A.InternalClass} */ internalClass = new foo.bar.baz.A.InternalClass();\n" + |
| " this.myString = internalClass.someString;\n" + |
| " internalClass.someString = this.myString;\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @nocollapse\n" + |
| " * @export\n" + |
| " * @type {string}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.myString;\n" + |
| "\n" + |
| "\n" + |
| "foo.bar.baz.A.prototype.get__myString = function() {\n" + |
| " return null;\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "foo.bar.baz.A.prototype.set__myString = function(value) {\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "Object.defineProperties(foo.bar.baz.A.prototype, /** @lends {foo.bar.baz.A.prototype} */ {\n" + |
| "/**\n" + |
| " * @type {string}\n" + |
| " */\n" + |
| "myString: {\n" + |
| "get: foo.bar.baz.A.prototype.get__myString,\n" + |
| "set: foo.bar.baz.A.prototype.set__myString}}\n" + |
| ");\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\n" + |
| " * @type {Object.<string, Array.<Object>>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Reflection\n" + |
| " *\n" + |
| " * @return {Object.<string, Function>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" + |
| " return {\n" + |
| " accessors: function () {\n" + |
| " return {\n" + |
| " 'myString': { type: 'String', access: 'readwrite', declaredBy: 'foo.bar.baz.A'}\n" + |
| " };\n" + |
| " },\n" + |
| " methods: function () {\n" + |
| " return {\n" + |
| " 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" + |
| " };\n" + |
| " }\n" + |
| " };\n" + |
| "};\n" + |
| "/**\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_COMPILE_FLAGS = 15;\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "foo.bar.baz.A.InternalClass = function() {\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @nocollapse\n" + |
| " * @export\n" + |
| " * @type {string}\n" + |
| " */\n" + |
| "foo.bar.baz.A.InternalClass.prototype.someString;\n" + |
| "\n" + |
| "\n" + |
| "foo.bar.baz.A.InternalClass.prototype.get__someString = function() {\n" + |
| " return null;\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "foo.bar.baz.A.InternalClass.prototype.set__someString = function(value) {\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "Object.defineProperties(foo.bar.baz.A.InternalClass.prototype, /** @lends {foo.bar.baz.A.InternalClass.prototype} */ {\n" + |
| "/**\n" + |
| " * @type {string}\n" + |
| " */\n" + |
| "someString: {\n" + |
| "get: foo.bar.baz.A.InternalClass.prototype.get__someString,\n" + |
| "set: foo.bar.baz.A.InternalClass.prototype.set__someString}}\n" + |
| ");\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\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' }] };\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" + |
| " 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" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.InternalClass.prototype.ROYALE_COMPILE_FLAGS = 15;\n" |
| ); |
| } |
| |
| @Test |
| public void testPackageQualified_ClassAndInternalROYALE_CLASS_INFO() |
| { |
| IFileNode node = compileAS("package foo.bar.baz {\n" + |
| "public class A {\n" + |
| "public function A(){\n" + |
| "var internalClass:ITestInterface = new InternalClass() as ITestInterface;\n" + |
| "internalClass.test();\n" + |
| "}\n" + |
| "}}\n" + |
| "interface ITestInterface {\n" + |
| "function test():void;\n" + |
| "}\n" + |
| "class InternalClass implements ITestInterface {\n" + |
| "public function InternalClass(){\n" + |
| "}\n" + |
| "public function test():void {}\n" + |
| "}"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n" + |
| " * foo.bar.baz.A\n" + |
| " *\n" + |
| " * @fileoverview\n" + |
| " *\n" + |
| " * @suppress {checkTypes|accessControls}\n" + |
| " */\n" + |
| "\n" + |
| "goog.provide('foo.bar.baz.A');\n" + |
| "goog.provide('foo.bar.baz.A.ITestInterface');\n" + |
| "goog.provide('foo.bar.baz.A.InternalClass');\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "foo.bar.baz.A = function() {\n" + |
| " var /** @type {foo.bar.baz.A.ITestInterface} */ internalClass = org.apache.royale.utils.Language.as(new foo.bar.baz.A.InternalClass(), foo.bar.baz.A.ITestInterface);\n" + |
| " internalClass.test();\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\n" + |
| " * @type {Object.<string, Array.<Object>>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Reflection\n" + |
| " *\n" + |
| " * @return {Object.<string, Function>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_REFLECTION_INFO = function () {\n" + |
| " return {\n" + |
| " methods: function () {\n" + |
| " return {\n" + |
| " 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" + |
| " };\n" + |
| " }\n" + |
| " };\n" + |
| "};\n" + |
| "/**\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.prototype.ROYALE_COMPILE_FLAGS = 15;\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @interface\n" + |
| " */\n" + |
| "foo.bar.baz.A.ITestInterface = function() {\n" + |
| "};\n" + |
| "foo.bar.baz.A.ITestInterface.prototype.test = function() {\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\n" + |
| " * @type {Object.<string, Array.<Object>>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.ITestInterface.prototype.ROYALE_CLASS_INFO = { names: [{ name: 'ITestInterface', qName: 'foo.bar.baz.A.ITestInterface', kind: 'interface' }] };\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Reflection\n" + |
| " *\n" + |
| " * @return {Object.<string, Function>}\n" + |
| " */\n" + |
| "foo.bar.baz.A.ITestInterface.prototype.ROYALE_REFLECTION_INFO = function () {\n" + |
| " return {\n" + |
| " methods: function () {\n" + |
| " return {\n" + |
| " 'test': { type: 'void', declaredBy: 'foo.bar.baz.A.ITestInterface'}\n" + |
| " };\n" + |
| " }\n" + |
| " };\n" + |
| "};\n" + |
| "/**\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.ITestInterface.prototype.ROYALE_COMPILE_FLAGS = 15;\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " * @implements {foo.bar.baz.A.ITestInterface}\n" + |
| " */\n" + |
| "foo.bar.baz.A.InternalClass = function() {\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " */\n" + |
| "foo.bar.baz.A.InternalClass.prototype.test = function() {\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\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] };\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" + |
| " 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" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.baz.A.InternalClass.prototype.ROYALE_COMPILE_FLAGS = 15;\n" |
| ); |
| } |
| |
| @Test |
| public void testPackageQualified_ClassAndInternalStaticConst() |
| { |
| IFileNode node = compileAS("package foo.bar {\n" + |
| //adding an unneeded import node here exposed a failing test at one point: |
| "import foo.bar.*\n" + |
| "public function A():Number {\n" + |
| " return Internal.x;\n" + |
| "}}\n" + |
| "internal class Internal {" + |
| "public static const x:Number = 3;}"); |
| |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n" + |
| " * foo.bar.A\n" + |
| " *\n" + |
| " * @fileoverview\n" + |
| " *\n" + |
| " * @suppress {checkTypes|accessControls}\n" + |
| " */\n" + |
| "\n" + |
| "goog.provide('foo.bar.A');\n" + |
| "goog.provide('foo.bar.A.Internal');\n" + |
| "\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @return {number}\n" + |
| " */\n" + |
| "foo.bar.A = function() {\n" + |
| " return foo.bar.A.Internal.x;\n" + |
| "}\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @constructor\n" + |
| " */\n" + |
| "foo.bar.A.Internal = function() {\n" + |
| "};\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * @nocollapse\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.A.Internal.x = 3;\n" + |
| "\n" + |
| "\n" + |
| "/**\n" + |
| " * Metadata\n" + |
| " *\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' }] };\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" + |
| "};\n" + |
| "/**\n" + |
| " * @const\n" + |
| " * @type {number}\n" + |
| " */\n" + |
| "foo.bar.A.Internal.prototype.ROYALE_COMPILE_FLAGS = 15;\n" + |
| "/**\n" + |
| " * Provide reflection support for distinguishing dynamic fields on class object (static)\n" + |
| " * @const\n" + |
| " * @type {Array<string>}\n" + |
| " */\n" + |
| "foo.bar.A.Internal.prototype.ROYALE_INITIAL_STATICS = Object.keys(foo.bar.A.Internal);\n" |
| ); |
| } |
| |
| @Test |
| public void testPackageSimple_Function() |
| { |
| IFileNode node = compileAS("package {public function A(){}}"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n * A\n *\n * @fileoverview\n *\n * @suppress {checkTypes|accessControls}\n */\n\ngoog.provide('A');\n\n\n\n/**\n */\nA = function() {\n}"); |
| } |
| |
| @Test |
| public void testPackageQualified_Function() |
| { |
| IFileNode node = compileAS("package foo.bar.baz {public function A(){}}"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n * foo.bar.baz.A\n *\n * @fileoverview\n *\n * @suppress {checkTypes|accessControls}\n */\n\ngoog.provide('foo.bar.baz.A');\n\n\n\n/**\n */\nfoo.bar.baz.A = function() {\n}"); |
| } |
| |
| @Test |
| public void testPackageSimple_Variable() |
| { |
| IFileNode node = compileAS("package {public var A:String = \"Hello\";}"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n * A\n *\n * @fileoverview\n *\n * @suppress {checkTypes|accessControls}\n */\n\ngoog.provide('A');\n\n\n\n/**\n * @type {string}\n */\nA = \"Hello\""); |
| } |
| |
| @Test |
| public void testPackageQualified_Variable() |
| { |
| IFileNode node = compileAS("package foo.bar.baz {public var A:String = \"Hello\";}"); |
| asBlockWalker.visitFile(node); |
| assertOutWithMetadata("/**\n * foo.bar.baz.A\n *\n * @fileoverview\n *\n * @suppress {checkTypes|accessControls}\n */\n\ngoog.provide('foo.bar.baz.A');\n\n\n\n/**\n * @type {string}\n */\nfoo.bar.baz.A = \"Hello\""); |
| } |
| |
| @Override |
| protected IBackend createBackend() |
| { |
| return new RoyaleBackend(); |
| } |
| |
| } |