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 b0867cb  compiler-jx: boolean coercion on assignment (references #78)
b0867cb is described below

commit b0867cbe5e5a1bc0b5a498f944074a5dca4b3ab0
Author: Josh Tynjala <[email protected]>
AuthorDate: Fri Feb 8 10:30:22 2019 -0800

    compiler-jx: boolean coercion on assignment (references #78)
---
 .../compiler/internal/codegen/js/JSEmitter.java    |  46 ++++-
 .../codegen/js/jx/BinaryOperatorEmitter.java       |  49 +++--
 .../codegen/js/jx/VarDeclarationEmitter.java       |  53 ++++--
 .../codegen/js/goog/TestGoogGlobalFunctions.java   |   3 +
 .../codegen/js/royale/TestRoyaleClass.java         |  53 +++++-
 .../codegen/js/royale/TestRoyaleExpressions.java   | 206 ++++++++++++++++++++-
 .../codegen/js/royale/TestRoyaleStatements.java    |  54 ++++++
 7 files changed, 426 insertions(+), 38 deletions(-)

diff --git 
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java
 
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java
index ddb6e0b..c7a4570 100644
--- 
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java
+++ 
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java
@@ -28,6 +28,7 @@ import org.apache.royale.compiler.codegen.ISubEmitter;
 import org.apache.royale.compiler.codegen.js.IJSEmitter;
 import org.apache.royale.compiler.codegen.js.IMappingEmitter;
 import org.apache.royale.compiler.common.ISourceLocation;
+import org.apache.royale.compiler.constants.IASLanguageConstants;
 import org.apache.royale.compiler.constants.IASLanguageConstants.BuiltinType;
 import org.apache.royale.compiler.definitions.IDefinition;
 import org.apache.royale.compiler.internal.codegen.as.ASEmitter;
@@ -521,10 +522,12 @@ public class JSEmitter extends ASEmitter implements 
IJSEmitter
     public void emitAssignmentCoercion(IExpressionNode assignedNode, 
IDefinition definition)
     {
         IDefinition assignedDef = null;
+        IDefinition assignedTypeDef = null;
         ICompilerProject project = getWalker().getProject();
         if (assignedNode != null)
         {
-            assignedDef = assignedNode.resolveType(project);
+            assignedDef = assignedNode.resolve(project);
+            assignedTypeDef = assignedNode.resolveType(project);
         }
                String coercionStart = null;
         String coercionEnd = null;
@@ -540,7 +543,7 @@ public class JSEmitter extends ASEmitter implements 
IJSEmitter
                 endMapping(assignedNode);
                 return;
                        }
-                       else 
if(!project.getBuiltinType(BuiltinType.INT).equals(assignedDef))
+                       else 
if(!project.getBuiltinType(BuiltinType.INT).equals(assignedTypeDef))
                        {
                                needsCoercion = true;
                        }
@@ -562,7 +565,7 @@ public class JSEmitter extends ASEmitter implements 
IJSEmitter
                 endMapping(assignedNode);
                 return;
                        }
-                       else 
if(!project.getBuiltinType(BuiltinType.UINT).equals(assignedDef))
+                       else 
if(!project.getBuiltinType(BuiltinType.UINT).equals(assignedTypeDef))
                        {
                                needsCoercion = true;
                        }
@@ -573,15 +576,42 @@ public class JSEmitter extends ASEmitter implements 
IJSEmitter
             }
         }
         else if (project.getBuiltinType(BuiltinType.NUMBER).equals(definition)
-                && 
!project.getBuiltinType(BuiltinType.NUMBER).equals(assignedDef)
-                && !project.getBuiltinType(BuiltinType.INT).equals(assignedDef)
-                && 
!project.getBuiltinType(BuiltinType.UINT).equals(assignedDef))
+                && 
!project.getBuiltinType(BuiltinType.NUMBER).equals(assignedTypeDef)
+                && 
!project.getBuiltinType(BuiltinType.INT).equals(assignedTypeDef)
+                && 
!project.getBuiltinType(BuiltinType.UINT).equals(assignedTypeDef))
         {
             coercionStart = "Number(";
         }
+        else if (project.getBuiltinType(BuiltinType.BOOLEAN).equals(definition)
+                && 
!project.getBuiltinType(BuiltinType.BOOLEAN).equals(assignedTypeDef))
+        {
+            if 
(project.getBuiltinType(BuiltinType.NULL).equals(assignedTypeDef)
+                    || (assignedDef != null && 
assignedDef.getQualifiedName().equals(IASLanguageConstants.UNDEFINED)))
+            {
+                //null and undefined are coerced to false
+                startMapping(assignedNode);
+                write(IASLanguageConstants.FALSE);
+                endMapping(assignedNode);
+                return;
+            }
+                       if (assignedNode instanceof INumericLiteralNode)
+                       {
+                INumericLiteralNode numericLiteral = (INumericLiteralNode) 
assignedNode;
+                INumericLiteralNode.INumericValue numericValue = 
numericLiteral.getNumericValue();
+                //zero is coerced to false, and everything else is true
+                String booleanValue = numericValue.toNumber() == 0.0
+                        ? IASLanguageConstants.FALSE
+                        : IASLanguageConstants.TRUE;
+                startMapping(assignedNode);
+                write(booleanValue);
+                endMapping(assignedNode);
+                return;
+                       }
+            coercionStart = "!!(";
+        }
         else if (project.getBuiltinType(BuiltinType.STRING).equals(definition)
-                && 
!project.getBuiltinType(BuiltinType.STRING).equals(assignedDef)
-                && 
!project.getBuiltinType(BuiltinType.NULL).equals(assignedDef))
+                && 
!project.getBuiltinType(BuiltinType.STRING).equals(assignedTypeDef)
+                && 
!project.getBuiltinType(BuiltinType.NULL).equals(assignedTypeDef))
         {
             coercionStart = "org.apache.royale.utils.Language.string(";
         }
diff --git 
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
 
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
index 629a0d9..884168a 100644
--- 
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
+++ 
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
@@ -403,11 +403,12 @@ public class BinaryOperatorEmitter extends JSSubEmitter 
implements
                                          
leftDef.getQualifiedName().equals(IASLanguageConstants._int) ||
                                          
leftDef.getQualifiedName().equals(IASLanguageConstants.uint)));
                IExpressionNode rNode = node.getRightOperandNode();
-               IDefinition rightDef = 
rNode.resolveType(getWalker().getProject());
-               boolean rightIsNumber = (rightDef != null && 
(rightDef.getQualifiedName().equals(IASLanguageConstants.Number) ||
-                                         
rightDef.getQualifiedName().equals(IASLanguageConstants._int) ||
-                                         
rightDef.getQualifiedName().equals(IASLanguageConstants.uint)));
-            if (leftIsNumber && !rightIsNumber && (rightDef == null || 
rightDef.getQualifiedName().equals(IASLanguageConstants.ANY_TYPE)))
+               IDefinition rightDef = rNode.resolve(getWalker().getProject());
+               IDefinition rightTypeDef = 
rNode.resolveType(getWalker().getProject());
+               boolean rightIsNumber = (rightTypeDef != null && 
(rightTypeDef.getQualifiedName().equals(IASLanguageConstants.Number) ||
+                                         
rightTypeDef.getQualifiedName().equals(IASLanguageConstants._int) ||
+                                         
rightTypeDef.getQualifiedName().equals(IASLanguageConstants.uint)));
+            if (leftIsNumber && !rightIsNumber && (rightTypeDef == null || 
rightTypeDef.getQualifiedName().equals(IASLanguageConstants.ANY_TYPE)))
             {
                        if (rNode.getNodeID() == ASTNodeID.FunctionCallID)
                        {
@@ -460,7 +461,7 @@ public class BinaryOperatorEmitter extends JSSubEmitter 
implements
                                                
INumericLiteralNode.INumericValue numericValue = 
numericLiteral.getNumericValue();
                                                coercedValue = 
Integer.toString(numericValue.toInt32());
                                        }
-                                       else 
if(!getProject().getBuiltinType(BuiltinType.INT).equals(rightDef))
+                                       else 
if(!getProject().getBuiltinType(BuiltinType.INT).equals(rightTypeDef))
                                        {
                                                needsCoercion = true;
                                        }
@@ -479,7 +480,7 @@ public class BinaryOperatorEmitter extends JSSubEmitter 
implements
                                                
INumericLiteralNode.INumericValue numericValue = 
numericLiteral.getNumericValue();
                                                coercedValue = 
Long.toString(numericValue.toUint32());
                                        }
-                                       else 
if(!getProject().getBuiltinType(BuiltinType.UINT).equals(rightDef))
+                                       else 
if(!getProject().getBuiltinType(BuiltinType.UINT).equals(rightTypeDef))
                                        {
                                                needsCoercion = true;
                                        }
@@ -493,19 +494,45 @@ public class BinaryOperatorEmitter extends JSSubEmitter 
implements
                                {
                                        coercionStart = "Number(";
                                }
+                               else if 
(getProject().getBuiltinType(BuiltinType.BOOLEAN).equals(leftDef)
+                                               && 
!getProject().getBuiltinType(BuiltinType.BOOLEAN).equals(rightTypeDef))
+                               {
+                                       boolean needsCoercion = true;
+                                       if 
(getProject().getBuiltinType(BuiltinType.NULL).equals(rightTypeDef)
+                                                       || (rightDef != null && 
rightDef.getQualifiedName().equals(IASLanguageConstants.UNDEFINED)))
+                                       {
+                                               //null and undefined are 
coerced to false
+                                               coercedValue = 
IASLanguageConstants.FALSE;
+                                               needsCoercion = false;
+                                       }
+                                       else if (rNode instanceof 
INumericLiteralNode)
+                                       {
+                                               INumericLiteralNode 
numericLiteral = (INumericLiteralNode) rNode;
+                                               
INumericLiteralNode.INumericValue numericValue = 
numericLiteral.getNumericValue();
+                                               //zero is coerced to false, and 
everything else is true
+                                               coercedValue = 
numericValue.toNumber() == 0.0
+                                                               ? 
IASLanguageConstants.FALSE
+                                                               : 
IASLanguageConstants.TRUE;
+                                                               needsCoercion = 
false;
+                                       }
+                                       if (needsCoercion)
+                                       {
+                                               coercionStart = "!!(";
+                                       }
+                               }
                                else if 
(getProject().getBuiltinType(BuiltinType.STRING).equals(leftDef))
                                {
                                        if (rNode.getNodeID() != 
ASTNodeID.LiteralStringID &&
                                                        rNode.getNodeID() != 
ASTNodeID.LiteralNullID)
                                        {
-                                               if (rightDef == null ||
-                                                               
(!(rightDef.getQualifiedName().equals(IASLanguageConstants.String) ||
-                                                               
(rightDef.getQualifiedName().equals(IASLanguageConstants.ANY_TYPE)
+                                               if (rightTypeDef == null ||
+                                                               
(!(rightTypeDef.getQualifiedName().equals(IASLanguageConstants.String) ||
+                                                               
(rightTypeDef.getQualifiedName().equals(IASLanguageConstants.ANY_TYPE)
                                                                                
&& rNode.getNodeID() == ASTNodeID.FunctionCallID &&
                                                                                
isToString(rNode)) ||
                                                                // if not an 
assignment we don't need to coerce numbers
                                                                (!isAssignment 
&& rightIsNumber) ||
-                                                               
rightDef.getQualifiedName().equals(IASLanguageConstants.Null))))
+                                                               
rightTypeDef.getQualifiedName().equals(IASLanguageConstants.Null))))
                                                {
                                                        JSRoyaleDocEmitter 
docEmitter = (JSRoyaleDocEmitter)(getEmitter().getDocEmitter());
                                                        if 
(docEmitter.emitStringConversions)
diff --git 
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
 
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
index 6adceae..64718b1 100644
--- 
a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
+++ 
b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/VarDeclarationEmitter.java
@@ -92,13 +92,15 @@ public class VarDeclarationEmitter extends JSSubEmitter 
implements
         }
         IExpressionNode avnode = node.getAssignedValueNode();
         IDefinition avdef = null;
+        IDefinition avtypedef = null;
         if (avnode != null)
         {
-               avdef = avnode.resolveType(getWalker().getProject());
+            avdef = avnode.resolve(getProject());
+               avtypedef = avnode.resolveType(getProject());
             String opcode = avnode.getNodeID().getParaphrase();
             if (opcode != "AnonymousFunction")
             {
-                fjs.getDocEmitter().emitVarDoc(node, avdef, 
getWalker().getProject());
+                fjs.getDocEmitter().emitVarDoc(node, avtypedef, 
getWalker().getProject());
             }
         }
         else
@@ -132,17 +134,17 @@ public class VarDeclarationEmitter extends JSSubEmitter 
implements
             boolean varIsNumber = (variableTypeNode.getNodeID() == 
ASTNodeID.IdentifierID && 
                          
(((IdentifierNode)variableTypeNode).getName().equals(IASLanguageConstants.Number)
 ||
                           varIsInt));
-            boolean valIsInt = (avdef != null && 
(avdef.getQualifiedName().equals(IASLanguageConstants._int) ||
-                                                                               
                  avdef.getQualifiedName().equals(IASLanguageConstants.uint) ||
-                                                                               
                  (avdef.getQualifiedName().equals(IASLanguageConstants.Number) 
&&
+            boolean valIsInt = (avtypedef != null && 
(avtypedef.getQualifiedName().equals(IASLanguageConstants._int) ||
+                                                                               
                  
avtypedef.getQualifiedName().equals(IASLanguageConstants.uint) ||
+                                                                               
                  
(avtypedef.getQualifiedName().equals(IASLanguageConstants.Number) &&
                                                                                
                                  (avnode.getNodeID() == 
ASTNodeID.LiteralIntegerID ||
                                                                                
                                   avnode.getNodeID() == 
ASTNodeID.LiteralIntegerZeroID))));
-            boolean valIsNumber = (avdef != null && 
(avdef.getQualifiedName().equals(IASLanguageConstants.Number) ||
+            boolean valIsNumber = (avtypedef != null && 
(avtypedef.getQualifiedName().equals(IASLanguageConstants.Number) ||
                                                                                
         valIsInt));
-            if (!valIsNumber && avdef == null && avnode.getNodeID() == 
ASTNodeID.MemberAccessExpressionID &&
+            if (!valIsNumber && avtypedef == null && avnode.getNodeID() == 
ASTNodeID.MemberAccessExpressionID &&
                        fjs.isDateProperty(avnode, false))
                valIsNumber = true;
-            if (varIsNumber && !valIsNumber && (avdef == null || 
avdef.getQualifiedName().equals(IASLanguageConstants.ANY_TYPE)))
+            if (varIsNumber && !valIsNumber && (avtypedef == null || 
avtypedef.getQualifiedName().equals(IASLanguageConstants.ANY_TYPE)))
             {
                        if (avnode.getNodeID() == ASTNodeID.FunctionCallID)
                        {
@@ -193,7 +195,7 @@ public class VarDeclarationEmitter extends JSSubEmitter 
implements
                     INumericLiteralNode.INumericValue numericValue = 
numericLiteral.getNumericValue();
                     coercedValue = Integer.toString(numericValue.toInt32());
                 }
-                else 
if(!getProject().getBuiltinType(BuiltinType.INT).equals(avdef))
+                else 
if(!getProject().getBuiltinType(BuiltinType.INT).equals(avtypedef))
                 {
                     needsCoercion = true;
                 }
@@ -212,7 +214,7 @@ public class VarDeclarationEmitter extends JSSubEmitter 
implements
                     INumericLiteralNode.INumericValue numericValue = 
numericLiteral.getNumericValue();
                     coercedValue = Long.toString(numericValue.toUint32());
                 }
-                else 
if(!getProject().getBuiltinType(BuiltinType.UINT).equals(avdef))
+                else 
if(!getProject().getBuiltinType(BuiltinType.UINT).equals(avtypedef))
                 {
                     needsCoercion = true;
                 }
@@ -226,9 +228,36 @@ public class VarDeclarationEmitter extends JSSubEmitter 
implements
             {
                 coercionStart = "Number(";
             }
+            else if 
(getProject().getBuiltinType(BuiltinType.BOOLEAN).equals(variableDef)
+                    && 
!getProject().getBuiltinType(BuiltinType.BOOLEAN).equals(avtypedef))
+            {
+                if 
(getProject().getBuiltinType(BuiltinType.NULL).equals(avtypedef)
+                        || (avdef != null && 
avdef.getQualifiedName().equals(IASLanguageConstants.UNDEFINED)))
+                {
+                    //null and undefined are coerced to false
+                    startMapping(avnode);
+                    write(IASLanguageConstants.FALSE);
+                    endMapping(avnode);
+                    return;
+                }
+                if (avnode instanceof INumericLiteralNode)
+                {
+                    INumericLiteralNode numericLiteral = (INumericLiteralNode) 
avnode;
+                    INumericLiteralNode.INumericValue numericValue = 
numericLiteral.getNumericValue();
+                    //zero is coerced to false, and everything else is true
+                    String booleanValue = numericValue.toNumber() == 0.0
+                            ? IASLanguageConstants.FALSE
+                            : IASLanguageConstants.TRUE;
+                    startMapping(avnode);
+                    write(booleanValue);
+                    endMapping(avnode);
+                    return;
+                }
+                coercionStart = "!!(";
+            }
             else if 
(getProject().getBuiltinType(BuiltinType.STRING).equals(variableDef) &&
-                !getProject().getBuiltinType(BuiltinType.STRING).equals(avdef) 
&&
-                !getProject().getBuiltinType(BuiltinType.NULL).equals(avdef))
+                
!getProject().getBuiltinType(BuiltinType.STRING).equals(avtypedef) &&
+                
!getProject().getBuiltinType(BuiltinType.NULL).equals(avtypedef))
             {
                 coercionStart = "org.apache.royale.utils.Language.string(";
             }
diff --git 
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogGlobalFunctions.java
 
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogGlobalFunctions.java
index 5b54916..107c1bc 100644
--- 
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogGlobalFunctions.java
+++ 
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/goog/TestGoogGlobalFunctions.java
@@ -24,6 +24,7 @@ import 
org.apache.royale.compiler.internal.codegen.as.TestGlobalFunctions;
 import org.apache.royale.compiler.internal.driver.js.goog.GoogBackend;
 import org.apache.royale.compiler.tree.as.IFunctionCallNode;
 import org.apache.royale.compiler.tree.as.IVariableNode;
+import org.junit.Ignore;
 import org.junit.Test;
 
 /**
@@ -121,6 +122,8 @@ public class TestGoogGlobalFunctions extends 
TestGlobalFunctions
         assertOut("var /** @type {boolean} */ a = isNaN(NaN)");
     }
 
+    //isXMLName is in E4X, which is not supported by JavaScript
+    @Ignore
     @Override
     @Test
     public void testIsXMLName()
diff --git 
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleClass.java
 
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleClass.java
index 9d36301..5445b85 100644
--- 
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleClass.java
+++ 
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleClass.java
@@ -149,7 +149,16 @@ public class TestRoyaleClass extends TestGoogClass
     }
 
     @Test
-    public void testMethod_returnInt()
+    public void testMethod_returnIntWithVariableNoCoercion()
+    {
+        IClassNode node = getClassNode("public class B {public function B() 
{}; public function foo():int { var a:int = 123; return a; };}");
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = 
function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for 
reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', 
org.apache.royale.B);\n\n\n/**\n * @export\n 
*/\norg.apache.royale.B.prototype.foo = function() {\n  var a /** @type 
{number} */ = 123.4;\n  return a;\n};";
+        assertOut(expected);
+    }
+
+    @Test
+    public void testMethod_returnIntWithVariableCoercion()
     {
         IClassNode node = getClassNode("public class B {public function B() 
{}; public function foo():int { var a:Number = 123.4; return a; };}");
         asBlockWalker.visitClass(node);
@@ -158,7 +167,7 @@ public class TestRoyaleClass extends TestGoogClass
     }
 
     @Test
-    public void testMethod_returnIntLiteral()
+    public void testMethod_returnIntWithLiteralCoercion()
     {
         IClassNode node = getClassNode("public class B {public function B() 
{}; public function foo():int { return 123.4 };}");
         asBlockWalker.visitClass(node);
@@ -167,7 +176,16 @@ public class TestRoyaleClass extends TestGoogClass
     }
 
     @Test
-    public void testMethod_returnUint()
+    public void testMethod_returnUintWithVariableNoCoercion()
+    {
+        IClassNode node = getClassNode("public class B {public function B() 
{}; public function foo():uint { var a:uint = 123; return a; };}");
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = 
function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for 
reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', 
org.apache.royale.B);\n\n\n/**\n * @export\n 
*/\norg.apache.royale.B.prototype.foo = function() {\n  var a /** @type 
{number} */ = 123.4;\n  return a;\n};";
+        assertOut(expected);
+    }
+
+    @Test
+    public void testMethod_returnUintWithVariableCoercion()
     {
         IClassNode node = getClassNode("public class B {public function B() 
{}; public function foo():uint { var a:Number = 123.4; return a; };}");
         asBlockWalker.visitClass(node);
@@ -176,7 +194,7 @@ public class TestRoyaleClass extends TestGoogClass
     }
 
     @Test
-    public void testMethod_returnUintLiteral()
+    public void testMethod_returnUintWithLiteralCoercion()
     {
         IClassNode node = getClassNode("public class B {public function B() 
{}; public function foo():uint { return 123.4 };}");
         asBlockWalker.visitClass(node);
@@ -185,6 +203,33 @@ public class TestRoyaleClass extends TestGoogClass
     }
 
     @Test
+    public void testMethod_returnBooleanWithVariableNoCoercion()
+    {
+        IClassNode node = getClassNode("public class B {public function B() 
{}; public function foo():Boolean { var a:Boolean = true; return a; };}");
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = 
function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for 
reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', 
org.apache.royale.B);\n\n\n/**\n * @export\n 
*/\norg.apache.royale.B.prototype.foo = function() {\n  var a /** @type 
{number} */ = 123.4;\n  return a;\n};";
+        assertOut(expected);
+    }
+
+    @Test
+    public void testMethod_returnBooleanWithVariableCoercion()
+    {
+        IClassNode node = getClassNode("public class B {public function B() 
{}; public function foo():Boolean { var a:Number = 123.4; return a; };}");
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = 
function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for 
reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', 
org.apache.royale.B);\n\n\n/**\n * @export\n 
*/\norg.apache.royale.B.prototype.foo = function() {\n  var a /** @type 
{number} */ = 123.4;\n  return !!(a);\n};";
+        assertOut(expected);
+    }
+
+    @Test
+    public void testMethod_returnBooleanWithLiteralNoCoercion()
+    {
+        IClassNode node = getClassNode("public class B {public function B() 
{}; public function foo():Boolean { return 123.4 };}");
+        asBlockWalker.visitClass(node);
+        String expected = "/**\n * @constructor\n */\norg.apache.royale.B = 
function() {\n};\n\n\n/**\n * Prevent renaming of class. Needed for 
reflection.\n */\ngoog.exportSymbol('org.apache.royale.B', 
org.apache.royale.B);\n\n\n/**\n * @export\n 
*/\norg.apache.royale.B.prototype.foo = function() {\n  return true;\n};";
+        assertOut(expected);
+    }
+
+    @Test
     public void testMethod_override()
     {
         IClassNode node = getClassNode("public class B {public function B() 
{}; override public function foo():void {};}");
diff --git 
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleExpressions.java
 
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleExpressions.java
index 56b6363..05f05ac 100644
--- 
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleExpressions.java
+++ 
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleExpressions.java
@@ -106,9 +106,9 @@ public class TestRoyaleExpressions extends 
TestGoogExpressions
     @Test
     public void testVisitLanguageIdentifierNode_SuperGetter()
     {
-        IClassNode node = (IClassNode)getNode("public function get 
defaultPrevented():Boolean " +
+        IClassNode node = (IClassNode)getNode("public function get 
defaultPrevented():Object " +
                                               "{ return 
super.isDefaultPrevented(); }" + 
-                                              "override public function 
isDefaultPrevented():Boolean" +
+                                              "override public function 
isDefaultPrevented():Object" +
                                        "{ return defaultPrevented; }", 
IClassNode.class);
         // getters and setters don't get output until the class is output so 
you can't just visit the accessorNode
         asBlockWalker.visitClass(node);
@@ -129,7 +129,7 @@ public class TestRoyaleExpressions extends 
TestGoogExpressions
                          "  return 
RoyaleTest_A.superClass_.isDefaultPrevented.apply(this);\n" +
                          "};\n\n\n" +
                          "Object.defineProperties(RoyaleTest_A.prototype, /** 
@lends {RoyaleTest_A.prototype} */ {\n" +
-                         "/**\n  * @export\n  * @type {boolean} */\n" +
+                         "/**\n  * @export\n  * @type {Object} */\n" +
                          "defaultPrevented: {\nget: 
RoyaleTest_A.prototype.get__defaultPrevented}}\n);");
     }
 
@@ -270,6 +270,78 @@ public class TestRoyaleExpressions extends 
TestGoogExpressions
     }
 
     @Test
+    public void testVisitBinaryOperatorNode_AssignmentBooleanVarToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool1:Boolean;var 
bool2:Boolean;bool1 = bool2");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool1 = bool2");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentNumberVarToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var boolean:Boolean;var 
number:Number;boolean = number");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("boolean = !!(number)");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentBooleanLiteralToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool:Boolean;bool = 
true");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool = true");
+    }
+
+    @Test
+    public void 
testVisitBinaryOperatorNode_AssignmentPositiveNumberLiteralToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool:Boolean;bool = 
123.4");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool = true");
+    }
+
+    @Test
+    public void 
testVisitBinaryOperatorNode_AssignmentNegativeNumberLiteralToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool:Boolean;bool = 
-123");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool = true");
+    }
+
+    @Test
+    public void 
testVisitBinaryOperatorNode_AssignmentZeroNumberLiteralToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool:Boolean;bool = 0");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool = false");
+    }
+
+    @Test
+    public void 
testVisitBinaryOperatorNode_AssignmentDecimalNumberLiteralToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool:Boolean;bool = 
0.123");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool = true");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentNullToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool:Boolean;bool = 
null");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool = false");
+    }
+
+    @Test
+    public void testVisitBinaryOperatorNode_AssignmentUndefinedToBoolean()
+    {
+        IBinaryOperatorNode node = getBinaryNode("var bool:Boolean;bool = 
undefined");
+        asBlockWalker.visitBinaryOperator(node);
+        assertOut("bool = false");
+    }
+
+    @Test
     public void testVisitBinaryOperatorNode_AssignmentIntVarToInt()
     {
         IBinaryOperatorNode node = getBinaryNode("var integer1:int;var 
integer2:int;integer1 = integer2");
@@ -1548,6 +1620,78 @@ public class TestRoyaleExpressions extends 
TestGoogExpressions
     }
 
     @Test
+    public void testVisitReturnBoolean()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return 
true; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return true");
+    }
+
+    @Test
+    public void testVisitReturnBooleanWithBooleanLiteral()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return 
true; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return true");
+    }
+
+    @Test
+    public void testVisitReturnBooleanWithPositiveNumberLiteral()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return 
123.4; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return true");
+    }
+
+    @Test
+    public void testVisitReturnBooleanWithNegativeNumberLiteral()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return 
-123; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return true");
+    }
+
+    @Test
+    public void testVisitReturnBooleanWithZeroLiteral()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return 
0; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return false");
+    }
+
+    @Test
+    public void testVisitReturnBooleanWithDecimalLiteral()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return 
0.01; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return true");
+    }
+
+    @Test
+    public void testVisitReturnBooleanWithNull()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return 
null; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return false");
+    }
+
+    @Test
+    public void testVisitReturnBooleanWithUndefined()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():Boolean { return 
undefined; }", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return false");
+    }
+
+    @Test
+    public void testVisitReturnIntWithIntLiteral()
+    {
+        IReturnNode node = (IReturnNode) getNode("function():int { return 123; 
}", IReturnNode.class);
+        asBlockWalker.visitReturn(node);
+        assertOut("return 123");
+    }
+
+    @Test
     public void testVisitReturnIntWithDecimalValue()
     {
         IReturnNode node = (IReturnNode) getNode("function():int { return 
-123.4; }", IReturnNode.class);
@@ -1603,6 +1747,62 @@ public class TestRoyaleExpressions extends 
TestGoogExpressions
         assertOut("a(123)");
     }
 
+    @Test
+    public void testVisitFunctionCallWithBooleanParameterBoolean()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function 
a(foo:Boolean):void {}; a(false)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(false)");
+    }
+
+    @Test
+    public void 
testVisitFunctionCallWithBooleanParameterPositiveNumberLiteral()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function 
a(foo:Boolean):void {}; a(123.4)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(true)");
+    }
+
+    @Test
+    public void 
testVisitFunctionCallWithBooleanParameterNegativeNumberLiteral()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function 
a(foo:Boolean):void {}; a(-123)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(true)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithBooleanParameterZeroNumberLiteral()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function 
a(foo:Boolean):void {}; a(0.0)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(false)");
+    }
+
+    @Test
+    public void 
testVisitFunctionCallWithBooleanParameterLessThanOneNumberLiteral()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function 
a(foo:Boolean):void {}; a(0.5)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(true)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithBooleanParameterNull()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function 
a(foo:Boolean):void {}; a(null)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(false)");
+    }
+
+    @Test
+    public void testVisitFunctionCallWithBooleanParameterUndefined()
+    {
+        IFunctionCallNode node = (IFunctionCallNode) getNode("function 
a(foo:Boolean):void {}; a(undefined)", IFunctionCallNode.class);
+        asBlockWalker.visitFunctionCall(node);
+        assertOut("a(false)");
+    }
+
     protected IBackend createBackend()
     {
         return new RoyaleBackend();
diff --git 
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleStatements.java
 
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleStatements.java
index a51da05..51de9a0 100644
--- 
a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleStatements.java
+++ 
b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/royale/TestRoyaleStatements.java
@@ -97,6 +97,60 @@ public class TestRoyaleStatements extends TestGoogStatements
     }
 
     @Test
+    public void testVarDeclaration_withTypeBooleanAndAssignedPositiveNumber()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:Boolean = 123.4;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {boolean} */ a = true");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeBooleanAndAssignedNegativeNumber()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:Boolean = -123;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {boolean} */ a = true");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeBooleanAndAssignedZeroNumber()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:Boolean = 0;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {boolean} */ a = false");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeBooleanAndAssignedDecimalNumber()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:Boolean = 0.123;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {boolean} */ a = true");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeBooleanAndAssignedNull()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:Boolean = null;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {boolean} */ a = false");
+    }
+
+    @Test
+    public void testVarDeclaration_withTypeBooleanAndAssignedUndefined()
+    {
+        IVariableNode node = (IVariableNode) getNode("var a:Boolean = 
undefined;",
+                IVariableNode.class);
+        asBlockWalker.visitVariable(node);
+        assertOut("var /** @type {boolean} */ a = false");
+    }
+
+    @Test
     public void testVarDeclaration_withTypeIntAndAssignedNumber()
     {
         IVariableNode node = (IVariableNode) getNode("var a:int = 123.4;",

Reply via email to