Repository: flex-falcon Updated Branches: refs/heads/feature-autobuild/maven-archetypes 506025f4d -> 1c96ccd6a
add keep-code-with-metadata option to generate exportSymbol and exportProperty calls that prevent methods with metadata from being removed by the GCC dead code removal Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/f84ae9ae Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/f84ae9ae Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/f84ae9ae Branch: refs/heads/feature-autobuild/maven-archetypes Commit: f84ae9ae271215bb78f0ac102fdd6492d082b46a Parents: 506025f Author: Alex Harui <[email protected]> Authored: Mon Oct 3 22:34:18 2016 -0700 Committer: Alex Harui <[email protected]> Committed: Mon Oct 3 22:34:18 2016 -0700 ---------------------------------------------------------------------- .../js/flexjs/JSFlexJSEmitterTokens.java | 1 + .../codegen/js/jx/PackageFooterEmitter.java | 102 ++++++++++++++++++- .../codegen/mxml/flexjs/MXMLFlexJSEmitter.java | 50 +++++++++ .../driver/js/goog/JSGoogConfiguration.java | 25 +++++ .../codegen/js/flexjs/TestFlexJSPackage.java | 70 +++++++++++++ 5 files changed, 245 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f84ae9ae/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitterTokens.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitterTokens.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitterTokens.java index 7c62278..4431407 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitterTokens.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/flexjs/JSFlexJSEmitterTokens.java @@ -31,6 +31,7 @@ public enum JSFlexJSEmitterTokens implements IEmitterTokens FLEXJS_CLASS_INFO_KIND("kind"), FLEXJS_CLASS_INFO_CLASS_KIND("class"), FLEXJS_CLASS_INFO_INTERFACE_KIND("interface"), + GOOG_EXPORT_PROPERTY("goog.exportProperty"), GOOG_EXPORT_SYMBOL("goog.exportSymbol"), INDENT(" "), INTERFACES("interfaces"), http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f84ae9ae/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java index 7509699..feaceb0 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/PackageFooterEmitter.java @@ -209,6 +209,8 @@ public class PackageFooterEmitter extends JSSubEmitter implements accessorData, methodData, metadata); + + emitExportProperties(typeName, exportProperties, exportSymbols); } public enum ReflectionKind{ @@ -243,11 +245,22 @@ public class PackageFooterEmitter extends JSSubEmitter implements private ArrayList<AccessorData> accessorData; private ArrayList<MethodData> methodData; private ReflectionKind reflectionKind; + private ArrayList<String> exportProperties; + private ArrayList<String> exportSymbols; public void collectReflectionData(ITypeNode tnode) { JSFlexJSEmitter fjs = (JSFlexJSEmitter)getEmitter(); - + exportProperties = new ArrayList<String>(); + exportSymbols = new ArrayList<String>(); + ICompilerProject project = getWalker().getProject(); + Set<String> exportMetadata = Collections.<String> emptySet(); + if (project instanceof FlexJSProject) + { + FlexJSProject fjsp = ((FlexJSProject)project); + if (fjsp.config != null) + exportMetadata = fjsp.config.getCompilerKeepCodeWithMetadata(); + } varData = new ArrayList<VariableData>(); accessorData = new ArrayList<AccessorData>(); methodData = new ArrayList<MethodData>(); @@ -260,7 +273,6 @@ public class PackageFooterEmitter extends JSSubEmitter implements String name; //bindables: HashMap<String, BindableVarInfo> bindableVars = getModel().getBindableVars(); - ICompilerProject project = getWalker().getProject(); boolean isInterface = tnode instanceof IInterfaceNode; if (!isInterface) dnodes = ((IClassNode) tnode).getAllMemberNodes(); @@ -322,7 +334,20 @@ public class PackageFooterEmitter extends JSSubEmitter implements { IMetaTagNode[] tags = metaData.getAllTags(); if (tags.length > 0) + { data.metaData = tags; + for (IMetaTagNode tag : tags) + { + String tagName = tag.getTagName(); + if (exportMetadata.contains(tagName)) + { + if (data.isStatic) + exportSymbols.add(data.name); + else + exportProperties.add(data.name); + } + } + } } } } @@ -386,7 +411,22 @@ public class PackageFooterEmitter extends JSSubEmitter implements { IMetaTagNode[] tags = metaData.getAllTags(); if (tags.length > 0) - data.metaData = tags; + { + data.metaData = tags; + /* accessors don't need exportProp since they are referenced via the defineProp data structure + for (IMetaTagNode tag : tags) + { + String tagName = tag.getTagName(); + if (exportMetadata.contains(tagName)) + { + if (data.isStatic) + exportSymbols.add(data.name); + else + exportProperties.add(data.name); + } + } + */ + } } } } @@ -425,7 +465,20 @@ public class PackageFooterEmitter extends JSSubEmitter implements { IMetaTagNode[] tags = metaData.getAllTags(); if (tags.length > 0) + { data.metaData = tags; + for (IMetaTagNode tag : tags) + { + String tagName = tag.getTagName(); + if (exportMetadata.contains(tagName)) + { + if (data.isStatic) + exportSymbols.add(data.name); + else + exportProperties.add(data.name); + } + } + } } IParameterNode[] paramNodes = fnNode.getParameterNodes(); if (paramNodes != null) { @@ -908,4 +961,47 @@ public class PackageFooterEmitter extends JSSubEmitter implements value = value.replace("'","\\'"); return value; } + + public void emitExportProperties(String typeName, ArrayList<String> exportProperties, ArrayList<String> exportSymbols) + { + for (String prop : exportSymbols) + { + write(JSFlexJSEmitterTokens.GOOG_EXPORT_SYMBOL); + write(ASEmitterTokens.PAREN_OPEN); + write(ASEmitterTokens.SINGLE_QUOTE); + write(typeName); + write(ASEmitterTokens.MEMBER_ACCESS); + write(prop); + write(ASEmitterTokens.SINGLE_QUOTE); + write(ASEmitterTokens.COMMA); + write(ASEmitterTokens.SPACE); + write(typeName); + write(ASEmitterTokens.MEMBER_ACCESS); + write(prop); + write(ASEmitterTokens.PAREN_CLOSE); + writeNewline(ASEmitterTokens.SEMICOLON); + } + for (String prop : exportProperties) + { + write(JSFlexJSEmitterTokens.GOOG_EXPORT_PROPERTY); + write(ASEmitterTokens.PAREN_OPEN); + write(typeName); + write(ASEmitterTokens.MEMBER_ACCESS); + write(JSEmitterTokens.PROTOTYPE); + write(ASEmitterTokens.COMMA); + write(ASEmitterTokens.SPACE); + write(ASEmitterTokens.SINGLE_QUOTE); + write(prop); + write(ASEmitterTokens.SINGLE_QUOTE); + write(ASEmitterTokens.COMMA); + write(ASEmitterTokens.SPACE); + write(typeName); + write(ASEmitterTokens.MEMBER_ACCESS); + write(JSEmitterTokens.PROTOTYPE); + write(ASEmitterTokens.MEMBER_ACCESS); + write(prop); + write(ASEmitterTokens.PAREN_CLOSE); + writeNewline(ASEmitterTokens.SEMICOLON); + } + } } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f84ae9ae/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java index dd02e85..f42692f 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/mxml/flexjs/MXMLFlexJSEmitter.java @@ -665,6 +665,11 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements { JSFlexJSEmitter asEmitter = (JSFlexJSEmitter)((IMXMLBlockWalker) getMXMLWalker()).getASEmitter(); FlexJSProject fjs = (FlexJSProject) getMXMLWalker().getProject(); + ArrayList<String> exportProperties = new ArrayList<String>(); + ArrayList<String> exportSymbols = new ArrayList<String>(); + Set<String> exportMetadata = Collections.<String> emptySet(); + if (fjs.config != null) + exportMetadata = fjs.config.getCompilerKeepCodeWithMetadata(); ArrayList<PackageFooterEmitter.VariableData> varData = new ArrayList<PackageFooterEmitter.VariableData>(); // vars can only come from script blocks? List<IVariableNode> vars = asEmitter.getModel().getVars(); @@ -684,7 +689,20 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements { IMetaTagNode[] tags = metaData.getAllTags(); if (tags.length > 0) + { data.metaData = tags; + for (IMetaTagNode tag : tags) + { + String tagName = tag.getTagName(); + if (exportMetadata.contains(tagName)) + { + if (data.isStatic) + exportSymbols.add(data.name); + else + exportProperties.add(data.name); + } + } + } } } } @@ -725,7 +743,22 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements { IMetaTagNode[] tags = metaData.getAllTags(); if (tags.length > 0) + { data.metaData = tags; + for (IMetaTagNode tag : tags) + { + String tagName = tag.getTagName(); + /* accessors don't need exportProp since they are referenced via the defineProp data structure + if (exportMetadata.contains(tagName)) + { + if (data.isStatic) + exportSymbols.add(data.name); + else + exportProperties.add(data.name); + } + */ + } + } } } } @@ -797,7 +830,20 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements { IMetaTagNode[] tags = metaData.getAllTags(); if (tags.length > 0) + { data.metaData = tags; + for (IMetaTagNode tag : tags) + { + String tagName = tag.getTagName(); + if (exportMetadata.contains(tagName)) + { + if (data.isStatic) + exportSymbols.add(data.name); + else + exportProperties.add(data.name); + } + } + } } } } @@ -839,6 +885,10 @@ public class MXMLFlexJSEmitter extends MXMLEmitter implements accessorData, methodData, metadataTagNodes.toArray(metaDataTags)); + asEmitter.packageFooterEmitter.emitExportProperties( + formatQualifiedName(cdef.getQualifiedName()), + exportProperties, + exportSymbols); } //-------------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f84ae9ae/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/JSGoogConfiguration.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/JSGoogConfiguration.java b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/JSGoogConfiguration.java index 40bdcfc..0c6df76 100644 --- a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/JSGoogConfiguration.java +++ b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/driver/js/goog/JSGoogConfiguration.java @@ -23,7 +23,10 @@ import java.io.File; import java.io.IOException; import java.net.URLDecoder; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.apache.flex.compiler.clients.JSConfiguration; import org.apache.flex.compiler.clients.MXMLJSC; @@ -373,5 +376,27 @@ public class JSGoogConfiguration extends JSConfiguration this.htmlOutputFileName = filename; } + // + // 'compiler.keep-code-with-metadata' option + // + + private Set<String> keepCodeWithMetadata = null; + + public Set<String> getCompilerKeepCodeWithMetadata() + { + return keepCodeWithMetadata == null ? Collections.<String> emptySet() : keepCodeWithMetadata; + } + + @Config(advanced = true, allowMultiple = true) + @Mapping({ "compiler", "keep-code-with-metadata" }) + @Arguments("name") + @InfiniteArguments + public void setCompilerKeepCodeWithMetadata(ConfigurationValue cv, List<String> values) + { + if (keepCodeWithMetadata == null) + keepCodeWithMetadata = new HashSet<String>(); + keepCodeWithMetadata.addAll(values); + } + } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/f84ae9ae/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSPackage.java ---------------------------------------------------------------------- diff --git a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSPackage.java b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSPackage.java index e1b8cad..7230646 100644 --- a/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSPackage.java +++ b/compiler-jx/src/test/java/org/apache/flex/compiler/internal/codegen/js/flexjs/TestFlexJSPackage.java @@ -41,7 +41,11 @@ public class TestFlexJSPackage extends TestGoogPackage 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(); } @@ -343,6 +347,72 @@ public class TestFlexJSPackage extends TestGoogPackage } @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" +
