Thanks Harbs for the explanation, now is more clear to me :)
2018-06-27 22:30 GMT+02:00 Harbs <[email protected]>:
> We’ve discussed this in the past.
>
> Basically:
> Before this option, all Object literals and Object access were being
> renamed by the Google Closure compiler. This caused untyped object
> references to be very fragile and tend to break when the code is minimized.
>
> This option changes all unknown references to quoted references. This
> means object literals will have property names quoted (i.e.
> {“name”:”Harbs”} instead of {name:”Harbs”} and foo[“name”] instead of
> foo.name. This is the recommended practice by Google when renaming
> properties might have unwanted consequences.
> https://developers.google.com/closure/compiler/docs/api-tutorial3 <
> https://developers.google.com/closure/compiler/docs/api-tutorial3>
>
> The downside of this change is that Objects might be minimized less than
> without this option. But it’s much safer. Another downside is that it
> encourages users to use Object.
>
> I spent many hours quoting object literals due to minimizing bugs. I
> expect this to be a pain point for lots of others too.
>
> Harbs
>
> > On Jun 27, 2018, at 10:57 PM, Carlos Rovira <[email protected]>
> wrote:
> >
> > Hi
> >
> > sorry, but I'd like to know more about this. I'm curious, what does this
> > change?
> > thanks! :)
> >
> > 2018-06-27 15:55 GMT+02:00 Harbs <[email protected]>:
> >
> >> Thanks for this Josh!
> >>
> >> I just tested this on a very complex library project with crazy complex
> >> untyped data structures. It works great!
> >>
> >> I wish we had this option when I was working on my app. I spent many
> hours
> >> chasing down minification issues that could have been fixed by this
> option.
> >>
> >> I also think it should default to true.
> >>
> >> Thanks,
> >> Harbs
> >>
> >>> On Jun 26, 2018, at 9:56 PM, [email protected] wrote:
> >>>
> >>> This is an automated email from the ASF dual-hosted git repository.
> >>>
> >>> joshtynjala pushed a commit to branch develop
> >>> in repository https://gitbox.apache.org/repos/asf/royale-compiler.git
> >>>
> >>>
> >>> The following commit(s) were added to refs/heads/develop by this push:
> >>> new 48d86c8 compiler-jx: added js-dynamic-access-unknown-members
> >> compiler option to have emitter use dynamic bracket access when the
> right
> >> side of a member access expression cannot be resolved to a definition.
> >>> 48d86c8 is described below
> >>>
> >>> commit 48d86c8c4b235ce60b282ad16d62d4ff87c3746b
> >>> Author: Josh Tynjala <[email protected]>
> >>> AuthorDate: Tue Jun 26 11:55:56 2018 -0700
> >>>
> >>> compiler-jx: added js-dynamic-access-unknown-members compiler option
> >> to have emitter use dynamic bracket access when the right side of a
> member
> >> access expression cannot be resolved to a definition.
> >>>
> >>> In other words, myObj.dynamicMember will become
> >> myObj['dynamicMember']. Known members will use the regular dot syntax.
> >> Useful for stopping the Closure compiler from renaming members that are
> >> dynamic, such as members of an object literal. Defaults to false to
> avoid
> >> breaking anything. However, I think it makes sense to have it default to
> >> true instead to give developers a better user experience.
> >>> ---
> >>> .../royale/compiler/clients/JSConfiguration.java | 26 ++++++++
> >>> .../codegen/js/jx/MemberAccessEmitter.java | 47 +++++++++++---
> >>> .../js/royale/TestDynamicAccessUnknownMembers.java | 71
> >> ++++++++++++++++++++++
> >>> 3 files changed, 137 insertions(+), 7 deletions(-)
> >>>
> >>> diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/
> clients/JSConfiguration.java
> >> b/compiler-jx/src/main/java/org/apache/royale/compiler/
> >> clients/JSConfiguration.java
> >>> index 0e6caf5..5433608 100644
> >>> --- a/compiler-jx/src/main/java/org/apache/royale/compiler/
> >> clients/JSConfiguration.java
> >>> +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/
> >> clients/JSConfiguration.java
> >>> @@ -137,6 +137,32 @@ public class JSConfiguration extends Configuration
> >>> }
> >>>
> >>> //
> >>> + // 'js-dynamic-access-unknown-members'
> >>> + //
> >>> +
> >>> + private boolean jsDynamicAccessUnknownMembers = false;
> >>> +
> >>> + public boolean getJsDynamicAccessUnknownMembers()
> >>> + {
> >>> + return jsDynamicAccessUnknownMembers;
> >>> + }
> >>> +
> >>> + /**
> >>> + * If the definition of a member cannot be resolved, emit dynamic
> >> access
> >>> + * instead of normal member access. Ensures that dynamic members
> >> aren't
> >>> + * renamed.
> >>> + *
> >>> + * <code>myObject.memberAccess</code> becomes
> >> <code>myObject["memberAccess"]</code>
> >>> + */
> >>> + @Config
> >>> + @Mapping("js-dynamic-access-unknown-members")
> >>> + public void setJsDynamicAccessUnknownMembers(ConfigurationValue
> >> cv, boolean value)
> >>> + throws ConfigurationException
> >>> + {
> >>> + jsDynamicAccessUnknownMembers = value;
> >>> + }
> >>> +
> >>> + //
> >>> // 'compiler.js-external-library-path' option
> >>> //
> >>>
> >>> diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/
> >> internal/codegen/js/jx/MemberAccessEmitter.java
> >> b/compiler-jx/src/main/java/org/apache/royale/compiler/
> >> internal/codegen/js/jx/MemberAccessEmitter.java
> >>> index d308d34..b7a577c 100644
> >>> --- a/compiler-jx/src/main/java/org/apache/royale/compiler/
> >> internal/codegen/js/jx/MemberAccessEmitter.java
> >>> +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/
> >> internal/codegen/js/jx/MemberAccessEmitter.java
> >>> @@ -32,12 +32,14 @@ import org.apache.royale.compiler.
> >> internal.codegen.js.goog.JSGoogEmitterTokens;
> >>> import org.apache.royale.compiler.internal.codegen.js.jx.
> >> BinaryOperatorEmitter.DatePropertiesGetters;
> >>> import org.apache.royale.compiler.internal.definitions.
> >> AccessorDefinition;
> >>> import org.apache.royale.compiler.internal.definitions.
> >> FunctionDefinition;
> >>> +import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
> >>> import org.apache.royale.compiler.internal.tree.as.DynamicAccessNode;
> >>> import org.apache.royale.compiler.internal.tree.as.FunctionCallNode;
> >>> import org.apache.royale.compiler.internal.tree.as.GetterNode;
> >>> import org.apache.royale.compiler.internal.tree.as.IdentifierNode;
> >>> import org.apache.royale.compiler.internal.tree.as.
> >> MemberAccessExpressionNode;
> >>> import org.apache.royale.compiler.internal.tree.as.
> >> NamespaceAccessExpressionNode;
> >>> +import org.apache.royale.compiler.projects.ICompilerProject;
> >>> import org.apache.royale.compiler.tree.ASTNodeID;
> >>> import org.apache.royale.compiler.tree.as.IASNode;
> >>> import org.apache.royale.compiler.tree.as.IExpressionNode;
> >>> @@ -255,17 +257,48 @@ public class MemberAccessEmitter extends
> >> JSSubEmitter implements
> >>> getEmitter().emitClosureStart();
> >>>
> >>> continueWalk = writeLeftSide(node, leftNode, rightNode);
> >>> - if (continueWalk && !isCustomNamespace)
> >>> - {
> >>> - startMapping(node, node.getLeftOperandNode());
> >>> - write(node.getOperator().getOperatorText());
> >>> - endMapping(node);
> >>> - }
> >>> }
> >>>
> >>> if (continueWalk)
> >>> {
> >>> - getWalker().walk(node.getRightOperandNode());
> >>> + boolean emitDynamicAccess = false;
> >>> + boolean dynamicAccessUnknownMembers = false;
> >>> + ICompilerProject project = getProject();
> >>> + if(project instanceof RoyaleJSProject)
> >>> + {
> >>> + RoyaleJSProject fjsProject = (RoyaleJSProject)
> project;
> >>> + if(fjsProject.config != null)
> >>> + {
> >>> + dynamicAccessUnknownMembers = fjsProject.config.
> >> getJsDynamicAccessUnknownMembers();
> >>> + }
> >>> + }
> >>> + if (dynamicAccessUnknownMembers && rightNode
> >> instanceof IIdentifierNode)
> >>> + {
> >>> + IIdentifierNode identifierNode =
> >> (IIdentifierNode) node.getRightOperandNode();
> >>> + IDefinition resolvedDefinition =
> >> identifierNode.resolve(getProject());
> >>> + emitDynamicAccess = resolvedDefinition ==
> >> null;
> >>> + }
> >>> + if (emitDynamicAccess)
> >>> + {
> >>> + IIdentifierNode identifierNode =
> >> (IIdentifierNode) node.getRightOperandNode();
> >>> + startMapping(node, rightNode);
> >>> + write(ASEmitterTokens.SQUARE_OPEN);
> >>> + write(ASEmitterTokens.DOUBLE_QUOTE);
> >>> + write(identifierNode.getName());
> >>> + write(ASEmitterTokens.DOUBLE_QUOTE);
> >>> + write(ASEmitterTokens.SQUARE_CLOSE);
> >>> + endMapping(node);
> >>> + }
> >>> + else
> >>> + {
> >>> + if (!isStatic && !isCustomNamespace)
> >>> + {
> >>> + startMapping(node,
> >> node.getLeftOperandNode());
> >>> + write(node.getOperator().
> >> getOperatorText());
> >>> + endMapping(node);
> >>> + }
> >>> + getWalker().walk(node.
> >> getRightOperandNode());
> >>> + }
> >>> }
> >>>
> >>> if (needClosure)
> >>> diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/
> >> internal/codegen/js/royale/TestDynamicAccessUnknownMembers.java
> >> b/compiler-jx/src/test/java/org/apache/royale/compiler/
> >> internal/codegen/js/royale/TestDynamicAccessUnknownMembers.java
> >>> new file mode 100644
> >>> index 0000000..64e5413
> >>> --- /dev/null
> >>> +++ b/compiler-jx/src/test/java/org/apache/royale/compiler/
> >> internal/codegen/js/royale/TestDynamicAccessUnknownMembers.java
> >>> @@ -0,0 +1,71 @@
> >>> +/*
> >>> + *
> >>> + * 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 org.apache.royale.compiler.driver.IBackend;
> >>> +import org.apache.royale.compiler.exceptions.ConfigurationException;
> >>> +import org.apache.royale.compiler.internal.driver.js.goog.
> >> JSGoogConfiguration;
> >>> +import org.apache.royale.compiler.internal.driver.js.royale.
> >> RoyaleBackend;
> >>> +import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
> >>> +import org.apache.royale.compiler.internal.test.ASTestBase;
> >>> +import org.apache.royale.compiler.tree.as.
> IMemberAccessExpressionNode;
> >>> +import org.junit.Test;
> >>> +
> >>> +public class TestDynamicAccessUnknownMembers extends ASTestBase
> >>> +{
> >>> + @Override
> >>> + public void setUp()
> >>> + {
> >>> + backend = createBackend();
> >>> + project = new RoyaleJSProject(workspace, backend);
> >>> + JSGoogConfiguration config = new JSGoogConfiguration();
> >>> + try {
> >>> + config.setJsDynamicAccessUnknownMembers(null,
> >> true);
> >>> + } catch (ConfigurationException e) {
> >>> + // TODO Auto-generated catch block
> >>> + e.printStackTrace();
> >>> + }
> >>> + project.config = config;
> >>> + super.setUp();
> >>> + }
> >>> +
> >>> + protected IBackend createBackend()
> >>> + {
> >>> + return new RoyaleBackend();
> >>> + }
> >>> +
> >>> + @Test
> >>> + public void testVisitKnownMember()
> >>> + {
> >>> + IMemberAccessExpressionNode node =
> >> (IMemberAccessExpressionNode) getNode(
> >>> + "public class KnownMember { public function
> >> KnownMember() { this.knownMember = 4; } public var knownMember:Number;
> }",
> >> IMemberAccessExpressionNode.class, WRAP_LEVEL_PACKAGE);
> >>> + asBlockWalker.visitMemberAccessExpression(node);
> >>> + assertOut("this.knownMember");
> >>> + }
> >>> +
> >>> + @Test
> >>> + public void testVisitUnknownMember()
> >>> + {
> >>> + IMemberAccessExpressionNode node =
> >> (IMemberAccessExpressionNode) getNode(
> >>> + "public dynamic class KnownMember { public function
> >> UnknownMember() { this.unknownMember = 4; } public var
> knownMember:Number;
> >> }", IMemberAccessExpressionNode.class, WRAP_LEVEL_PACKAGE);
> >>> + asBlockWalker.visitMemberAccessExpression(node);
> >>> + assertOut("this[\"unknownMember\"]");
> >>> + }
> >>> +}
> >>> \ No newline at end of file
> >>>
> >>
> >>
> >
> >
> > --
> > Carlos Rovira
> > http://about.me/carlosrovira
>
>
--
Carlos Rovira
http://about.me/carlosrovira