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 32c533852 null conditional operator with dynamic access
32c533852 is described below
commit 32c533852cc23f1d2019ed09de681a83440b3f05
Author: Josh Tynjala <[email protected]>
AuthorDate: Wed Aug 13 13:10:02 2025 -0700
null conditional operator with dynamic access
Example: a?.['b']
This new syntax enables a combination of the null conditional operator
(a?.b) and dynamic access (a['b']). In the example above, if a is nullish, the
operator will return null instead of trying to access the field named 'b'.
With a?.b, the name of b must be known at compile-time. With a?.['b'], the
field name b can be generated at run-time.
---
.../royale/compiler/internal/parsing/as/ASParser.g | 34 +-
.../compiler/internal/parsing/as/BaseASParser.java | 177 +++++--
... => ASNullConditionalOperatorDynamicTests.java} | 542 +++++++++++----------
.../java/as/ASNullConditionalOperatorTests.java | 14 -
4 files changed, 463 insertions(+), 304 deletions(-)
diff --git
a/compiler/src/main/antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.g
b/compiler/src/main/antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.g
index 7996c3c46..c7dd0992d 100644
---
a/compiler/src/main/antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.g
+++
b/compiler/src/main/antlr/org/apache/royale/compiler/internal/parsing/as/ASParser.g
@@ -3222,10 +3222,7 @@ propertyAccessExpression [ExpressionNodeBase l] returns
[ExpressionNodeBase n]
{ n = new MemberAccessExpressionNode(l, op, r); }
| TOKEN_OPERATOR_DESCENDANT_ACCESS r=accessPart
{ n = new MemberAccessExpressionNode(l, op, r); }
- | TOKEN_OPERATOR_NULL_CONDITIONAL_ACCESS r=nullConditionalAccessPart
- {
- n = transformNullConditional(l, op, r);
- }
+ | TOKEN_OPERATOR_NULL_CONDITIONAL_ACCESS n=nullConditionalExpression[l,
op]
| TOKEN_OPERATOR_NS_QUALIFIER r=nsAccessPart
{ if (l instanceof NamespaceIdentifierNode)
{
@@ -3278,6 +3275,35 @@ nsAccessPart returns [ExpressionNodeBase n]
;
exception catch [RecognitionException ex] { n =
handleMissingIdentifier(ex); }
+/**
+ * Matches a ?. null conditional expression.
+ */
+nullConditionalExpression [ExpressionNodeBase l, ASToken op] returns
[ExpressionNodeBase n]
+{
+ n = null;
+ ExpressionNodeBase r = null;
+ DynamicAccessNode d = null;
+}
+ : r=nullConditionalAccessPart
+ {
+ n = transformNullConditional(l, op, r);
+ }
+ | (
+ d=bracketExpression[l]
+ {
+ n = (ExpressionNodeBase)
d.getRightOperandNode();
+ }
+ (
+ n=arguments[n]
+ | n=propertyAccessExpression[n]
+ )*
+ )
+ {
+ n = transformNullConditionalDynamicAccess(l, op, d, n);
+ }
+ ;
+ exception catch [RecognitionException ex] { n =
handleMissingIdentifier(ex); }
+
/**
* Matches parts after the ?. in a null conditional access expression.
*/
diff --git
a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/BaseASParser.java
b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/BaseASParser.java
index f3785b8ce..0b93614a0 100644
---
a/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/BaseASParser.java
+++
b/compiler/src/main/java/org/apache/royale/compiler/internal/parsing/as/BaseASParser.java
@@ -3371,6 +3371,12 @@ abstract class BaseASParser extends LLkParser implements
IProblemReporter
return ternaryNode;
}
+ private enum NullConditionalType
+ {
+ MEMBER_ACCESS,
+ DYNAMIC_ACCESS;
+ }
+
/**
* The null conditional operator is rewritten as a ternary operator, in
* order to support SWF without adding new bytecode.
@@ -3382,23 +3388,26 @@ abstract class BaseASParser extends LLkParser
implements IProblemReporter
* performed on null.
*/
private static class NullConditionalTernaryOperatorNode extends
TernaryOperatorNode
- {
+ {
+ private NullConditionalType type;
private ExpressionNodeBase originalLeftOperandNode;
private ExpressionNodeBase originalRightOperandNode;
private ASToken originalOperator;
private Collection<ICompilerProblem> problems;
- public NullConditionalTernaryOperatorNode(ExpressionNodeBase
leftOperandNode, ASToken operator, ExpressionNodeBase rightOperandNode,
Collection<ICompilerProblem> problems)
+ private NullConditionalTernaryOperatorNode(NullConditionalType type,
+ ExpressionNodeBase leftOperandNode, ASToken operator,
ExpressionNodeBase rightNode, Collection<ICompilerProblem> problems)
{
super(new ASToken(ASTokenTypes.TOKEN_OPERATOR_TERNARY, -1, -1, -1,
-1, "?"),
generateConditionalNode(leftOperandNode),
generateLeftResultNode(),
- generateRightResultNode(leftOperandNode, operator,
rightOperandNode, problems));
+ generateRightResultNode(type, leftOperandNode, operator,
rightNode, problems));
setHasParenthesis(true);
+ this.type = type;
+ this.problems = problems;
originalLeftOperandNode = leftOperandNode;
- originalRightOperandNode = rightOperandNode;
originalOperator = operator;
- this.problems = problems;
+ originalRightOperandNode = rightNode;
}
private static ExpressionNodeBase
generateConditionalNode(ExpressionNodeBase leftOperandNode)
@@ -3407,7 +3416,7 @@ abstract class BaseASParser extends LLkParser implements
IProblemReporter
ASToken conditionNullToken = new
ASToken(ASTokenTypes.TOKEN_KEYWORD_NULL, -1, -1, -1, -1, "null");
LiteralNode conditionNullNode = new
LiteralNode(conditionNullToken, LiteralType.NULL);
return new BinaryOperatorEqualNode(conditionEqualToken,
leftOperandNode, conditionNullNode);
- }
+ }
private static ExpressionNodeBase generateLeftResultNode()
{
@@ -3415,57 +3424,113 @@ abstract class BaseASParser extends LLkParser
implements IProblemReporter
return new LiteralNode(resultNullToken, LiteralType.NULL);
}
- private static ExpressionNodeBase
generateRightResultNode(ExpressionNodeBase l, ASToken op, ExpressionNodeBase r,
Collection<ICompilerProblem> problems)
+ private static ExpressionNodeBase
generateRightResultNode(NullConditionalType type, ExpressionNodeBase l, ASToken
op, ExpressionNodeBase r, Collection<ICompilerProblem> problems)
{
if (r instanceof NullConditionalTernaryOperatorNode)
{
NullConditionalTernaryOperatorNode rightNullConditional =
(NullConditionalTernaryOperatorNode) r;
ExpressionNodeBase oldNullConditionalLeft =
rightNullConditional.getNullConditionalLeftOperandNode();
- ExpressionNodeBase memberAccessRight = oldNullConditionalLeft;
- if (oldNullConditionalLeft instanceof
MemberAccessExpressionNode)
+
+ if (NullConditionalType.DYNAMIC_ACCESS.equals(type))
+ {
+ ExpressionNodeBase newDynamicAccessRightOperand =
oldNullConditionalLeft;
+ if (oldNullConditionalLeft instanceof DynamicAccessNode)
+ {
+ // replace the entire left side, but keeping the right
side
+ DynamicAccessNode oldLeftDynamicAccess =
(DynamicAccessNode) oldNullConditionalLeft;
+ newDynamicAccessRightOperand = (ExpressionNodeBase)
oldLeftDynamicAccess.getRightOperandNode();
+ }
+ DynamicAccessNode newDynamicAccessNode = new
DynamicAccessNode(l);
+
newDynamicAccessNode.setRightOperandNode(newDynamicAccessRightOperand);
+ ExpressionNodeBase newNullConditionalLeftOperand =
rewriteDynamicAccess(newDynamicAccessNode);
+
rightNullConditional.setNullConditionalLeftOperandNode(newNullConditionalLeftOperand);
+ }
+ else
{
- // replace the entire left side, but keeping the right side
- MemberAccessExpressionNode oldLeftMemberAccess =
(MemberAccessExpressionNode) oldNullConditionalLeft;
- memberAccessRight = (ExpressionNodeBase)
oldLeftMemberAccess.getRightOperandNode();
+ ExpressionNodeBase newMemberAccessRightOperand =
oldNullConditionalLeft;
+ if (oldNullConditionalLeft instanceof
MemberAccessExpressionNode)
+ {
+ // replace the entire left side, but keeping the right
side
+ MemberAccessExpressionNode oldLeftMemberAccess =
(MemberAccessExpressionNode) oldNullConditionalLeft;
+ newMemberAccessRightOperand = (ExpressionNodeBase)
oldLeftMemberAccess.getRightOperandNode();
+ }
+ ASToken memberAccessOperator = new
ASToken(ASTokenTypes.TOKEN_OPERATOR_MEMBER_ACCESS, op.getStart(), op.getEnd(),
op.getLine(), op.getColumn(), ".");
+ MemberAccessExpressionNode newMemberAccessNode = new
MemberAccessExpressionNode(l, memberAccessOperator,
newMemberAccessRightOperand);
+ ExpressionNodeBase newNullConditionalLeftOperand =
rewriteMemberAccess(newMemberAccessNode);
+
rightNullConditional.setNullConditionalLeftOperandNode(newNullConditionalLeftOperand);
}
- ASToken memberAccessOperator = new
ASToken(ASTokenTypes.TOKEN_OPERATOR_MEMBER_ACCESS, op.getStart(), op.getEnd(),
op.getLine(), op.getColumn(), ".");
- MemberAccessExpressionNode memberAccessNode = new
MemberAccessExpressionNode(l, memberAccessOperator, memberAccessRight);
-
rightNullConditional.setNullConditionalLeftOperandNode(rewriteMemberAccess(memberAccessNode));
-
return rightNullConditional;
}
FunctionCallNode originalFunctionCallNode = null;
DynamicAccessNode originalDynamicAccessNode = null;
MemberAccessExpressionNode originalMemberAccessNode = null;
- ExpressionNodeBase memberAccessRight = r;
+ ExpressionNodeBase newRightOperand = r;
if (r instanceof FunctionCallNode)
{
originalFunctionCallNode = (FunctionCallNode) r;
- memberAccessRight = (ExpressionNodeBase)
originalFunctionCallNode.getNameNode();
+ newRightOperand = (ExpressionNodeBase)
originalFunctionCallNode.getNameNode();
}
else if (r instanceof DynamicAccessNode)
{
originalDynamicAccessNode = (DynamicAccessNode) r;
- memberAccessRight = (ExpressionNodeBase)
originalDynamicAccessNode.getLeftOperandNode();
+ newRightOperand = (ExpressionNodeBase)
originalDynamicAccessNode.getLeftOperandNode();
}
else if (r instanceof MemberAccessExpressionNode)
{
originalMemberAccessNode = (MemberAccessExpressionNode) r;
- memberAccessRight = (ExpressionNodeBase)
originalMemberAccessNode.getLeftOperandNode();
- }
- else if (!(r instanceof IIdentifierNode))
- {
- problems.add(new SyntaxProblem(r, r.getNodeKind()));
- return null;
+ newRightOperand = (ExpressionNodeBase)
originalMemberAccessNode.getLeftOperandNode();
}
ExpressionNodeBase expressionNode = null;
- if (memberAccessRight != null)
+ if (NullConditionalType.DYNAMIC_ACCESS.equals(type))
+ {
+ DynamicAccessNode dynamicAccessNode = new DynamicAccessNode(l);
+ if (newRightOperand instanceof MemberAccessExpressionNode)
+ {
+ MemberAccessExpressionNode rightMemberAccess =
(MemberAccessExpressionNode) newRightOperand;
+
dynamicAccessNode.setRightOperandNode((ExpressionNodeBase)rightMemberAccess.getLeftOperandNode());
+
+ ASToken memberAccessOperator = new
ASToken(ASTokenTypes.TOKEN_OPERATOR_MEMBER_ACCESS, op.getStart(), op.getEnd(),
op.getLine(), op.getColumn(), ".");
+ MemberAccessExpressionNode newMemberAccessNode = new
MemberAccessExpressionNode(dynamicAccessNode, memberAccessOperator,
(ExpressionNodeBase)rightMemberAccess.getRightOperandNode());
+
+ expressionNode = rewriteMemberAccess(newMemberAccessNode);
+ }
+ else if (newRightOperand instanceof DynamicAccessNode)
+ {
+ DynamicAccessNode rightDynamicAccses = (DynamicAccessNode)
newRightOperand;
+
dynamicAccessNode.setRightOperandNode((ExpressionNodeBase)rightDynamicAccses.getLeftOperandNode());
+
+ DynamicAccessNode newDynamicAccessNode = new
DynamicAccessNode(dynamicAccessNode);
+
newDynamicAccessNode.setRightOperandNode((ExpressionNodeBase)rightDynamicAccses.getRightOperandNode());
+
+ expressionNode =
rewriteDynamicAccess(newDynamicAccessNode);
+ }
+ else if (newRightOperand instanceof FunctionCallNode)
+ {
+ FunctionCallNode rightFunctionCall = (FunctionCallNode)
newRightOperand;
+
dynamicAccessNode.setRightOperandNode((ExpressionNodeBase)rightFunctionCall.getNameNode());
+
+ FunctionCallNode newFunctionCallNode = new
FunctionCallNode(dynamicAccessNode);
+ ContainerNode argumentsNode =
newFunctionCallNode.getArgumentsNode();
+ for (IExpressionNode argNode :
rightFunctionCall.getArgumentNodes())
+ {
+ argumentsNode.addItem((ExpressionNodeBase) argNode);
+ }
+
+ expressionNode = newFunctionCallNode;
+ }
+ else
+ {
+ dynamicAccessNode.setRightOperandNode(newRightOperand);
+ expressionNode = dynamicAccessNode;
+ }
+ }
+ else
{
ASToken memberAccessOperator = new
ASToken(ASTokenTypes.TOKEN_OPERATOR_MEMBER_ACCESS, op.getStart(), op.getEnd(),
op.getLine(), op.getColumn(), ".");
- MemberAccessExpressionNode memberAccessNode = new
MemberAccessExpressionNode(l, memberAccessOperator, memberAccessRight);
+ MemberAccessExpressionNode memberAccessNode = new
MemberAccessExpressionNode(l, memberAccessOperator, newRightOperand);
expressionNode = rewriteMemberAccess(memberAccessNode);
}
@@ -3483,7 +3548,7 @@ abstract class BaseASParser extends LLkParser implements
IProblemReporter
{
DynamicAccessNode newDynamicAccessNode = new
DynamicAccessNode(expressionNode);
newDynamicAccessNode.setRightOperandNode((ExpressionNodeBase)
originalDynamicAccessNode.getRightOperandNode());
- return newDynamicAccessNode;
+ return rewriteDynamicAccess(newDynamicAccessNode);
}
else if (originalMemberAccessNode != null)
{
@@ -3507,7 +3572,7 @@ abstract class BaseASParser extends LLkParser implements
IProblemReporter
{
originalLeftOperandNode = node;
setConditionalNode(generateConditionalNode(originalLeftOperandNode));
-
setRightOperandNode(generateRightResultNode(originalLeftOperandNode,
originalOperator, originalRightOperandNode, problems));
+ setRightOperandNode(generateRightResultNode(type,
originalLeftOperandNode, originalOperator, originalRightOperandNode, problems));
}
private static ASToken
copyMemberAccessOperator(MemberAccessExpressionNode m, ISourceLocation
sourceLocation)
@@ -3538,6 +3603,11 @@ abstract class BaseASParser extends LLkParser implements
IProblemReporter
private static ExpressionNodeBase
rewriteMemberAccess(MemberAccessExpressionNode m)
{
ExpressionNodeBase leftOperand = (ExpressionNodeBase)
m.getLeftOperandNode();
+ if (leftOperand instanceof DynamicAccessNode)
+ {
+ leftOperand = rewriteDynamicAccess((DynamicAccessNode)
leftOperand);
+ m.setLeftOperandNode(leftOperand);
+ }
ExpressionNodeBase rightOperand = (ExpressionNodeBase)
m.getRightOperandNode();
if (rightOperand instanceof DynamicAccessNode)
{
@@ -3546,7 +3616,7 @@ abstract class BaseASParser extends LLkParser implements
IProblemReporter
MemberAccessExpressionNode innerMemberAccess = new
MemberAccessExpressionNode(leftOperand, op, (ExpressionNodeBase)
rightOperandDynamicAccess.getLeftOperandNode());
DynamicAccessNode newDynamicAccess = new
DynamicAccessNode(rewriteMemberAccess(innerMemberAccess));
newDynamicAccess.setRightOperandNode((ExpressionNodeBase)
rightOperandDynamicAccess.getRightOperandNode());
- return newDynamicAccess;
+ return rewriteDynamicAccess(newDynamicAccess);
}
else if (rightOperand instanceof MemberAccessExpressionNode)
{
@@ -3572,10 +3642,55 @@ abstract class BaseASParser extends LLkParser
implements IProblemReporter
}
return m;
}
+
+ private static ExpressionNodeBase
rewriteDynamicAccess(DynamicAccessNode d)
+ {
+ ExpressionNodeBase leftOperand = (ExpressionNodeBase)
d.getLeftOperandNode();
+ ExpressionNodeBase rightOperand = (ExpressionNodeBase)
d.getRightOperandNode();
+ if (rightOperand instanceof DynamicAccessNode)
+ {
+ DynamicAccessNode rightOperandDynamicAccess =
(DynamicAccessNode) rightOperand;
+ DynamicAccessNode innerDynamicAccess = new
DynamicAccessNode(leftOperand);
+ innerDynamicAccess.setRightOperandNode((ExpressionNodeBase)
rightOperandDynamicAccess.getLeftOperandNode());
+ DynamicAccessNode newOuterDynamicAccess = new
DynamicAccessNode(rewriteDynamicAccess(innerDynamicAccess));
+ newOuterDynamicAccess.setRightOperandNode((ExpressionNodeBase)
rightOperandDynamicAccess.getRightOperandNode());
+ return rewriteDynamicAccess(newOuterDynamicAccess);
+ }
+ else if (rightOperand instanceof MemberAccessExpressionNode)
+ {
+ MemberAccessExpressionNode rightOperandMemberAccess =
(MemberAccessExpressionNode) rightOperand;
+ ASToken op =
copyMemberAccessOperator(rightOperandMemberAccess, rightOperandMemberAccess);
+ DynamicAccessNode innerDynamicAccess = new
DynamicAccessNode(leftOperand);
+ innerDynamicAccess.setRightOperandNode((ExpressionNodeBase)
rightOperandMemberAccess.getLeftOperandNode());
+ ExpressionNodeBase innerExpression =
rewriteDynamicAccess(innerDynamicAccess);
+ MemberAccessExpressionNode result = new
MemberAccessExpressionNode(innerExpression, op, (ExpressionNodeBase)
rightOperandMemberAccess.getRightOperandNode());
+ return rewriteMemberAccess(result);
+ }
+ else if (rightOperand instanceof FunctionCallNode)
+ {
+ FunctionCallNode rightOperandFunctionCall = (FunctionCallNode)
rightOperand;
+ DynamicAccessNode innerDynamicAccess = new
DynamicAccessNode(leftOperand);
+
innerDynamicAccess.setRightOperandNode(rightOperandFunctionCall.getNameNode());
+ ExpressionNodeBase innerExpression =
rewriteDynamicAccess(innerDynamicAccess);
+ FunctionCallNode newFunctionCall = new
FunctionCallNode(innerExpression);
+ ContainerNode argumentsNode =
newFunctionCall.getArgumentsNode();
+ for (IExpressionNode argNode :
rightOperandFunctionCall.getArgumentNodes())
+ {
+ argumentsNode.addItem((ExpressionNodeBase) argNode);
+ }
+ return newFunctionCall;
+ }
+ return d;
+ }
}
protected final ExpressionNodeBase
transformNullConditional(ExpressionNodeBase l, ASToken op, ExpressionNodeBase r)
{
- return new NullConditionalTernaryOperatorNode(l, op, r,
getSyntaxProblems());
+ return new
NullConditionalTernaryOperatorNode(NullConditionalType.MEMBER_ACCESS, l, op, r,
getSyntaxProblems());
+ }
+
+ protected final ExpressionNodeBase
transformNullConditionalDynamicAccess(ExpressionNodeBase l, ASToken op,
DynamicAccessNode d, ExpressionNodeBase r)
+ {
+ return new
NullConditionalTernaryOperatorNode(NullConditionalType.DYNAMIC_ACCESS, l, op,
r, getSyntaxProblems());
}
}
diff --git a/compiler/src/test/java/as/ASNullConditionalOperatorTests.java
b/compiler/src/test/java/as/ASNullConditionalOperatorDynamicTests.java
similarity index 58%
copy from compiler/src/test/java/as/ASNullConditionalOperatorTests.java
copy to compiler/src/test/java/as/ASNullConditionalOperatorDynamicTests.java
index 160b02755..a3802052d 100644
--- a/compiler/src/test/java/as/ASNullConditionalOperatorTests.java
+++ b/compiler/src/test/java/as/ASNullConditionalOperatorDynamicTests.java
@@ -24,35 +24,8 @@ import java.io.File;
import org.junit.Assert;
import org.junit.Test;
-public class ASNullConditionalOperatorTests extends ASFeatureTestsBase
+public class ASNullConditionalOperatorDynamicTests extends ASFeatureTestsBase
{
- @Test
- public void testInvalidSyntaxBeforeDynamicAccess()
- {
- String[] testCode = new String[]
- {
- "var o:Object = {};",
- // the ?. operator before [] square brackets is not valid syntax
- "var result:* = o?.a?.[0];",
- };
- String source = getAS(new String[0], new String[0], testCode, new
String[0]);
-
- compileAndExpectErrors(source, false, false, false, new String[0],
"'[' is not allowed here\n");
- }
-
- @Test
- public void testInvalidSyntaxBeforeFunctionCall()
- {
- String[] testCode = new String[]
- {
- "var o:Object = {};",
- // the ?. operator before () parentheses is not valid syntax
- "var result:* = o?.a?.toString?.();",
- };
- String source = getAS(new String[0], new String[0], testCode, new
String[0]);
-
- compileAndExpectErrors(source, false, false, false, new String[0],
"'(' is not allowed here\n");
- }
// null is considered nullish
@Test
@@ -61,8 +34,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = null;",
- "var result:* = o?.toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['toString']();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -76,8 +49,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:* = undefined;",
- "var result:* = o?.toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['toString']();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -91,8 +64,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var b:Boolean = false;",
- "var result:* = b?.toString();",
- "assertEqual('null conditional', result, 'false');",
+ "var result:* = b?.['toString']();",
+ "assertEqual('dynamic null conditional', result, 'false');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -106,8 +79,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var n:Number = NaN;",
- "var result:* = n?.toString();",
- "assertEqual('null conditional', result, 'NaN');",
+ "var result:* = n?.['toString']();",
+ "assertEqual('dynamic null conditional', result, 'NaN');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -121,8 +94,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var n:Number = 0;",
- "var result:* = n?.toString();",
- "assertEqual('null conditional', result, '0');",
+ "var result:* = n?.['toString']();",
+ "assertEqual('dynamic null conditional', result, '0');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -136,8 +109,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var s:String = '';",
- "var result:* = s?.toString();",
- "assertEqual('null conditional', result, '');",
+ "var result:* = s?.['toString']();",
+ "assertEqual('dynamic null conditional', result, '');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -150,8 +123,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {};",
- "var result:* = o?.toString();",
- "assertEqual('null conditional', result, '[object Object]');",
+ "var result:* = o?.['toString']();",
+ "assertEqual('dynamic null conditional', result, '[object
Object]');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -164,8 +137,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: null};",
- "var result:* = o?.a?.toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a']?.['toString']();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -178,8 +151,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {};",
- "var result:* = o?.a?.toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a']?.['toString']();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -192,8 +165,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: undefined};",
- "var result:* = o?.a?.toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a']?.['toString']();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -206,8 +179,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: false};",
- "var result:* = o?.a?.toString();",
- "assertEqual('null conditional', result, 'false');",
+ "var result:* = o?.['a']?.['toString']();",
+ "assertEqual('dynamic null conditional', result, 'false');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -220,8 +193,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: 0};",
- "var result:* = o?.a?.toString();",
- "assertEqual('null conditional', result, '0');",
+ "var result:* = o?.['a']?.['toString']();",
+ "assertEqual('dynamic null conditional', result, '0');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -234,8 +207,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {}};",
- "var result:* = o?.a?.toString();",
- "assertEqual('null conditional', result, '[object Object]');",
+ "var result:* = o?.['a']?.['toString']();",
+ "assertEqual('dynamic null conditional', result, '[object
Object]');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -248,8 +221,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: null};",
- "var result:* = o?.a;",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a'];",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -262,8 +235,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {};",
- "var result:* = o?.a;",
- "assertEqual('null conditional', result, undefined);",
+ "var result:* = o?.['a'];",
+ "assertEqual('dynamic null conditional', result, undefined);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -276,8 +249,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: undefined};",
- "var result:* = o?.a;",
- "assertEqual('null conditional', result, undefined);",
+ "var result:* = o?.['a'];",
+ "assertEqual('dynamic null conditional', result, undefined);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -290,8 +263,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: false};",
- "var result:* = o?.a;",
- "assertEqual('null conditional', result, false);",
+ "var result:* = o?.['a'];",
+ "assertEqual('dynamic null conditional', result, false);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -304,8 +277,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: 0};",
- "var result:* = o?.a;",
- "assertEqual('null conditional', result, 0);",
+ "var result:* = o?.['a'];",
+ "assertEqual('dynamic null conditional', result, 0);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -319,8 +292,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
{
"var expected:Object = {};",
"var o:Object = {a: expected};",
- "var result:* = o?.a;",
- "assertEqual('null conditional', result, expected);",
+ "var result:* = o?.['a'];",
+ "assertEqual('dynamic null conditional', result, expected);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -333,8 +306,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {b: null}};",
- "var result:* = o?.a?.b;",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a']?.['b'];",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -347,8 +320,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {}};",
- "var result:* = o?.a?.b;",
- "assertEqual('null conditional', result, undefined);",
+ "var result:* = o?.['a']?.['b'];",
+ "assertEqual('dynamic null conditional', result, undefined);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -361,8 +334,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {b: undefined}};",
- "var result:* = o?.a?.b;",
- "assertEqual('null conditional', result, undefined);",
+ "var result:* = o?.['a']?.['b'];",
+ "assertEqual('dynamic null conditional', result, undefined);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -375,8 +348,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {b: false}};",
- "var result:* = o?.a?.b;",
- "assertEqual('null conditional', result, false);",
+ "var result:* = o?.['a']?.['b'];",
+ "assertEqual('dynamic null conditional', result, false);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -389,8 +362,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {b: 0}};",
- "var result:* = o?.a?.b;",
- "assertEqual('null conditional', result, 0);",
+ "var result:* = o?.['a']?.['b'];",
+ "assertEqual('dynamic null conditional', result, 0);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -404,8 +377,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
{
"var expected:Object = {};",
"var o:Object = {a: {b: expected}};",
- "var result:* = o?.a?.b;",
- "assertEqual('null conditional', result, expected);",
+ "var result:* = o?.['a']?.['b'];",
+ "assertEqual('dynamic null conditional', result, expected);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -418,8 +391,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = null;",
- "var result:* = o?.hasOwnProperty('a');",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['hasOwnProperty']('a');",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -432,8 +405,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:* = undefined;",
- "var result:* = o?.hasOwnProperty('a');",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['hasOwnProperty']('a');",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -446,8 +419,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var b:Boolean = false;",
- "var result:* = b?.hasOwnProperty('xyz');",
- "assertEqual('null conditional', result, false);",
+ "var result:* = b?.['hasOwnProperty']('xyz');",
+ "assertEqual('dynamic null conditional', result, false);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -460,8 +433,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var n:Number = 0;",
- "var result:* = n?.hasOwnProperty('xyz');",
- "assertEqual('null conditional', result, false);",
+ "var result:* = n?.['hasOwnProperty']('xyz');",
+ "assertEqual('dynamic null conditional', result, false);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -474,8 +447,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: 123};",
- "var result:* = o?.hasOwnProperty('a');",
- "assertEqual('null conditional', result, true);",
+ "var result:* = o?.['hasOwnProperty']('a');",
+ "assertEqual('dynamic null conditional', result, true);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -488,8 +461,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = null;",
- "var result:* = o?.a['b'];",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a']['b'];",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -502,8 +475,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:* = undefined;",
- "var result:* = o?.a['b'];",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a']['b'];",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -516,8 +489,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {}};",
- "var result:* = o?.a['b'];",
- "assertEqual('null conditional', result, undefined);",
+ "var result:* = o?.['a']['b'];",
+ "assertEqual('dynamic null conditional', result, undefined);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -530,8 +503,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {b: 2}};",
- "var result:* = o?.a['b'];",
- "assertEqual('null conditional', result, 2);",
+ "var result:* = o?.['a']['b'];",
+ "assertEqual('dynamic null conditional', result, 2);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -544,8 +517,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = null;",
- "var result:* = o?.a.b;",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a'].b;",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -558,8 +531,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:* = undefined;",
- "var result:* = o?.a.b;",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a'].b;",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -572,8 +545,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {}};",
- "var result:* = o?.a.b;",
- "assertEqual('null conditional', result, undefined);",
+ "var result:* = o?.['a'].b;",
+ "assertEqual('dynamic null conditional', result, undefined);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -586,8 +559,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {b: 2}};",
- "var result:* = o?.a.b;",
- "assertEqual('null conditional', result, 2);",
+ "var result:* = o?.['a'].b;",
+ "assertEqual('dynamic null conditional', result, 2);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -600,82 +573,82 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:* = {a: {b: {c: {d1: undefined, d2: null, d3: 0, d4:
false}}}};",
- "assertEqual('null conditional', o?.a?.b?.c?.d1, undefined);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d3, 0);",
- "assertEqual('null conditional', o?.a?.b?.c?.d4, false);",
- "assertEqual('null conditional', o?.a?.b?.c?.d1?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d3?.toString(),
'0');",
- "assertEqual('null conditional', o?.a?.b?.c?.d4?.toString(),
'false');",
- "assertEqual('null conditional', o?.a?.b?.c?.d1?.e, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2?.e, null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1'], undefined);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d3'], 0);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d4'], false);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d3']?.toString(), '0');",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d4']?.toString(), 'false');",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1']?.['e'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2']?.['e'], null);",
"o = {a: {b: {c: {}}}};",
- "assertEqual('null conditional', o?.a?.b?.c?.d1, undefined);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2, undefined);",
- "assertEqual('null conditional', o?.a?.b?.c?.d3, undefined);",
- "assertEqual('null conditional', o?.a?.b?.c?.d4, undefined);",
- "assertEqual('null conditional', o?.a?.b?.c?.d1?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d3?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d4?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d1?.e, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2?.e, null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1'], undefined);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2'], undefined);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d3'], undefined);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d4'], undefined);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d3']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d4']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1']?.['e'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2']?.['e'], null);",
"o = {a: {b: {}}};",
- "assertEqual('null conditional', o?.a?.b?.c?.d1, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d3, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d4, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d1?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d3?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d4?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d1?.e, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2?.e, null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d3'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d4'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d3']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d4']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1']?.['e'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2']?.['e'], null);",
"o = {a: {}};",
- "assertEqual('null conditional', o?.a?.b?.c?.d1, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d3, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d4, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d1?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d3?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d4?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d1?.e, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2?.e, null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d3'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d4'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d3']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d4']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1']?.['e'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2']?.['e'], null);",
"o = {};",
- "assertEqual('null conditional', o?.a?.b?.c?.d1, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d3, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d4, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d1?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d3?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d4?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d1?.e, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2?.e, null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d3'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d4'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d3']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d4']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1']?.['e'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2']?.['e'], null);",
"o = null;",
- "assertEqual('null conditional', o?.a?.b?.c?.d1, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d3, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d4, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d1?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d3?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d4?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d1?.e, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2?.e, null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d3'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d4'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d3']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d4']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1']?.['e'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2']?.['e'], null);",
"o = undefined;",
- "assertEqual('null conditional', o?.a?.b?.c?.d1, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d3, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d4, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d1?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d3?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d4?.toString(),
null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d1?.e, null);",
- "assertEqual('null conditional', o?.a?.b?.c?.d2?.e, null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d3'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d4'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d3']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d4']?.toString(), null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d1']?.['e'], null);",
+ "assertEqual('dynamic null conditional',
o?.['a']?.['b']?.['c']?.['d2']?.['e'], null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -692,7 +665,7 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
"if (o?.toString() === null) {",
" result = true;",
"}",
- "assertEqual('null conditional', result, true);",
+ "assertEqual('dynamic null conditional', result, true);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -706,10 +679,10 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
{
"var o:* = undefined;",
"var result:Boolean = false;",
- "if (o?.toString() === null) {",
+ "if (o?.['toString']() === null) {",
" result = true;",
"}",
- "assertEqual('null conditional', result, true);",
+ "assertEqual('dynamic null conditional', result, true);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -723,10 +696,10 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
{
"var b:Boolean = false;",
"var result:Boolean = false;",
- "if (b?.toString() === null) {",
+ "if (b?.['toString']() === null) {",
" result = true;",
"}",
- "assertEqual('null conditional', result, false);",
+ "assertEqual('dynamic null conditional', result, false);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -740,10 +713,10 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
{
"var n:Number = 0;",
"var result:Boolean = false;",
- "if (n?.toString() === null) {",
+ "if (n?.['toString']() === null) {",
" result = true;",
"}",
- "assertEqual('null conditional', result, false);",
+ "assertEqual('dynamic null conditional', result, false);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -757,10 +730,10 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
{
"var o:Object = {};",
"var result:Boolean = false;",
- "if (o?.toString() === null) {",
+ "if (o?.['toString']() === null) {",
" result = true;",
"}",
- "assertEqual('null conditional', result, false);",
+ "assertEqual('dynamic null conditional', result, false);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -773,8 +746,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = null;",
- "var result:* = o?.hasOwnProperty('a')?.toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['hasOwnProperty']('a')?.toString();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -787,8 +760,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:* = undefined;",
- "var result:* = o?.hasOwnProperty('a')?.toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['hasOwnProperty']('a')?.toString();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -801,8 +774,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var b:Boolean = false;",
- "var result:* = b?.hasOwnProperty('a')?.toString();",
- "assertEqual('null conditional', result, 'false');",
+ "var result:* = b?.['hasOwnProperty']('a')?.toString();",
+ "assertEqual('dynamic null conditional', result, 'false');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -815,8 +788,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var n:Number = 0;",
- "var result:* = n?.hasOwnProperty('a')?.toString();",
- "assertEqual('null conditional', result, 'false');",
+ "var result:* = n?.['hasOwnProperty']('a')?.toString();",
+ "assertEqual('dynamic null conditional', result, 'false');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -829,8 +802,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: 123};",
- "var result:* = o?.hasOwnProperty('a')?.toString();",
- "assertEqual('null conditional', result, 'true');",
+ "var result:* = o?.['hasOwnProperty']('a')?.toString();",
+ "assertEqual('dynamic null conditional', result, 'true');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -843,8 +816,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = null;",
- "var result:* = o?.a.b.c;",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a'].b.c;",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -857,8 +830,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:* = undefined;",
- "var result:* = o?.a.b.c;",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a'].b.c;",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -871,8 +844,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {b: {c: 123}}};",
- "var result:* = o?.a.b.c;",
- "assertEqual('null conditional', result, 123);",
+ "var result:* = o?.['a'].b.c;",
+ "assertEqual('dynamic null conditional', result, 123);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -885,8 +858,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = null;",
- "var result:* = o?.a.toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a'].toString();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -899,8 +872,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:* = undefined;",
- "var result:* = o?.a.toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a'].toString();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -913,8 +886,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {}};",
- "var result:* = o?.a.toString();",
- "assertEqual('null conditional', result, '[object Object]');",
+ "var result:* = o?.['a'].toString();",
+ "assertEqual('dynamic null conditional', result, '[object
Object]');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -927,8 +900,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = null;",
- "var result:* = o?.a.b['c'];",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a'].b['c'];",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -941,8 +914,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:* = undefined;",
- "var result:* = o?.a.b['c'];",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a'].b['c'];",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -955,8 +928,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {b: {c: 123}}};",
- "var result:* = o?.a.b['c'];",
- "assertEqual('null conditional', result, 123);",
+ "var result:* = o?.['a'].b['c'];",
+ "assertEqual('dynamic null conditional', result, 123);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -969,8 +942,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: null};",
- "var result:* = o.a?.toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o.a?.['toString']();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -983,8 +956,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {};",
- "var result:* = o.a?.toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o.a?.['toString']();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -997,8 +970,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: undefined};",
- "var result:* = o.a?.toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o.a?.['toString']();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1011,8 +984,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: false};",
- "var result:* = o.a?.toString();",
- "assertEqual('null conditional', result, 'false');",
+ "var result:* = o.a?.['toString']();",
+ "assertEqual('dynamic null conditional', result, 'false');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1025,8 +998,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: 0};",
- "var result:* = o.a?.toString();",
- "assertEqual('null conditional', result, '0');",
+ "var result:* = o.a?.['toString']();",
+ "assertEqual('dynamic null conditional', result, '0');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1039,8 +1012,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {}};",
- "var result:* = o.a?.toString();",
- "assertEqual('null conditional', result, '[object Object]');",
+ "var result:* = o.a?.['toString']();",
+ "assertEqual('dynamic null conditional', result, '[object
Object]');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1053,8 +1026,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = null;",
- "var result:* = o?.a['b']['c'];",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a']['b']['c'];",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1067,8 +1040,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:* = undefined;",
- "var result:* = o?.a['b']['c'];",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a']['b']['c'];",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1081,8 +1054,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {b: {c: 123}}};",
- "var result:* = o?.a['b']['c'];",
- "assertEqual('null conditional', result, 123);",
+ "var result:* = o?.['a']['b']['c'];",
+ "assertEqual('dynamic null conditional', result, 123);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1095,8 +1068,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = null;",
- "var result:* = o?.hasOwnProperty('a').toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['hasOwnProperty']('a').toString();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1109,8 +1082,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:* = undefined;",
- "var result:* = o?.hasOwnProperty('a').toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['hasOwnProperty']('a').toString();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1123,8 +1096,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var b:Boolean = false;",
- "var result:* = b?.hasOwnProperty('a').toString();",
- "assertEqual('null conditional', result, 'false');",
+ "var result:* = b?.['hasOwnProperty']('a').toString();",
+ "assertEqual('dynamic null conditional', result, 'false');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1137,8 +1110,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var n:Number = 0;",
- "var result:* = n?.hasOwnProperty('a').toString();",
- "assertEqual('null conditional', result, 'false');",
+ "var result:* = n?.['hasOwnProperty']('a').toString();",
+ "assertEqual('dynamic null conditional', result, 'false');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1151,8 +1124,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: 123};",
- "var result:* = o?.hasOwnProperty('a').toString();",
- "assertEqual('null conditional', result, 'true');",
+ "var result:* = o?.['hasOwnProperty']('a').toString();",
+ "assertEqual('dynamic null conditional', result, 'true');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1165,8 +1138,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = null;",
- "var result:* = o?.a['b'].toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a']['b'].toString();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1179,8 +1152,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:* = undefined;",
- "var result:* = o?.a['b'].toString();",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['a']['b'].toString();",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1193,8 +1166,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {a: {b: 123}};",
- "var result:* = o?.a['b'].toString();",
- "assertEqual('null conditional', result, '123');",
+ "var result:* = o?.['a']['b'].toString();",
+ "assertEqual('dynamic null conditional', result, '123');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1207,8 +1180,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = null;",
- "var result:* = o?.toString()['length'];",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['toString']()['length'];",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1221,8 +1194,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:* = undefined;",
- "var result:* = o?.toString()['length'];",
- "assertEqual('null conditional', result, null);",
+ "var result:* = o?.['toString']()['length'];",
+ "assertEqual('dynamic null conditional', result, null);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1235,8 +1208,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var b:Boolean = false;",
- "var result:* = b?.toString()['length'];",
- "assertEqual('null conditional', result, 5);",
+ "var result:* = b?.['toString']()['length'];",
+ "assertEqual('dynamic null conditional', result, 5);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1249,8 +1222,8 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var n:Number = 0;",
- "var result:* = n?.toString()['length'];",
- "assertEqual('null conditional', result, 1);",
+ "var result:* = n?.['toString']()['length'];",
+ "assertEqual('dynamic null conditional', result, 1);",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
@@ -1263,8 +1236,67 @@ public class ASNullConditionalOperatorTests extends
ASFeatureTestsBase
String[] testCode = new String[]
{
"var o:Object = {};",
- "var result:* = o?.toString()['length'];",
- "assertEqual('null conditional', result, '[object
Object]'.length);",
+ "var result:* = o?.['toString']()['length'];",
+ "assertEqual('dynamic null conditional', result, '[object
Object]'.length);",
+ };
+ String source = getAS(new String[0], new String[0], testCode, new
String[0]);
+
+ compileAndRun(source);
+ }
+
+ @Test
+ public void testStringFieldNameWithConcatenation()
+ {
+ String[] testCode = new String[]
+ {
+ "var n:Number = 123.4;",
+ "var result:* = n?.['to' + 'String']();",
+ "assertEqual('dynamic null conditional', result, '123.4');",
+ };
+ String source = getAS(new String[0], new String[0], testCode, new
String[0]);
+
+ compileAndRun(source);
+ }
+
+ @Test
+ public void testNestedStringFieldNameWithConcatenation()
+ {
+ String[] testCode = new String[]
+ {
+ "var o:Object = {a: {}}",
+ "var result:* = o?.['a']?.['to' + 'String']();",
+ "assertEqual('dynamic null conditional', result, '[object
Object]');",
+ };
+ String source = getAS(new String[0], new String[0], testCode, new
String[0]);
+
+ compileAndRun(source);
+ }
+
+ @Test
+ public void testVariableFieldName()
+ {
+ String[] testCode = new String[]
+ {
+ "var n:Number = 123.4;",
+ "var fieldName:String = 'toString';",
+ "var result:* = n?.[fieldName]();",
+ "assertEqual('dynamic null conditional', result, '123.4');",
+ };
+ String source = getAS(new String[0], new String[0], testCode, new
String[0]);
+
+ compileAndRun(source);
+ }
+
+ @Test
+ public void testVariableFieldNameWithConcatenation()
+ {
+ String[] testCode = new String[]
+ {
+ "var n:Number = 123.4;",
+ "var f1:String = 'to';",
+ "var f2:String = 'String';",
+ "var result:* = n?.[f1 + f2]();",
+ "assertEqual('dynamic null conditional', result, '123.4');",
};
String source = getAS(new String[0], new String[0], testCode, new
String[0]);
diff --git a/compiler/src/test/java/as/ASNullConditionalOperatorTests.java
b/compiler/src/test/java/as/ASNullConditionalOperatorTests.java
index 160b02755..9cd4dd2ad 100644
--- a/compiler/src/test/java/as/ASNullConditionalOperatorTests.java
+++ b/compiler/src/test/java/as/ASNullConditionalOperatorTests.java
@@ -26,20 +26,6 @@ import org.junit.Test;
public class ASNullConditionalOperatorTests extends ASFeatureTestsBase
{
- @Test
- public void testInvalidSyntaxBeforeDynamicAccess()
- {
- String[] testCode = new String[]
- {
- "var o:Object = {};",
- // the ?. operator before [] square brackets is not valid syntax
- "var result:* = o?.a?.[0];",
- };
- String source = getAS(new String[0], new String[0], testCode, new
String[0]);
-
- compileAndExpectErrors(source, false, false, false, new String[0],
"'[' is not allowed here\n");
- }
-
@Test
public void testInvalidSyntaxBeforeFunctionCall()
{