Repository: flex-falcon Updated Branches: refs/heads/develop 6bd08f108 -> 53c43a1b5
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e1c69a7d/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_same_package_as_conflict/mypackage/TestClass_result.js ---------------------------------------------------------------------- diff --git a/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_same_package_as_conflict/mypackage/TestClass_result.js b/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_same_package_as_conflict/mypackage/TestClass_result.js index c00a208..0950a77 100644 --- a/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_same_package_as_conflict/mypackage/TestClass_result.js +++ b/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_same_package_as_conflict/mypackage/TestClass_result.js @@ -48,3 +48,28 @@ mypackage.TestClass.prototype.event; * @type {Object.<string, Array.<Object>>} */ mypackage.TestClass.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 'TestClass', qName: 'mypackage.TestClass'}] }; + + + +/** + * Reflection + * + * @return {Object.<string, Function>} + */ +mypackage.TestClass.prototype.FLEXJS_REFLECTION_INFO = function () { + return { + variables: function () { + return { + }; + }, + accessors: function () { + return { + }; + }, + methods: function () { + return { + 'TestClass': { type: '', declaredBy: 'mypackage.TestClass'} + }; + } + }; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e1c69a7d/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/Event_result.js ---------------------------------------------------------------------- diff --git a/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/Event_result.js b/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/Event_result.js index 8bd22d5..1382eb5 100644 --- a/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/Event_result.js +++ b/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/Event_result.js @@ -37,3 +37,28 @@ Event = function() { * @type {Object.<string, Array.<Object>>} */ Event.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 'Event', qName: 'Event'}] }; + + + +/** + * Reflection + * + * @return {Object.<string, Function>} + */ +Event.prototype.FLEXJS_REFLECTION_INFO = function () { + return { + variables: function () { + return { + }; + }, + accessors: function () { + return { + }; + }, + methods: function () { + return { + 'Event': { type: '', declaredBy: 'Event'} + }; + } + }; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e1c69a7d/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/UseWindow_result.js ---------------------------------------------------------------------- diff --git a/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/UseWindow_result.js b/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/UseWindow_result.js index b9344e0..162ee47 100644 --- a/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/UseWindow_result.js +++ b/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/UseWindow_result.js @@ -12,7 +12,6 @@ * limitations under the License. */ /** - * Generated by Apache Flex Cross-Compiler from UseWindow.as * UseWindow * * @fileoverview @@ -47,3 +46,28 @@ UseWindow.prototype.testClass; * @type {Object.<string, Array.<Object>>} */ UseWindow.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 'UseWindow', qName: 'UseWindow'}] }; + + + +/** + * Reflection + * + * @return {Object.<string, Function>} + */ +UseWindow.prototype.FLEXJS_REFLECTION_INFO = function () { + return { + variables: function () { + return { + }; + }, + accessors: function () { + return { + }; + }, + methods: function () { + return { + 'UseWindow': { type: '', declaredBy: 'UseWindow'} + }; + } + }; +}; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e1c69a7d/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/mypackage/TestClass_result.js ---------------------------------------------------------------------- diff --git a/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/mypackage/TestClass_result.js b/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/mypackage/TestClass_result.js index 3e3362b..0a15bf8 100644 --- a/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/mypackage/TestClass_result.js +++ b/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/mypackage/TestClass_result.js @@ -56,3 +56,28 @@ mypackage.TestClass.prototype.event2; * @type {Object.<string, Array.<Object>>} */ mypackage.TestClass.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 'TestClass', qName: 'mypackage.TestClass'}] }; + + + +/** + * Reflection + * + * @return {Object.<string, Function>} + */ +mypackage.TestClass.prototype.FLEXJS_REFLECTION_INFO = function () { + return { + variables: function () { + return { + }; + }, + accessors: function () { + return { + }; + }, + methods: function () { + return { + 'TestClass': { type: '', declaredBy: 'mypackage.TestClass'} + }; + } + }; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e1c69a7d/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/otherpackage/Event_result.js ---------------------------------------------------------------------- diff --git a/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/otherpackage/Event_result.js b/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/otherpackage/Event_result.js index edc8003..d8ba2eb 100644 --- a/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/otherpackage/Event_result.js +++ b/compiler.jx.tests/test-files/flexjs/projects/package_conflicts_use_window/otherpackage/Event_result.js @@ -37,3 +37,28 @@ otherpackage.Event = function() { * @type {Object.<string, Array.<Object>>} */ otherpackage.Event.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 'Event', qName: 'otherpackage.Event'}] }; + + + +/** + * Reflection + * + * @return {Object.<string, Function>} + */ +otherpackage.Event.prototype.FLEXJS_REFLECTION_INFO = function () { + return { + variables: function () { + return { + }; + }, + accessors: function () { + return { + }; + }, + methods: function () { + return { + 'Event': { type: '', declaredBy: 'otherpackage.Event'} + }; + } + }; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e1c69a7d/compiler.jx.tests/test-files/flexjs/projects/super/Base_result.js ---------------------------------------------------------------------- diff --git a/compiler.jx.tests/test-files/flexjs/projects/super/Base_result.js b/compiler.jx.tests/test-files/flexjs/projects/super/Base_result.js index 784541c..b30fc00 100644 --- a/compiler.jx.tests/test-files/flexjs/projects/super/Base_result.js +++ b/compiler.jx.tests/test-files/flexjs/projects/super/Base_result.js @@ -56,3 +56,29 @@ set: /** @this {Base} */ function(value) { * @type {Object.<string, Array.<Object>>} */ Base.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 'Base', qName: 'Base'}] }; + + + +/** + * Reflection + * + * @return {Object.<string, Function>} + */ +Base.prototype.FLEXJS_REFLECTION_INFO = function () { + return { + variables: function () { + return { + }; + }, + accessors: function () { + return { + 'text': { type: 'String', declaredBy: 'Base'} + }; + }, + methods: function () { + return { + 'Base': { type: '', declaredBy: 'Base'} + }; + } + }; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e1c69a7d/compiler.jx.tests/test-files/flexjs/projects/super/Super_result.js ---------------------------------------------------------------------- diff --git a/compiler.jx.tests/test-files/flexjs/projects/super/Super_result.js b/compiler.jx.tests/test-files/flexjs/projects/super/Super_result.js index baf2c62..fd3ad66 100644 --- a/compiler.jx.tests/test-files/flexjs/projects/super/Super_result.js +++ b/compiler.jx.tests/test-files/flexjs/projects/super/Super_result.js @@ -57,3 +57,29 @@ set: /** @this {Super} */ function(value) { * @type {Object.<string, Array.<Object>>} */ Super.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 'Super', qName: 'Super'}] }; + + + +/** + * Reflection + * + * @return {Object.<string, Function>} + */ +Super.prototype.FLEXJS_REFLECTION_INFO = function () { + return { + variables: function () { + return { + }; + }, + accessors: function () { + return { + 'text': { type: 'String', declaredBy: 'Super'} + }; + }, + methods: function () { + return { + 'Super': { type: '', declaredBy: 'Super'} + }; + } + }; +}; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e1c69a7d/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java index 5f3f768..5c45227 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/JSSessionModel.java @@ -26,8 +26,10 @@ import java.util.List; import java.util.Stack; import org.apache.flex.compiler.definitions.IClassDefinition; +import org.apache.flex.compiler.tree.as.IFunctionNode; import org.apache.flex.compiler.tree.as.IGetterNode; import org.apache.flex.compiler.tree.as.ISetterNode; +import org.apache.flex.compiler.tree.as.IVariableNode; /** * @author Michael Schmalle @@ -52,6 +54,8 @@ public class JSSessionModel public List<String> interfacePropertyMap; public LinkedHashMap<String, PropertyNodes> staticPropertyMap; public ArrayList<String> bindableVars; + public ArrayList<IVariableNode> vars; + public ArrayList<IFunctionNode> methods; public IClassDefinition classDefinition; } private Stack<Context> stack = new Stack<Context>(); @@ -64,6 +68,10 @@ public class JSSessionModel private ArrayList<String> bindableVars = new ArrayList<String>(); + private ArrayList<IVariableNode> vars = new ArrayList<IVariableNode>(); + + private ArrayList<IFunctionNode> methods = new ArrayList<IFunctionNode>(); + private HashMap<String, String> internalClasses; private int foreachLoopCount = 0; @@ -86,12 +94,16 @@ public class JSSessionModel context.propertyMap = propertyMap; context.staticPropertyMap = staticPropertyMap; context.classDefinition = this.currentClass; + context.vars = vars; + context.methods = methods; stack.push(context); this.currentClass = currentClass; bindableVars = new ArrayList<String>(); staticPropertyMap = new LinkedHashMap<String, PropertyNodes>(); interfacePropertyMap = new ArrayList<String>(); propertyMap = new LinkedHashMap<String, PropertyNodes>(); + vars = new ArrayList<IVariableNode>(); + methods = new ArrayList<IFunctionNode>(); } public void popClass() @@ -102,6 +114,8 @@ public class JSSessionModel staticPropertyMap = context.staticPropertyMap; propertyMap = context.propertyMap; interfacePropertyMap = context.interfacePropertyMap; + vars = context.vars; + methods = context.methods; } public HashMap<String, PropertyNodes> getPropertyMap() @@ -129,6 +143,16 @@ public class JSSessionModel return bindableVars; } + public List<IVariableNode> getVars() + { + return vars; + } + + public List<IFunctionNode> getMethods() + { + return methods; + } + public HashMap<String, String> getInternalClasses() { if (internalClasses == null) http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e1c69a7d/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java index 558d0ba..6fb1f11 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitter.java @@ -102,7 +102,7 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter private JSFlexJSDocEmitter docEmitter = null; private PackageHeaderEmitter packageHeaderEmitter; - private PackageFooterEmitter packageFooterEmitter; + public PackageFooterEmitter packageFooterEmitter; private BindableEmitter bindableEmitter; @@ -110,9 +110,9 @@ public class JSFlexJSEmitter extends JSGoogEmitter implements IJSFlexJSEmitter private InterfaceEmitter interfaceEmitter; private FieldEmitter fieldEmitter; - private VarDeclarationEmitter varDeclarationEmitter; - private AccessorEmitter accessorEmitter; - private MethodEmitter methodEmitter; + public VarDeclarationEmitter varDeclarationEmitter; + public AccessorEmitter accessorEmitter; + public MethodEmitter methodEmitter; private FunctionCallEmitter functionCallEmitter; private SuperCallEmitter superCallEmitter; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e1c69a7d/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitterTokens.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitterTokens.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitterTokens.java index 4c4a16b..ac4fc8d 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitterTokens.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitterTokens.java @@ -27,6 +27,7 @@ import org.apache.flex.compiler.codegen.IEmitterTokens; public enum JSFlexJSEmitterTokens implements IEmitterTokens { FLEXJS_CLASS_INFO("FLEXJS_CLASS_INFO"), + FLEXJS_REFLECTION_INFO("FLEXJS_REFLECTION_INFO"), INDENT(" "), INTERFACES("interfaces"), LANGUAGE_QNAME("org.apache.flex.utils.Language"), http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e1c69a7d/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MethodEmitter.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MethodEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MethodEmitter.java index 086fcc0..66210ca 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MethodEmitter.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/MethodEmitter.java @@ -50,6 +50,8 @@ public class MethodEmitter extends JSSubEmitter implements @Override public void emit(IFunctionNode node) { + getModel().getMethods().add(node); + // TODO (mschmalle) will remove this cast as more things get abstracted JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter(); http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e1c69a7d/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java index daffb46..b8f1e42 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java @@ -20,24 +20,34 @@ package org.apache.flex.compiler.internal.codegen.js.jx; import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import org.apache.flex.compiler.codegen.ISubEmitter; import org.apache.flex.compiler.codegen.js.IJSEmitter; +import org.apache.flex.compiler.constants.IASKeywordConstants; import org.apache.flex.compiler.definitions.IDefinition; import org.apache.flex.compiler.definitions.IPackageDefinition; import org.apache.flex.compiler.definitions.ITypeDefinition; +import org.apache.flex.compiler.definitions.metadata.IMetaTagAttribute; import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens; import org.apache.flex.compiler.internal.codegen.js.JSEmitterTokens; import org.apache.flex.compiler.internal.codegen.js.JSSubEmitter; import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSDocEmitter; -import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter; import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitterTokens; import org.apache.flex.compiler.internal.codegen.js.utils.EmitterUtils; +import org.apache.flex.compiler.internal.tree.as.SetterNode; import org.apache.flex.compiler.scopes.IASScope; +import org.apache.flex.compiler.tree.ASTNodeID; import org.apache.flex.compiler.tree.as.IClassNode; +import org.apache.flex.compiler.tree.as.IDefinitionNode; import org.apache.flex.compiler.tree.as.IExpressionNode; +import org.apache.flex.compiler.tree.as.IFunctionNode; import org.apache.flex.compiler.tree.as.IInterfaceNode; import org.apache.flex.compiler.tree.as.ITypeNode; +import org.apache.flex.compiler.tree.as.IVariableNode; +import org.apache.flex.compiler.tree.metadata.IMetaTagNode; +import org.apache.flex.compiler.tree.metadata.IMetaTagsNode; public class PackageFooterEmitter extends JSSubEmitter implements ISubEmitter<IPackageDefinition> @@ -134,9 +144,455 @@ public class PackageFooterEmitter extends JSSubEmitter implements } write(ASEmitterTokens.SQUARE_CLOSE); } - write(ASEmitterTokens.SPACE); write(ASEmitterTokens.BLOCK_CLOSE); + write(ASEmitterTokens.SEMICOLON); + + collectReflectionData(tnode); + IMetaTagNode[] metadata = null; + IMetaTagsNode metadataTags = tnode.getMetaTags(); + if (metadataTags != null) + metadata = metadataTags.getAllTags(); + emitReflectionData(getEmitter().formatQualifiedName(tnode.getQualifiedName()), + varData, + accessorData, + methodData, + metadata); + } + + public class VariableData + { + public String name; + public String type; + public IMetaTagNode[] metaData; + } + + private ArrayList<VariableData> varData; + + public class MethodData + { + public String name; + public String type; + public String declaredBy; + public IMetaTagNode[] metaData; + } + + private ArrayList<MethodData> accessorData; + private ArrayList<MethodData> methodData; + + public void collectReflectionData(ITypeNode tnode) + { + varData = new ArrayList<VariableData>(); + accessorData = new ArrayList<MethodData>(); + methodData = new ArrayList<MethodData>(); + /* + * Reflection + * + * @return {Object.<string, Function>} + */ + IDefinitionNode[] dnodes; + boolean isInterface = tnode instanceof IInterfaceNode; + if (!isInterface) + dnodes = ((IClassNode) tnode).getAllMemberNodes(); + else + dnodes = ((IInterfaceNode) tnode).getAllMemberDefinitionNodes(); + + for (IDefinitionNode dnode : dnodes) + { + if (dnode.getNodeID() == ASTNodeID.VariableID || + dnode.getNodeID() == ASTNodeID.BindableVariableID) + { + IVariableNode varNode = (IVariableNode)dnode; + String ns = varNode.getNamespace(); + if (ns == IASKeywordConstants.PUBLIC || isInterface) + { + VariableData data = new VariableData(); + varData.add(data); + data.name = varNode.getName(); + data.type = getEmitter().formatQualifiedName(varNode.getVariableType()); + IMetaTagsNode metaData = varNode.getMetaTags(); + if (metaData != null) + { + IMetaTagNode[] tags = metaData.getAllTags(); + if (tags.length > 0) + data.metaData = tags; + } + } + } + } + + HashMap<String, MethodData> accessorMap = new HashMap<String, MethodData>(); + for (IDefinitionNode dnode : dnodes) + { + if (dnode.getNodeID() == ASTNodeID.GetterID || + dnode.getNodeID() == ASTNodeID.SetterID) + { + IFunctionNode fnNode = (IFunctionNode)dnode; + String ns = fnNode.getNamespace(); + if (ns == IASKeywordConstants.PUBLIC || isInterface) + { + MethodData data = new MethodData(); + data.name = fnNode.getName(); + if (accessorMap.containsKey(data.name)) continue; + accessorData.add(data); + if (dnode.getNodeID() == ASTNodeID.GetterID) + data.type = fnNode.getReturnType(); + else + data.type = ((SetterNode)fnNode).getVariableType(); + accessorMap.put(data.name, data); + data.type = getEmitter().formatQualifiedName(data.type); + IClassNode declarer = (IClassNode)fnNode.getAncestorOfType(IClassNode.class); + String declarant = getEmitter().formatQualifiedName(tnode.getQualifiedName()); + if (declarer != null) + declarant = getEmitter().formatQualifiedName(declarer.getQualifiedName()); + data.declaredBy = declarant; + IMetaTagsNode metaData = fnNode.getMetaTags(); + if (metaData != null) + { + IMetaTagNode[] tags = metaData.getAllTags(); + if (tags.length > 0) + data.metaData = tags; + } + } + } + } + for (IDefinitionNode dnode : dnodes) + { + if (dnode.getNodeID() == ASTNodeID.FunctionID) + { + IFunctionNode fnNode = (IFunctionNode)dnode; + String ns = fnNode.getNamespace(); + if (ns == IASKeywordConstants.PUBLIC || isInterface) + { + MethodData data = new MethodData(); + methodData.add(data); + data.name = fnNode.getName(); + data.type = getEmitter().formatQualifiedName(fnNode.getReturnType()); + ITypeNode declarer; + if (isInterface) + declarer = (IInterfaceNode)fnNode.getAncestorOfType(IInterfaceNode.class); + else + declarer = (IClassNode)fnNode.getAncestorOfType(IClassNode.class); + String declarant = getEmitter().formatQualifiedName(tnode.getQualifiedName()); + if (declarer != null) + declarant = getEmitter().formatQualifiedName(declarer.getQualifiedName()); + data.declaredBy = declarant; + IMetaTagsNode metaData = fnNode.getMetaTags(); + if (metaData != null) + { + IMetaTagNode[] tags = metaData.getAllTags(); + if (tags.length > 0) + data.metaData = tags; + } + } + } + } + } + + public void emitReflectionData(String typeName, + List<VariableData> varData, + List<MethodData> accessorData, + List<MethodData> methodData, + IMetaTagNode[] metaData + ) + { + JSFlexJSDocEmitter doc = (JSFlexJSDocEmitter) getEmitter() + .getDocEmitter(); + /* + * Reflection + * + * @return {Object.<string, Function>} + */ + + writeNewline(); + writeNewline(); + writeNewline(); + writeNewline(); + doc.begin(); + writeNewline(" * Reflection"); + writeNewline(" *"); + writeNewline(" * @return {Object.<string, Function>}"); + doc.end(); + + // a.B.prototype.FLEXJS_REFLECTION_INFO = function() { + write(typeName); + write(ASEmitterTokens.MEMBER_ACCESS); + write(JSEmitterTokens.PROTOTYPE); + write(ASEmitterTokens.MEMBER_ACCESS); + writeToken(JSFlexJSEmitterTokens.FLEXJS_REFLECTION_INFO); + writeToken(ASEmitterTokens.EQUAL); + writeToken(ASEmitterTokens.FUNCTION); + write(ASEmitterTokens.PAREN_OPEN); + writeToken(ASEmitterTokens.PAREN_CLOSE); + write(ASEmitterTokens.BLOCK_OPEN); + + indentPush(); + writeNewline(); + // return { + writeToken(ASEmitterTokens.RETURN); + write(ASEmitterTokens.BLOCK_OPEN); + indentPush(); + writeNewline(); + // variables: function() { + write("variables"); + writeToken(ASEmitterTokens.COLON); + writeToken(ASEmitterTokens.FUNCTION); + write(ASEmitterTokens.PAREN_OPEN); + writeToken(ASEmitterTokens.PAREN_CLOSE); + write(ASEmitterTokens.BLOCK_OPEN); + indentPush(); + writeNewline(); + // return { + writeToken(ASEmitterTokens.RETURN); + write(ASEmitterTokens.BLOCK_OPEN); + indentPush(); + + int count = 0; + for (VariableData var : varData) + { + if (count > 0) + write(ASEmitterTokens.COMMA); + writeNewline(); + count++; + // varname: { type: typename + write(ASEmitterTokens.SINGLE_QUOTE); + write(var.name); + write(ASEmitterTokens.SINGLE_QUOTE); + writeToken(ASEmitterTokens.COLON); + writeToken(ASEmitterTokens.BLOCK_OPEN); + write("type"); + writeToken(ASEmitterTokens.COLON); + write(ASEmitterTokens.SINGLE_QUOTE); + write(var.type); + write(ASEmitterTokens.SINGLE_QUOTE); + IMetaTagNode[] tags = var.metaData; + if (tags != null) + { + writeToken(ASEmitterTokens.COMMA); + writeMetaData(tags); + } + // close object + write(ASEmitterTokens.BLOCK_CLOSE); + } + indentPop(); + writeNewline(); + write(ASEmitterTokens.BLOCK_CLOSE); + write(ASEmitterTokens.SEMICOLON); + indentPop(); + writeNewline(); + // close variable function + write(ASEmitterTokens.BLOCK_CLOSE); + write(ASEmitterTokens.COMMA); + writeNewline(); + + + // accessors: function() { + write("accessors"); + writeToken(ASEmitterTokens.COLON); + writeToken(ASEmitterTokens.FUNCTION); + write(ASEmitterTokens.PAREN_OPEN); + writeToken(ASEmitterTokens.PAREN_CLOSE); + write(ASEmitterTokens.BLOCK_OPEN); + indentPush(); + writeNewline(); + // return { + writeToken(ASEmitterTokens.RETURN); + write(ASEmitterTokens.BLOCK_OPEN); + indentPush(); + + count = 0; + for (MethodData accessor : accessorData) + { + if (count > 0) + write(ASEmitterTokens.COMMA); + writeNewline(); + count++; + // accessorname: { type: typename + write(ASEmitterTokens.SINGLE_QUOTE); + write(accessor.name); + write(ASEmitterTokens.SINGLE_QUOTE); + writeToken(ASEmitterTokens.COLON); + writeToken(ASEmitterTokens.BLOCK_OPEN); + write("type"); + writeToken(ASEmitterTokens.COLON); + write(ASEmitterTokens.SINGLE_QUOTE); + write(accessor.type); + write(ASEmitterTokens.SINGLE_QUOTE); + writeToken(ASEmitterTokens.COMMA); + write("declaredBy"); + writeToken(ASEmitterTokens.COLON); + write(ASEmitterTokens.SINGLE_QUOTE); + write(accessor.declaredBy); + write(ASEmitterTokens.SINGLE_QUOTE); + IMetaTagNode[] tags = accessor.metaData; + if (tags != null) + { + writeToken(ASEmitterTokens.COMMA); + writeMetaData(tags); + } + // close object + write(ASEmitterTokens.BLOCK_CLOSE); + } + indentPop(); + writeNewline(); + write(ASEmitterTokens.BLOCK_CLOSE); + write(ASEmitterTokens.SEMICOLON); + indentPop(); + writeNewline(); + // close accessor function + write(ASEmitterTokens.BLOCK_CLOSE); + write(ASEmitterTokens.COMMA); + writeNewline(); + + + // methods: function() { + write("methods"); + writeToken(ASEmitterTokens.COLON); + writeToken(ASEmitterTokens.FUNCTION); + write(ASEmitterTokens.PAREN_OPEN); + writeToken(ASEmitterTokens.PAREN_CLOSE); + write(ASEmitterTokens.BLOCK_OPEN); + indentPush(); + writeNewline(); + // return { + writeToken(ASEmitterTokens.RETURN); + write(ASEmitterTokens.BLOCK_OPEN); + indentPush(); + + count = 0; + for (MethodData method : methodData) + { + if (count > 0) + write(ASEmitterTokens.COMMA); + writeNewline(); + count++; + // methodname: { type: typename + write(ASEmitterTokens.SINGLE_QUOTE); + write(method.name); + write(ASEmitterTokens.SINGLE_QUOTE); + writeToken(ASEmitterTokens.COLON); + writeToken(ASEmitterTokens.BLOCK_OPEN); + write("type"); + writeToken(ASEmitterTokens.COLON); + write(ASEmitterTokens.SINGLE_QUOTE); + write(method.type); + write(ASEmitterTokens.SINGLE_QUOTE); + writeToken(ASEmitterTokens.COMMA); + write("declaredBy"); + writeToken(ASEmitterTokens.COLON); + ITypeNode declarer; + write(ASEmitterTokens.SINGLE_QUOTE); + write(method.declaredBy); + write(ASEmitterTokens.SINGLE_QUOTE); + IMetaTagNode[] tags = method.metaData; + if (tags != null) + { + writeToken(ASEmitterTokens.COMMA); + writeMetaData(tags); + } + // close object + write(ASEmitterTokens.BLOCK_CLOSE); + } + // close return + indentPop(); + writeNewline(); + write(ASEmitterTokens.BLOCK_CLOSE); + write(ASEmitterTokens.SEMICOLON); + indentPop(); + writeNewline(); + // close method function + write(ASEmitterTokens.BLOCK_CLOSE); + + if (metaData != null && metaData.length > 0) + { + write(ASEmitterTokens.COMMA); + writeNewline(); + writeMetaData(metaData); + } + + indentPop(); + writeNewline(); + // close return object + write(ASEmitterTokens.BLOCK_CLOSE); + write(ASEmitterTokens.SEMICOLON); + + // close function + indentPop(); + writeNewline(); + write(ASEmitterTokens.BLOCK_CLOSE); writeNewline(ASEmitterTokens.SEMICOLON); } + + private void writeMetaData(IMetaTagNode[] tags) + { + // metadata: function() { + write("metadata"); + writeToken(ASEmitterTokens.COLON); + writeToken(ASEmitterTokens.FUNCTION); + write(ASEmitterTokens.PAREN_OPEN); + writeToken(ASEmitterTokens.PAREN_CLOSE); + writeToken(ASEmitterTokens.BLOCK_OPEN); + // return [ array of metadata tags ] + writeToken(ASEmitterTokens.RETURN); + writeToken(ASEmitterTokens.SQUARE_OPEN); + + for (int i = 0; i < tags.length; i++) + { + IMetaTagNode tag = tags[i]; + if (i > 0) + { + writeToken(ASEmitterTokens.COMMA); + } + // { name: <tag name> + writeToken(ASEmitterTokens.BLOCK_OPEN); + write("name"); + writeToken(ASEmitterTokens.COLON); + write(ASEmitterTokens.SINGLE_QUOTE); + write(tag.getTagName()); + write(ASEmitterTokens.SINGLE_QUOTE); + IMetaTagAttribute[] args = tag.getAllAttributes(); + if (args.length > 0) + { + writeToken(ASEmitterTokens.COMMA); + + // args: [ + write("args"); + writeToken(ASEmitterTokens.COLON); + writeToken(ASEmitterTokens.SQUARE_OPEN); + + for (int j = 0; j < args.length; j++) + { + if (j > 0) + { + writeToken(ASEmitterTokens.COMMA); + } + // { key: key, value: value } + IMetaTagAttribute arg = args[j]; + writeToken(ASEmitterTokens.BLOCK_OPEN); + write("key"); + writeToken(ASEmitterTokens.COLON); + write(ASEmitterTokens.SINGLE_QUOTE); + String key = arg.getKey(); + write(key == null ? "" : key); + write(ASEmitterTokens.SINGLE_QUOTE); + writeToken(ASEmitterTokens.COMMA); + write("value"); + writeToken(ASEmitterTokens.COLON); + write(ASEmitterTokens.SINGLE_QUOTE); + write(arg.getValue()); + write(ASEmitterTokens.SINGLE_QUOTE); + write(ASEmitterTokens.BLOCK_CLOSE); + } + // close array of args + write(ASEmitterTokens.SQUARE_CLOSE); + } + // close metadata object + write(ASEmitterTokens.BLOCK_CLOSE); + } + // close array of metadatas + write(ASEmitterTokens.SQUARE_CLOSE); + writeToken(ASEmitterTokens.SEMICOLON); + // close function + write(ASEmitterTokens.BLOCK_CLOSE); + } } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e1c69a7d/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java index bda108d..171be76 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java @@ -46,6 +46,8 @@ public class VarDeclarationEmitter extends JSSubEmitter implements // TODO (mschmalle) will remove this cast as more things get abstracted JSFlexJSEmitter fjs = (JSFlexJSEmitter) getEmitter(); + getModel().getVars().add(node); + if (!(node instanceof ChainedVariableNode) && !node.isConst()) { fjs.emitMemberKeyword(node); http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e1c69a7d/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java ---------------------------------------------------------------------- diff --git a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java index dd18a90..5cd1111 100644 --- a/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java +++ b/compiler.jx/src/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java @@ -35,6 +35,7 @@ import org.apache.flex.abc.semantics.Name; import org.apache.flex.abc.semantics.Namespace; import org.apache.flex.compiler.codegen.as.IASEmitter; import org.apache.flex.compiler.codegen.mxml.flexjs.IMXMLFlexJSEmitter; +import org.apache.flex.compiler.constants.IASKeywordConstants; import org.apache.flex.compiler.definitions.IClassDefinition; import org.apache.flex.compiler.definitions.IDefinition; import org.apache.flex.compiler.internal.codegen.as.ASEmitterTokens; @@ -46,9 +47,12 @@ import org.apache.flex.compiler.internal.codegen.databinding.StaticPropertyWatch import org.apache.flex.compiler.internal.codegen.databinding.WatcherInfoBase; import org.apache.flex.compiler.internal.codegen.databinding.WatcherInfoBase.WatcherType; import org.apache.flex.compiler.internal.codegen.databinding.XMLWatcherInfo; +import org.apache.flex.compiler.internal.codegen.js.JSSessionModel.PropertyNodes; import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter; import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitterTokens; import org.apache.flex.compiler.internal.codegen.js.goog.JSGoogEmitterTokens; +import org.apache.flex.compiler.internal.codegen.js.jx.PackageFooterEmitter; +import org.apache.flex.compiler.internal.codegen.js.jx.PackageFooterEmitter.VariableData; import org.apache.flex.compiler.internal.codegen.js.utils.EmitterUtils; import org.apache.flex.compiler.internal.codegen.mxml.MXMLEmitter; import org.apache.flex.compiler.internal.projects.FlexJSProject; @@ -57,12 +61,17 @@ import org.apache.flex.compiler.internal.scopes.ASProjectScope; import org.apache.flex.compiler.internal.tree.as.FunctionCallNode; import org.apache.flex.compiler.internal.tree.as.IdentifierNode; import org.apache.flex.compiler.internal.tree.as.MemberAccessExpressionNode; +import org.apache.flex.compiler.internal.tree.mxml.MXMLDocumentNode; import org.apache.flex.compiler.projects.ICompilerProject; import org.apache.flex.compiler.tree.ASTNodeID; import org.apache.flex.compiler.tree.as.IASNode; +import org.apache.flex.compiler.tree.as.IClassNode; import org.apache.flex.compiler.tree.as.IExpressionNode; +import org.apache.flex.compiler.tree.as.IFunctionNode; import org.apache.flex.compiler.tree.as.IImportNode; import org.apache.flex.compiler.tree.as.IVariableNode; +import org.apache.flex.compiler.tree.metadata.IMetaTagNode; +import org.apache.flex.compiler.tree.metadata.IMetaTagsNode; import org.apache.flex.compiler.tree.mxml.IMXMLArrayNode; import org.apache.flex.compiler.tree.mxml.IMXMLClassDefinitionNode; import org.apache.flex.compiler.tree.mxml.IMXMLClassNode; @@ -74,6 +83,7 @@ import org.apache.flex.compiler.tree.mxml.IMXMLEventSpecifierNode; import org.apache.flex.compiler.tree.mxml.IMXMLFactoryNode; import org.apache.flex.compiler.tree.mxml.IMXMLInstanceNode; import org.apache.flex.compiler.tree.mxml.IMXMLLiteralNode; +import org.apache.flex.compiler.tree.mxml.IMXMLMetadataNode; import org.apache.flex.compiler.tree.mxml.IMXMLNode; import org.apache.flex.compiler.tree.mxml.IMXMLObjectNode; import org.apache.flex.compiler.tree.mxml.IMXMLPropertySpecifierNode; @@ -110,6 +120,7 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements //private ArrayList<MXMLStyleSpecifier> styles; private IClassDefinition classDefinition; private ArrayList<String> usedNames = new ArrayList<String>(); + private ArrayList<IMXMLMetadataNode> metadataNodes = new ArrayList<IMXMLMetadataNode>(); private int eventCounter; private int idCounter; @@ -361,6 +372,12 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements } + @Override + public void emitMetadata(IMXMLMetadataNode node) + { + metadataNodes.add(node); + } + //-------------------------------------------------------------------------- protected void emitClassDeclStart(String cname, String baseClassName, @@ -479,9 +496,125 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements write(cdef.getBaseName()); write("', qName: '"); write(formatQualifiedName(cname)); - writeNewline("' }] };"); + write("' }] };"); + + emitReflectionData(cdef); writeNewline(); writeNewline(); + + } + + private void emitReflectionData(IClassDefinition cdef) + { + JSFlexJSEmitter asEmitter = (JSFlexJSEmitter)((IMXMLBlockWalker) getMXMLWalker()).getASEmitter(); + + ArrayList<PackageFooterEmitter.VariableData> varData = new ArrayList<PackageFooterEmitter.VariableData>(); + // vars can only come from script blocks? + List<IVariableNode> vars = asEmitter.getModel().getVars(); + for (IVariableNode varNode : vars) + { + String ns = varNode.getNamespace(); + if (ns == IASKeywordConstants.PUBLIC) + { + PackageFooterEmitter.VariableData data = asEmitter.packageFooterEmitter.new VariableData(); + varData.add(data); + data.name = varNode.getName(); + data.type = formatQualifiedName(varNode.getVariableType()); + IMetaTagsNode metaData = varNode.getMetaTags(); + if (metaData != null) + { + IMetaTagNode[] tags = metaData.getAllTags(); + if (tags.length > 0) + data.metaData = tags; + } + } + } + + ArrayList<PackageFooterEmitter.MethodData> accessorData = new ArrayList<PackageFooterEmitter.MethodData>(); + HashMap<String, PropertyNodes> accessors = asEmitter.getModel().getPropertyMap(); + for (String propName : accessors.keySet()) + { + PropertyNodes p = accessors.get(propName); + IFunctionNode accessorNode = p.getter; + if (accessorNode == null) + accessorNode = p.setter; + String ns = accessorNode.getNamespace(); + if (ns == IASKeywordConstants.PUBLIC) + { + PackageFooterEmitter.MethodData data = asEmitter.packageFooterEmitter.new MethodData(); + accessorData.add(data); + data.name = accessorNode.getName(); + if (p.getter != null) + data.type = formatQualifiedName(p.getter.getReturnType()); + else + data.type = formatQualifiedName(p.setter.getVariableType()); + data.declaredBy = formatQualifiedName(cdef.getQualifiedName()); + IMetaTagsNode metaData = accessorNode.getMetaTags(); + if (metaData != null) + { + IMetaTagNode[] tags = metaData.getAllTags(); + if (tags.length > 0) + data.metaData = tags; + } + } + } + + for (MXMLDescriptorSpecifier instance : instances) + { + if (!instance.id.startsWith(MXMLFlexJSEmitterTokens.ID_PREFIX + .getToken())) + { + PackageFooterEmitter.MethodData data = asEmitter.packageFooterEmitter.new MethodData(); + accessorData.add(data); + data.name = instance.id; + data.type = formatQualifiedName(instance.name); + data.declaredBy = formatQualifiedName(cdef.getQualifiedName()); + } + } + + ArrayList<PackageFooterEmitter.MethodData> methodData = new ArrayList<PackageFooterEmitter.MethodData>(); + List<IFunctionNode> methods = asEmitter.getModel().getMethods(); + for (IFunctionNode methodNode : methods) + { + String ns = methodNode.getNamespace(); + if (ns == IASKeywordConstants.PUBLIC) + { + PackageFooterEmitter.MethodData data = asEmitter.packageFooterEmitter.new MethodData(); + accessorData.add(data); + data.name = methodNode.getName(); + data.type = formatQualifiedName(methodNode.getReturnType()); + data.declaredBy = formatQualifiedName(cdef.getQualifiedName()); + IMetaTagsNode metaData = methodNode.getMetaTags(); + if (metaData != null) + { + IMetaTagNode[] tags = metaData.getAllTags(); + if (tags.length > 0) + data.metaData = tags; + } + } + } + + for (MXMLEventSpecifier event : events) + { + PackageFooterEmitter.MethodData data = asEmitter.packageFooterEmitter.new MethodData(); + methodData.add(data); + data.name = event.eventHandler; + data.type = ASEmitterTokens.VOID.getToken(); + data.declaredBy = formatQualifiedName(cdef.getQualifiedName()); + } + + ArrayList<IMetaTagNode> metadataTagNodes = new ArrayList<IMetaTagNode>(); + for (IMXMLMetadataNode metadataTag : metadataNodes) + { + IMetaTagNode[] tags = metadataTag.getMetaTagNodes(); + for (IMetaTagNode tag : tags) + { + metadataTagNodes.add(tag); + } + } + IMetaTagNode[] metaDataTags = new IMetaTagNode[metadataTagNodes.size()]; + asEmitter.packageFooterEmitter.emitReflectionData(formatQualifiedName(cdef.getQualifiedName()), varData, + accessorData, methodData, metadataTagNodes.toArray(metaDataTags)); } //--------------------------------------------------------------------------
