blob: 9e948288fada1ea66784cf25a6c5385da94f1507 [file] [log] [blame]
/*
*
* 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.compiler.internal.codegen.js.flexjs;
import java.util.ArrayList;
import org.apache.flex.compiler.driver.IBackend;
import org.apache.flex.compiler.internal.codegen.js.goog.TestGoogPackage;
import org.apache.flex.compiler.internal.driver.js.flexjs.FlexJSBackend;
import org.apache.flex.compiler.internal.driver.js.goog.JSGoogConfiguration;
import org.apache.flex.compiler.internal.projects.FlexJSProject;
import org.apache.flex.compiler.tree.as.IFileNode;
import org.junit.Test;
/**
* @author Erik de Bruin
*/
public class TestFlexJSPackage extends TestGoogPackage
{
@Override
public void setUp()
{
backend = createBackend();
project = new FlexJSProject(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);
((FlexJSProject)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.FLEXJS_CLASS_INFO = { names: [{ name: 'A', qName: 'A', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('A', A);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"A.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
" return {\n" +
" variables: function () {return {};},\n" +
" accessors: function () {return {};},\n" +
" methods: function () {return {};}\n" +
" };\n" +
"};\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.FLEXJS_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
" return {\n" +
" variables: function () {return {};},\n" +
" accessors: function () {return {};},\n" +
" methods: function () {return {};}\n" +
" };\n" +
"};\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.FLEXJS_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
" return {\n" +
" variables: function () {return {};},\n" +
" accessors: function () {return {};},\n" +
" methods: function () {\n" +
" return {\n" +
" 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
" };\n" +
" }\n" +
" };\n" +
"};\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.FLEXJS_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
" return {\n" +
" variables: function () {return {};},\n" +
" accessors: function () {return {};},\n" +
" methods: function () {\n" +
" return {\n" +
" 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
" };\n" +
" }\n" +
" };\n" +
"};\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.FLEXJS_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
" return {\n" +
" variables: function () {return {};},\n" +
" accessors: function () {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");
}
@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" +
" * @export\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.FLEXJS_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
" return {\n" +
" variables: function () {return {};},\n" +
" accessors: function () {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" +
"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" +
"\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.FLEXJS_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
" return {\n" +
" variables: function () {return {};},\n" +
" accessors: function () {return {};},\n" +
" methods: function () {\n" +
" return {\n" +
" 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
" };\n" +
" }\n" +
" };\n" +
"};\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.FLEXJS_CLASS_INFO = { names: [{ name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A.InternalClass', foo.bar.baz.A.InternalClass);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.InternalClass.prototype.FLEXJS_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");
}
@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" +
"\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.FLEXJS_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
" return {\n" +
" variables: function () {return {};},\n" +
" accessors: function () {return {};},\n" +
" methods: function () {\n" +
" return {\n" +
" 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
" };\n" +
" }\n" +
" };\n" +
"};\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" +
"\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.FLEXJS_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
" return {\n" +
" variables: function () {return {};},\n" +
" accessors: function () {return {};},\n" +
" methods: function () {\n" +
" return {\n" +
" 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
" };\n" +
" }\n" +
" };\n" +
"};\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * @export\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" +
"\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.FLEXJS_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
" return {\n" +
" variables: function () {return {};},\n" +
" accessors: function () {return {};},\n" +
" methods: function () {\n" +
" return {\n" +
" 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
" };\n" +
" }\n" +
" };\n" +
"};\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * @constructor\n" +
" */\n" +
"foo.bar.baz.A.InternalClass = function() {\n" +
"};\n" +
"\n" +
"\n" +
"/**\n" +
" * @export\n" +
" * @type {string}\n" +
" */\n" +
"foo.bar.baz.A.InternalClass.someString = \"foo\";\n" +
"\n" +
"\n" +
"/**\n" +
" * @export\n" +
" * @return {string}\n" +
" */\n" +
"foo.bar.baz.A.InternalClass.someStaticFunction = function() {\n" +
" return \"bar\";\n" +
"};\n" +
"\n" +
"\n" +
"/**\n" +
" * @export\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.FLEXJS_CLASS_INFO = { names: [{ name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A.InternalClass', foo.bar.baz.A.InternalClass);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.InternalClass.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
" return {\n" +
" variables: function () {\n" +
" return {\n" +
" '|someString': { type: 'String'}\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");
}
@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" +
"\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" +
"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" +
"/** @export */\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.FLEXJS_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
" return {\n" +
" variables: function () {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" +
"\n" +
"\n" +
"/**\n" +
" * @constructor\n" +
" */\n" +
"foo.bar.baz.A.InternalClass = function() {\n" +
"};\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" +
"/** @export */\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.FLEXJS_CLASS_INFO = { names: [{ name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A.InternalClass', foo.bar.baz.A.InternalClass);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.InternalClass.prototype.FLEXJS_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");
}
@Test
public void testPackageQualified_ClassAndInternalFLEXJS_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" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * @constructor\n" +
" */\n" +
"foo.bar.baz.A = function() {\n" +
" var /** @type {foo.bar.baz.A.ITestInterface} */ internalClass = org.apache.flex.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.FLEXJS_CLASS_INFO = { names: [{ name: 'A', qName: 'foo.bar.baz.A', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A', foo.bar.baz.A);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
" return {\n" +
" variables: function () {return {};},\n" +
" accessors: function () {return {};},\n" +
" methods: function () {\n" +
" return {\n" +
" 'A': { type: '', declaredBy: 'foo.bar.baz.A'}\n" +
" };\n" +
" }\n" +
" };\n" +
"};\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.FLEXJS_CLASS_INFO = { names: [{ name: 'ITestInterface', qName: 'foo.bar.baz.A.ITestInterface', kind: 'interface' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A.ITestInterface', foo.bar.baz.A.ITestInterface);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.ITestInterface.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
" return {\n" +
" accessors: function () {return {};},\n" +
" methods: function () {\n" +
" return {\n" +
" 'test': { type: 'void', declaredBy: 'foo.bar.baz.A.ITestInterface'}\n" +
" };\n" +
" }\n" +
" };\n" +
"};\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" +
" * @export\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.FLEXJS_CLASS_INFO = { names: [{ name: 'InternalClass', qName: 'foo.bar.baz.A.InternalClass', kind: 'class' }], interfaces: [foo.bar.baz.A.ITestInterface] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.baz.A.InternalClass', foo.bar.baz.A.InternalClass);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.baz.A.InternalClass.prototype.FLEXJS_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"
);
}
@Test
public void testPackageQualified_ClassAndInternalStaticConst()
{
IFileNode node = compileAS("package 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" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * @export\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" +
" * @export\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.FLEXJS_CLASS_INFO = { names: [{ name: 'Internal', qName: 'foo.bar.A.Internal', kind: 'class' }] };\n" +
"\n" +
"\n" +
"/**\n" +
" * Prevent renaming of class. Needed for reflection.\n" +
" */\n" +
"goog.exportSymbol('foo.bar.A.Internal', foo.bar.A.Internal);\n" +
"\n" +
"\n" +
"\n" +
"/**\n" +
" * Reflection\n" +
" *\n" +
" * @return {Object.<string, Function>}\n" +
" */\n" +
"foo.bar.A.Internal.prototype.FLEXJS_REFLECTION_INFO = function () {\n" +
" return {\n" +
" variables: function () {return {};},\n" +
" accessors: function () {return {};},\n" +
" methods: function () {return {};}\n" +
" };\n" +
"};\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 * @export\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 * @export\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 * @export\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 * @export\n * @type {string}\n */\nfoo.bar.baz.A = \"Hello\"");
}
@Override
protected IBackend createBackend()
{
return new FlexJSBackend();
}
}