One suggestion on this:

Instead of making it a simple true/false, I’d suggest a tristate control of 
true/false/booleans.

The reason I’m making that suggestion is because even without strict equality, 
setting booleans to false has the benefit that bool1 == bool2 will work as 
expected where undefined might not.

FWIW, I have discovered that undefined for Numbers generally behaves the same 
as NaN. I have also discovered that it’s very useful to NOT initialize Numbers. 
Most NaN math errors I get are due to math with numbers which have not been 
properly initialized. Anytime I get an unexpected NaN value, I’ve found it’s 
very easy to walk up the stack trace to discover where math has been done with 
an undefined value which basically without fail exposes the bug. Initializing 
the values to NaN would mask the issues and make them harder to find.

My $0.02,
Harbs

> On Aug 1, 2017, at 1:02 AM, joshtynj...@apache.org wrote:
> 
> Repository: flex-falcon
> Updated Branches:
>  refs/heads/develop b04074bf0 -> c500b3fe5
> 
> 
> compiler-jx: Added -js-default-initializers option to force uninitialized 
> variables to default to the same values in JS as they do in SWF.
> 
> -js-default-initializers defaults to false and is completely optional, but 
> may be useful for porting SWF projects to JS if an existing codebase uses 
> strict equality and relies on the SWF default initializers.
> 
> 
> Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo
> Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/c500b3fe
> Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/c500b3fe
> Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/c500b3fe
> 
> Branch: refs/heads/develop
> Commit: c500b3fe52299272dbf201033723296057c79413
> Parents: b04074b
> Author: Josh Tynjala <joshtynj...@apache.org>
> Authored: Mon Jul 31 14:47:24 2017 -0700
> Committer: Josh Tynjala <joshtynj...@apache.org>
> Committed: Mon Jul 31 14:54:24 2017 -0700
> 
> ----------------------------------------------------------------------
> .../flex/compiler/clients/JSConfiguration.java  | 19 ++++++
> .../codegen/js/jx/VarDeclarationEmitter.java    | 61 ++++++++++++++++----
> 2 files changed, 68 insertions(+), 12 deletions(-)
> ----------------------------------------------------------------------
> 
> 
> http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c500b3fe/compiler-jx/src/main/java/org/apache/flex/compiler/clients/JSConfiguration.java
> ----------------------------------------------------------------------
> diff --git 
> a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/JSConfiguration.java
>  
> b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/JSConfiguration.java
> index ab1c73c..9f6bbe9 100644
> --- 
> a/compiler-jx/src/main/java/org/apache/flex/compiler/clients/JSConfiguration.java
> +++ 
> b/compiler-jx/src/main/java/org/apache/flex/compiler/clients/JSConfiguration.java
> @@ -118,6 +118,25 @@ public class JSConfiguration extends Configuration
>     }
> 
>     //
> +    // 'js-default-initializers'
> +    //
> +
> +    private boolean jsDefaultInitializers = false;
> +
> +    public boolean getJsDefaultInitializers()
> +    {
> +        return jsDefaultInitializers;
> +    }
> +
> +    @Config
> +    @Mapping("js-default-initializers")
> +    public void setJsDefaultInitializers(ConfigurationValue cv, boolean 
> value)
> +            throws ConfigurationException
> +    {
> +        jsDefaultInitializers = value;
> +    }
> +
> +    //
>     // 'compiler.js-external-library-path' option
>     //
> 
> 
> http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c500b3fe/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
> ----------------------------------------------------------------------
> diff --git 
> a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
>  
> b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
> index 4e35e39..e71c54e 100644
> --- 
> a/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
> +++ 
> b/compiler-jx/src/main/java/org/apache/flex/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
> @@ -21,6 +21,7 @@ package org.apache.flex.compiler.internal.codegen.js.jx;
> 
> 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.constants.IASLanguageConstants;
> import org.apache.flex.compiler.definitions.IDefinition;
> import org.apache.flex.compiler.definitions.metadata.IMetaTag;
> @@ -28,11 +29,13 @@ 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.JSSubEmitter;
> import org.apache.flex.compiler.internal.codegen.js.flexjs.JSFlexJSEmitter;
> +import org.apache.flex.compiler.internal.projects.FlexJSProject;
> import org.apache.flex.compiler.internal.tree.as.ChainedVariableNode;
> import org.apache.flex.compiler.internal.tree.as.DynamicAccessNode;
> 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.projects.ICompilerProject;
> import org.apache.flex.compiler.tree.ASTNodeID;
> import org.apache.flex.compiler.tree.as.IASNode;
> import org.apache.flex.compiler.tree.as.IEmbedNode;
> @@ -182,18 +185,52 @@ public class VarDeclarationEmitter extends JSSubEmitter 
> implements
>                 typedef = enode.resolveType(getWalker().getProject());
>             if (typedef != null)
>             {
> -                     String defName = typedef.getQualifiedName();
> -                     if (defName.equals("int") || defName.equals("uint"))
> -                     {
> -                             if (node.getParent() != null &&
> -                                             node.getParent().getParent() != 
> null &&
> -                                             
> node.getParent().getParent().getNodeID() != ASTNodeID.Op_InID)
> -                             {
> -                                 write(ASEmitterTokens.SPACE);
> -                                 writeToken(ASEmitterTokens.EQUAL);
> -                                 write("0");
> -                             }
> -                     }
> +                boolean defaultInitializers = false;
> +                ICompilerProject project = getProject();
> +                if(project instanceof FlexJSProject)
> +                {
> +                    FlexJSProject fjsProject = (FlexJSProject) project; 
> +                    if(fjsProject.config != null)
> +                    {
> +                        defaultInitializers = 
> fjsProject.config.getJsDefaultInitializers();
> +                    }
> +                }
> +                if (node.getParent() != null &&
> +                        node.getParent().getParent() != null &&
> +                        node.getParent().getParent().getNodeID() != 
> ASTNodeID.Op_InID)
> +                {
> +                    String defName = typedef.getQualifiedName();
> +                    if (defName.equals("int") || defName.equals("uint"))
> +                    {
> +                        write(ASEmitterTokens.SPACE);
> +                        writeToken(ASEmitterTokens.EQUAL);
> +                        write("0");
> +                    }
> +                    if (defaultInitializers)
> +                    {
> +                        if (defName.equals("Number"))
> +                        {
> +                            write(ASEmitterTokens.SPACE);
> +                            writeToken(ASEmitterTokens.EQUAL);
> +                            write(IASKeywordConstants.NA_N);
> +                        }
> +                        else if (defName.equals("Boolean"))
> +                        {
> +                            write(ASEmitterTokens.SPACE);
> +                            writeToken(ASEmitterTokens.EQUAL);
> +                            write(IASKeywordConstants.FALSE);
> +                        }
> +                        else if (!defName.equals("*"))
> +                        {
> +                            //type * is meant to default to undefined, so it
> +                            //doesn't need to be initialized, but everything
> +                            //else should default to null
> +                            write(ASEmitterTokens.SPACE);
> +                            writeToken(ASEmitterTokens.EQUAL);
> +                            write(IASKeywordConstants.NULL);
> +                        }
> +                    }
> +                }
>             }
>         }
> 
> 

Reply via email to