Skip to content

Commit

Permalink
Fix optional member call (#1233)
Browse files Browse the repository at this point in the history
  • Loading branch information
lahma committed Jul 19, 2022
1 parent c5cd625 commit 79fbf10
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
17 changes: 17 additions & 0 deletions Jint.Tests/Runtime/EngineTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2865,6 +2865,23 @@ public void ShouldGetZeroPrefixedNumericKeys()
Assert.Equal("[\"02100\"]", engine.Evaluate("JSON.stringify(Object.getOwnPropertyNames(testObj));").AsString());
}

[Fact]
public void ShouldAllowOptionalChainingForMemberCall()
{
var engine = new Engine();
const string Script = @"
const adventurer = { name: 'Alice', cat: { name: 'Dinah' } };
const dogName = adventurer.dog?.name;
const methodResult = adventurer.someNonExistentMethod?.();
return [ dogName, methodResult ];
";
var array = engine.Evaluate(Script).AsArray();

Assert.Equal(2L, array.Length);
Assert.True(array[0].IsUndefined());
Assert.True(array[1].IsUndefined());
}

private class Wrapper
{
public Testificate Test { get; set; }
Expand Down
11 changes: 8 additions & 3 deletions Jint/Runtime/Interpreter/Expressions/JintCallExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ private JsValue Call(EvaluationContext context)
var engine = context.Engine;
var func = engine.GetValue(reference, false);

if (func.IsNullOrUndefined() && _expression.IsOptional())
{
return Undefined.Instance;
}

if (reference is Reference referenceRecord
&& !referenceRecord.IsPropertyReference()
&& referenceRecord.GetReferencedName() == CommonProperties.Eval
Expand All @@ -134,7 +139,7 @@ private JsValue Call(EvaluationContext context)
var evalArg = argList[0];
var strictCaller = StrictModeScope.IsStrictModeCode;
var evalRealm = evalFunctionInstance._realm;
var direct = !((CallExpression) _expression).Optional;
var direct = !_expression.IsOptional();
var value = evalFunctionInstance.PerformEval(evalArg, evalRealm, strictCaller, direct);
engine._referencePool.Return(referenceRecord);
return value;
Expand Down Expand Up @@ -172,7 +177,7 @@ private JsValue EvaluateCall(EvaluationContext context, JsValue func, object ref
else
{
var refEnv = (EnvironmentRecord) baseValue;
thisValue = refEnv.WithBaseObject();
thisValue = refEnv.WithBaseObject();
}
}
}
Expand Down Expand Up @@ -257,4 +262,4 @@ private sealed class CachedArgumentsHolder
internal JsValue[] CachedArguments;
}
}
}
}

0 comments on commit 79fbf10

Please sign in to comment.