diff --git a/rhino/src/main/java/org/mozilla/javascript/CodeGenerator.java b/rhino/src/main/java/org/mozilla/javascript/CodeGenerator.java index 1ece422f8d..8d5db55760 100644 --- a/rhino/src/main/java/org/mozilla/javascript/CodeGenerator.java +++ b/rhino/src/main/java/org/mozilla/javascript/CodeGenerator.java @@ -600,7 +600,6 @@ private void visitExpression(Node node, int contextFlags) { case Token.REF_CALL: case Token.CALL: - case Token.CALL_OPTIONAL: case Token.NEW: { if (type == Token.NEW) { @@ -685,11 +684,6 @@ private void visitExpression(Node node, int contextFlags) { resolveForwardGoto(afterElseJumpStart); } break; - case Token.GETPROP_OPTIONAL: - visitExpression(child, 0); - child = child.getNext(); - addStringOp(type, child.getString()); - break; case Token.GETPROP: case Token.GETPROPNOWARN: @@ -966,7 +960,6 @@ private void visitExpression(Node node, int contextFlags) { visitArrayComprehension(node, child, child.getNext()); break; - case Token.REF_SPECIAL_OPTIONAL: case Token.REF_SPECIAL: visitExpression(child, 0); addStringOp(type, (String) node.getProp(Node.NAME_PROP)); @@ -1062,7 +1055,6 @@ private void generateCallFunAndThis(Node left) { stackChange(2); break; } - case Token.GETPROP_OPTIONAL: case Token.GETPROP: case Token.GETELEM: { @@ -1074,11 +1066,6 @@ private void generateCallFunAndThis(Node left) { // stack: ... target -> ... function thisObj addStringOp(Icode_PROP_AND_THIS, property); stackChange(1); - } else if (type == Token.GETPROP_OPTIONAL) { - String property = id.getString(); - // stack: ... target -> ... function thisObj - addStringOp(Icode_PROP_AND_THIS_OPTIONAL, property); - stackChange(1); } else { visitExpression(id, 0); // stack: ... target id -> ... function thisObj diff --git a/rhino/src/main/java/org/mozilla/javascript/IRFactory.java b/rhino/src/main/java/org/mozilla/javascript/IRFactory.java index 283d6f15ab..d06050d214 100644 --- a/rhino/src/main/java/org/mozilla/javascript/IRFactory.java +++ b/rhino/src/main/java/org/mozilla/javascript/IRFactory.java @@ -141,7 +141,6 @@ private Node transform(AstNode node) { return transformBlock(node); case Token.BREAK: return transformBreak((BreakStatement) node); - case Token.CALL_OPTIONAL: case Token.CALL: return transformFunctionCall((FunctionCall) node); case Token.CONTINUE: @@ -162,7 +161,6 @@ private Node transform(AstNode node) { return transformGenExpr((GeneratorExpression) node); case Token.GETELEM: return transformElementGet((ElementGet) node); - case Token.QUESTION_DOT: case Token.GETPROP: return transformPropertyGet((PropertyGet) node); case Token.HOOK: @@ -349,8 +347,7 @@ private Node arrayCompTransformHelper(ArrayComprehension node, String arrayName) Node call = createCallOrNew( Token.CALL, - createPropertyGet( - parser.createName(arrayName), null, "push", 0, node.type)); + createPropertyGet(parser.createName(arrayName), null, "push", 0)); Node body = new Node(Token.EXPR_VOID, call, lineno); @@ -644,10 +641,7 @@ private Node transformFunction(FunctionNode fn) { } private Node transformFunctionCall(FunctionCall node) { - Node call = - createCallOrNew( - node.type == Token.CALL_OPTIONAL ? Token.CALL_OPTIONAL : Token.CALL, - transform(node.getTarget())); + Node call = createCallOrNew(Token.CALL, transform(node.getTarget())); call.setLineno(node.getLineno()); List args = node.getArguments(); for (int i = 0; i < args.size(); i++) { @@ -944,7 +938,7 @@ private Node transformComputedPropertyKey(ComputedPropertyKey node) { private Node transformPropertyGet(PropertyGet node) { Node target = transform(node.getTarget()); String name = node.getProperty().getIdentifier(); - return createPropertyGet(target, null, name, 0, node.type); + return createPropertyGet(target, null, name, 0); } private Node transformTemplateLiteral(TemplateLiteral node) { @@ -1268,7 +1262,7 @@ private Node transformXmlRef(Node pn, XmlRef node, int memberTypeFlags) { String ns = namespace != null ? namespace.getIdentifier() : null; if (node instanceof XmlPropRef) { String name = ((XmlPropRef) node).getPropName().getIdentifier(); - return createPropertyGet(pn, ns, name, memberTypeFlags, node.type); + return createPropertyGet(pn, ns, name, memberTypeFlags); } Node expr = transform(((XmlElemRef) node).getExpression()); return createElementGet(pn, ns, expr, memberTypeFlags); @@ -1903,27 +1897,19 @@ private static Node createIncDec(int nodeType, boolean post, Node child) { } private Node createPropertyGet( - Node target, String namespace, String name, int memberTypeFlags, int type) { + Node target, String namespace, String name, int memberTypeFlags) { if (namespace == null && memberTypeFlags == 0) { if (target == null) { return parser.createName(name); } parser.checkActivationName(name, Token.GETPROP); if (ScriptRuntime.isSpecialProperty(name)) { - Node ref = - new Node( - type == Token.QUESTION_DOT - ? Token.REF_SPECIAL_OPTIONAL - : Token.REF_SPECIAL, - target); + Node ref = new Node(Token.REF_SPECIAL, target); ref.putProp(Node.NAME_PROP, name); return new Node(Token.GET_REF, ref); } - return new Node( - type == Token.QUESTION_DOT ? Token.GETPROP_OPTIONAL : Token.GETPROP, - target, - Node.newString(name)); + return new Node(Token.GETPROP, target, Node.newString(name)); } Node elem = Node.newString(name); memberTypeFlags |= Node.PROPERTY_FLAG; diff --git a/rhino/src/main/java/org/mozilla/javascript/Icode.java b/rhino/src/main/java/org/mozilla/javascript/Icode.java index 13662a356c..31d1b72343 100644 --- a/rhino/src/main/java/org/mozilla/javascript/Icode.java +++ b/rhino/src/main/java/org/mozilla/javascript/Icode.java @@ -142,9 +142,8 @@ abstract class Icode { Icode_TEMPLATE_LITERAL_CALLSITE = Icode_REG_BIGINT4 - 1, Icode_LITERAL_KEYS = Icode_TEMPLATE_LITERAL_CALLSITE - 1, Icode_LITERAL_KEY_SET = Icode_LITERAL_KEYS - 1, - Icode_PROP_AND_THIS_OPTIONAL = Icode_LITERAL_KEY_SET - 1, // Last icode - MIN_ICODE = Icode_PROP_AND_THIS_OPTIONAL; + MIN_ICODE = Icode_LITERAL_KEY_SET; static String bytecodeName(int bytecode) { if (!validBytecode(bytecode)) { @@ -190,8 +189,6 @@ static String bytecodeName(int bytecode) { return "NAME_AND_THIS"; case Icode_PROP_AND_THIS: return "PROP_AND_THIS"; - case Icode_PROP_AND_THIS_OPTIONAL: - return "PROP_AND_THIS_OPTIONAL"; case Icode_ELEM_AND_THIS: return "ELEM_AND_THIS"; case Icode_VALUE_AND_THIS: diff --git a/rhino/src/main/java/org/mozilla/javascript/Interpreter.java b/rhino/src/main/java/org/mozilla/javascript/Interpreter.java index 29d486b444..4141f5b28b 100644 --- a/rhino/src/main/java/org/mozilla/javascript/Interpreter.java +++ b/rhino/src/main/java/org/mozilla/javascript/Interpreter.java @@ -1622,16 +1622,6 @@ private static Object interpretLoop(Context cx, CallFrame frame, Object throwabl lhs, stringReg, cx, frame.scope); continue Loop; } - case Token.GETPROP_OPTIONAL: - { - Object lhs = stack[stackTop]; - if (lhs == DBL_MRK) - lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]); - stack[stackTop] = - ScriptRuntime.getObjectPropOptional( - lhs, stringReg, cx, frame.scope); - continue Loop; - } case Token.SETPROP: { Object rhs = stack[stackTop]; @@ -1728,19 +1718,6 @@ private static Object interpretLoop(Context cx, CallFrame frame, Object throwabl ++stackTop; stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx); continue Loop; - case Icode_PROP_AND_THIS_OPTIONAL: - { - Object obj = stack[stackTop]; - if (obj == DBL_MRK) - obj = ScriptRuntime.wrapNumber(sDbl[stackTop]); - // stringReg: property - stack[stackTop] = - ScriptRuntime.getPropFunctionAndThisOptional( - obj, stringReg, cx, frame.scope); - ++stackTop; - stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx); - continue Loop; - } case Icode_PROP_AND_THIS: { Object obj = stack[stackTop]; @@ -1791,7 +1768,6 @@ private static Object interpretLoop(Context cx, CallFrame frame, Object throwabl continue Loop; } case Token.CALL: - case Token.CALL_OPTIONAL: case Icode_TAIL_CALL: case Token.REF_CALL: { @@ -2308,17 +2284,6 @@ private static Object interpretLoop(Context cx, CallFrame frame, Object throwabl obj, stringReg, cx, frame.scope); continue Loop; } - case Token.REF_SPECIAL_OPTIONAL: - { - // stringReg: name of special property - Object obj = stack[stackTop]; - if (obj == DBL_MRK) - obj = ScriptRuntime.wrapNumber(sDbl[stackTop]); - stack[stackTop] = - ScriptRuntime.optionalSpecialRef( - obj, stringReg, cx, frame.scope); - continue Loop; - } case Token.REF_MEMBER: { // indexReg: flags diff --git a/rhino/src/main/java/org/mozilla/javascript/Parser.java b/rhino/src/main/java/org/mozilla/javascript/Parser.java index 27ff2e8afb..edd1d2c4aa 100644 --- a/rhino/src/main/java/org/mozilla/javascript/Parser.java +++ b/rhino/src/main/java/org/mozilla/javascript/Parser.java @@ -2439,8 +2439,6 @@ private AstNode assignExpr() throws IOException { markDestructuring(pn); int opPos = ts.tokenBeg; - if (isNotValidSimpleAssignmentTarget(pn)) - reportError("msg.syntax.invalid.assignment.lhs"); pn = new Assignment(tt, pn, assignExpr(), opPos); @@ -2463,12 +2461,6 @@ private AstNode assignExpr() throws IOException { return pn; } - private static boolean isNotValidSimpleAssignmentTarget(AstNode pn) { - if (pn.getType() == Token.GETPROP) - return isNotValidSimpleAssignmentTarget(((PropertyGet) pn).getLeft()); - return pn.getType() == Token.QUESTION_DOT; - } - private AstNode condExpr() throws IOException { AstNode pn = nullishCoalescingExpr(); if (matchToken(Token.HOOK, true)) { @@ -2895,7 +2887,6 @@ private AstNode memberExprTail(boolean allowCallSyntax, AstNode pn) throws IOExc int tt = peekToken(); switch (tt) { case Token.DOT: - case Token.QUESTION_DOT: case Token.DOTDOT: lineno = ts.lineno; pn = propertyAccess(tt, pn); @@ -3026,27 +3017,6 @@ private AstNode propertyAccess(int tt, AstNode pn) throws IOException { AstNode ref = null; // right side of . or .. operator int token = nextToken(); - if (token == Token.LP && tt == Token.QUESTION_DOT) { - // optional chaining operator method call, o.func?.() - var pos = pn.getPosition(); - pn.setType(Token.QUESTION_DOT); - consumeToken(); - checkCallRequiresActivation(pn); - FunctionCall f = new FunctionCall(pos); - f.setTarget(pn); - // Assign the line number for the function call to where - // the paren appeared, not where the name expression started. - f.setLineno(lineno); - f.setLp(ts.tokenBeg - pos); - List args = argumentList(); - if (args != null && args.size() > ARGC_LIMIT) reportError("msg.too.many.function.args"); - f.setArguments(args); - f.setRp(ts.tokenBeg - pos); - f.setLength(ts.tokenEnd - pos); - f.setType(Token.CALL_OPTIONAL); - return f; - } - switch (token) { case Token.THROW: // needed for generator.throw(); @@ -3102,10 +3072,6 @@ private AstNode propertyAccess(int tt, AstNode pn) throws IOException { result.setLineno(pn.getLineno()); result.setLeft(pn); // do this after setting position result.setRight(ref); - - if (tt == Token.QUESTION_DOT && result instanceof PropertyGet) { - result.setType(Token.QUESTION_DOT); - } return result; } diff --git a/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java b/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java index 9dd071c368..b4ca8d8fbb 100644 --- a/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java +++ b/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java @@ -1738,22 +1738,6 @@ public static Object getObjectProp(Object obj, String property, Context cx, Scri return getObjectProp(sobj, property, cx); } - public static Object getObjectPropOptional( - Object obj, String property, Context cx, Scriptable scope) { - if (obj == null || Undefined.isUndefined(obj)) { - return Undefined.instance; - } - return getObjectProp(obj, property, cx, scope); - } - - public static Object getObjectPropOptional( - Scriptable obj, String property, Context cx, Scriptable scope) { - if (obj == null || Undefined.isUndefined(obj)) { - return Undefined.instance; - } - return getObjectProp(obj, property, cx); - } - public static Object getObjectProp(Scriptable obj, String property, Context cx) { Object result = ScriptableObject.getProperty(obj, property); @@ -1992,11 +1976,6 @@ public static Ref specialRef(Object obj, String specialProperty, Context cx, Scr return SpecialRef.createSpecial(cx, scope, obj, specialProperty); } - public static Ref optionalSpecialRef( - Object obj, String specialProperty, Context cx, Scriptable scope) { - return SpecialOptionalRef.create(cx, scope, obj, specialProperty); - } - /** * @deprecated Use {@link #delete(Object, Object, Context, Scriptable, boolean)} instead */ @@ -2649,20 +2628,6 @@ public static Callable getElemFunctionAndThis( return (Callable) value; } - public static Callable getPropFunctionAndThisOptional( - Object obj, String property, Context cx, Scriptable scope) { - - Scriptable thisObj = toObjectOrNull(cx, obj, scope); - if (thisObj == null) { - throw undefCallError(obj, property); - } - - Object value = ScriptableObject.getProperty(thisObj, property); - if (Scriptable.NOT_FOUND == value || Undefined.isUndefined(value) || value == null) - return (cx1, scope1, thisObj2, args) -> Undefined.instance; - return getPropFunctionAndThisHelper(obj, property, cx, thisObj); - } - /** * Prepare for calling obj.property(...): return function corresponding to obj.property and make * obj properly converted to Scriptable available as ScriptRuntime.lastStoredScriptable() for diff --git a/rhino/src/main/java/org/mozilla/javascript/SpecialOptionalRef.java b/rhino/src/main/java/org/mozilla/javascript/SpecialOptionalRef.java deleted file mode 100644 index d2f88cd1ee..0000000000 --- a/rhino/src/main/java/org/mozilla/javascript/SpecialOptionalRef.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.mozilla.javascript; - -class SpecialOptionalRef extends Ref { - Ref specialRef; - - private SpecialOptionalRef(Ref specialRef) { - this.specialRef = specialRef; - } - - public static Ref create(Context cx, Scriptable scope, Object object, String name) { - Scriptable target = ScriptRuntime.toObjectOrNull(cx, object, scope); - if (target != null && target != Undefined.instance) { - return new SpecialOptionalRef(SpecialRef.createSpecial(cx, scope, object, name)); - } - return new SpecialOptionalRef(null); - } - - @Override - public Object get(Context cx) { - if (specialRef == null) return Undefined.instance; - return specialRef.get(cx); - } - - @Deprecated - @Override - public Object set(Context cx, Object value) { - throw new IllegalStateException(); - } -} diff --git a/rhino/src/main/java/org/mozilla/javascript/Token.java b/rhino/src/main/java/org/mozilla/javascript/Token.java index 5218c13760..57bb68ce56 100644 --- a/rhino/src/main/java/org/mozilla/javascript/Token.java +++ b/rhino/src/main/java/org/mozilla/javascript/Token.java @@ -121,13 +121,10 @@ public static enum CommentType { REF_NS_MEMBER = REF_MEMBER + 1, // Reference for x.ns::y, x..ns::y etc. REF_NAME = REF_NS_MEMBER + 1, // Reference for @y, @[y] etc. REF_NS_NAME = REF_NAME + 1, // Reference for ns::y, @ns::y@[y] etc. - BIGINT = REF_NS_NAME + 1, // ES2020 BigInt - GETPROP_OPTIONAL = BIGINT + 1, - REF_SPECIAL_OPTIONAL = GETPROP_OPTIONAL + 1, - CALL_OPTIONAL = REF_SPECIAL_OPTIONAL + 1; + BIGINT = REF_NS_NAME + 1; // ES2020 BigInt // End of interpreter bytecodes - public static final int LAST_BYTECODE_TOKEN = CALL_OPTIONAL, + public static final int LAST_BYTECODE_TOKEN = BIGINT, TRY = LAST_BYTECODE_TOKEN + 1, SEMI = TRY + 1, // semicolon LB = SEMI + 1, // left and right brackets @@ -235,8 +232,7 @@ public static enum CommentType { TEMPLATE_LITERAL_SUBST + 1, // template literal - tagged/handler DOTDOTDOT = TAGGED_TEMPLATE_LITERAL + 1, // spread/rest ... NULLISH_COALESCING = DOTDOTDOT + 1, // nullish coalescing (??) - QUESTION_DOT = NULLISH_COALESCING + 1, // optional chaining operator (?.) - LAST_TOKEN = QUESTION_DOT; + LAST_TOKEN = NULLISH_COALESCING; /** * Returns a name for the token. If Rhino is compiled with certain hardcoded debugging flags in @@ -609,12 +605,6 @@ public static String typeToName(int token) { return "YIELD_STAR"; case BIGINT: return "BIGINT"; - case GETPROP_OPTIONAL: - return "GETPROP_OPTIONAL"; - case REF_SPECIAL_OPTIONAL: - return "REF_SPECIAL_OPTIONAL"; - case CALL_OPTIONAL: - return "CALL_OPTIONAL"; case TEMPLATE_LITERAL: return "TEMPLATE_LITERAL"; case TEMPLATE_CHARS: @@ -625,8 +615,6 @@ public static String typeToName(int token) { return "TAGGED_TEMPLATE_LITERAL"; case DOTDOTDOT: return "DOTDOTDOT"; - case QUESTION_DOT: - return "DOT_QUESTION"; } // Token without name diff --git a/rhino/src/main/java/org/mozilla/javascript/TokenStream.java b/rhino/src/main/java/org/mozilla/javascript/TokenStream.java index adb4789be7..e8df53d648 100644 --- a/rhino/src/main/java/org/mozilla/javascript/TokenStream.java +++ b/rhino/src/main/java/org/mozilla/javascript/TokenStream.java @@ -1147,9 +1147,6 @@ && peekChar() == '!' case ',': return Token.COMMA; case '?': - if (matchChar('.')) { - return Token.QUESTION_DOT; - } if (matchChar('?')) { return Token.NULLISH_COALESCING; } diff --git a/rhino/src/main/java/org/mozilla/javascript/ast/AstNode.java b/rhino/src/main/java/org/mozilla/javascript/ast/AstNode.java index ea5c6f3fd5..862b434de2 100644 --- a/rhino/src/main/java/org/mozilla/javascript/ast/AstNode.java +++ b/rhino/src/main/java/org/mozilla/javascript/ast/AstNode.java @@ -126,7 +126,6 @@ public abstract class AstNode extends Node implements Comparable { operatorNames.put(Token.ASSIGN_BITXOR, "^="); operatorNames.put(Token.ASSIGN_EXP, "**="); operatorNames.put(Token.VOID, "void"); - operatorNames.put(Token.QUESTION_DOT, "?."); StringBuilder sb = new StringBuilder(); INDENTATIONS[0] = sb.toString(); diff --git a/rhino/src/main/java/org/mozilla/javascript/optimizer/BodyCodegen.java b/rhino/src/main/java/org/mozilla/javascript/optimizer/BodyCodegen.java index a18e5a8ca4..f091bd13bb 100644 --- a/rhino/src/main/java/org/mozilla/javascript/optimizer/BodyCodegen.java +++ b/rhino/src/main/java/org/mozilla/javascript/optimizer/BodyCodegen.java @@ -991,7 +991,6 @@ private void generateExpression(Node node, Node parent) { break; case Token.CALL: - case Token.CALL_OPTIONAL: case Token.NEW: { int specialType = node.getIntProp(Node.SPECIALCALL_PROP, Node.NON_SPECIALCALL); @@ -1001,7 +1000,7 @@ private void generateExpression(Node node, Node parent) { if (target != null) { visitOptimizedCall(node, target, type, child); - } else if (type == Token.CALL || type == Token.CALL_OPTIONAL) { + } else if (type == Token.CALL) { visitStandardCall(node, child); } else { visitStandardNew(node, child); @@ -1354,9 +1353,6 @@ private void generateExpression(Node node, Node parent) { case Token.GETPROPNOWARN: visitGetProp(node, child); break; - case Token.GETPROP_OPTIONAL: - visitGetPropOptional(node, child); - break; case Token.GETELEM: generateExpression(child, node); // object @@ -1499,22 +1495,6 @@ private void generateExpression(Node node, Node parent) { + ")Lorg/mozilla/javascript/Ref;"); } break; - case Token.REF_SPECIAL_OPTIONAL: - { - String special = (String) node.getProp(Node.NAME_PROP); - generateExpression(child, node); - cfw.addPush(special); - cfw.addALoad(contextLocal); - cfw.addALoad(variableObjectLocal); - addScriptRuntimeInvoke( - "optionalSpecialRef", - "(Ljava/lang/Object;" - + "Ljava/lang/String;" - + "Lorg/mozilla/javascript/Context;" - + "Lorg/mozilla/javascript/Scriptable;" - + ")Lorg/mozilla/javascript/Ref;"); - } - break; case Token.REF_MEMBER: case Token.REF_NS_MEMBER: case Token.REF_NAME: @@ -2306,8 +2286,7 @@ private void visitSpecialCall(Node node, int type, int specialType, Node child) } private void visitStandardCall(Node node, Node child) { - if (node.getType() != Token.CALL && node.getType() != Token.CALL_OPTIONAL) - throw Codegen.badTree(); + if (node.getType() != Token.CALL) throw Codegen.badTree(); Node firstArgChild = child.getNext(); int childType = child.getType(); @@ -2326,14 +2305,14 @@ private void visitStandardCall(Node node, Node child) { + "Lorg/mozilla/javascript/Context;" + "Lorg/mozilla/javascript/Scriptable;" + ")Ljava/lang/Object;"; - } else if (childType == Token.GETPROP || childType == Token.GETPROP_OPTIONAL) { + } else if (childType == Token.GETPROP) { // x.name() call Node propTarget = child.getFirstChild(); generateExpression(propTarget, node); Node id = propTarget.getNext(); String property = id.getString(); cfw.addPush(property); - methodName = childType == Token.GETPROP ? "callProp0" : "callProp0Optional"; + methodName = "callProp0"; signature = "(Ljava/lang/Object;" + "Ljava/lang/String;" @@ -4004,36 +3983,6 @@ private void visitGetProp(Node node, Node child) { } } - private void visitGetPropOptional(Node node, Node child) { - generateExpression(child, node); // object - Node nameChild = child.getNext(); - generateExpression(nameChild, node); // the name - /* - for 'this.foo' we call getObjectPropOptional(Scriptable...) which can - skip some casting overhead. - */ - int childType = child.getType(); - if (childType == Token.THIS && nameChild.getType() == Token.STRING) { - cfw.addALoad(contextLocal); - addScriptRuntimeInvoke( - "getObjectPropOptional", - "(Lorg/mozilla/javascript/Scriptable;" - + "Ljava/lang/String;" - + "Lorg/mozilla/javascript/Context;" - + ")Ljava/lang/Object;"); - } else { - cfw.addALoad(contextLocal); - cfw.addALoad(variableObjectLocal); - addScriptRuntimeInvoke( - "getObjectPropOptional", - "(Ljava/lang/Object;" - + "Ljava/lang/String;" - + "Lorg/mozilla/javascript/Context;" - + "Lorg/mozilla/javascript/Scriptable;" - + ")Ljava/lang/Object;"); - } - } - private void visitSetProp(int type, Node node, Node child) { generateExpression(child, node); child = child.getNext(); diff --git a/rhino/src/main/java/org/mozilla/javascript/optimizer/OptRuntime.java b/rhino/src/main/java/org/mozilla/javascript/optimizer/OptRuntime.java index 7d5688cbf1..80ae3ae1bd 100644 --- a/rhino/src/main/java/org/mozilla/javascript/optimizer/OptRuntime.java +++ b/rhino/src/main/java/org/mozilla/javascript/optimizer/OptRuntime.java @@ -73,14 +73,6 @@ public static Object callProp0(Object value, String property, Context cx, Script return f.call(cx, scope, thisObj, ScriptRuntime.emptyArgs); } - /** Implement x?.property() call shrinking optimizer code. */ - public static Object callProp0Optional( - Object value, String property, Context cx, Scriptable scope) { - Callable f = getPropFunctionAndThisOptional(value, property, cx, scope); - Scriptable thisObj = lastStoredScriptable(cx); - return f.call(cx, scope, thisObj, ScriptRuntime.emptyArgs); - } - public static Object add(Object val1, double val2, Context cx) { if (val1 instanceof Double) { return ((Double) val1) + val2; diff --git a/rhino/src/main/resources/org/mozilla/javascript/resources/Messages.properties b/rhino/src/main/resources/org/mozilla/javascript/resources/Messages.properties index b3fcce45b9..230a7aa0af 100644 --- a/rhino/src/main/resources/org/mozilla/javascript/resources/Messages.properties +++ b/rhino/src/main/resources/org/mozilla/javascript/resources/Messages.properties @@ -483,9 +483,6 @@ msg.generator.returns =\ msg.anon.generator.returns =\ anonymous generator function returns a value -msg.syntax.invalid.assignment.lhs =\ - syntax error: Invalid left-hand side in assignment - msg.syntax =\ syntax error diff --git a/rhino/src/test/java/org/mozilla/javascript/tests/OptionalChainingOperatorTests.java b/rhino/src/test/java/org/mozilla/javascript/tests/OptionalChainingOperatorTests.java deleted file mode 100644 index 482b64a97c..0000000000 --- a/rhino/src/test/java/org/mozilla/javascript/tests/OptionalChainingOperatorTests.java +++ /dev/null @@ -1,129 +0,0 @@ -package org.mozilla.javascript.tests; - -import static org.junit.Assert.assertEquals; - -import org.junit.Assert; -import org.junit.Test; -import org.mozilla.javascript.EvaluatorException; -import org.mozilla.javascript.Scriptable; -import org.mozilla.javascript.Undefined; - -public class OptionalChainingOperatorTests { - - @Test - public void testOptionalChainingOperator() { - - Utils.runWithAllOptimizationLevels( - cx -> { - String sourceName = "optionalChainingOperator"; - Scriptable scope = cx.initStandardObjects(); - assertEquals( - Undefined.instance, - cx.evaluateString( - scope, "var nul = null; nul?.a", sourceName, 1, null)); - - String script = " var a = {name: 'val'}; a.outerProp?.innerProp"; - assertEquals( - Undefined.instance, - cx.evaluateString(scope, script, sourceName, 1, null)); - - String script2 = - " var a = {outerProp: {innerProp: 'val' } }; a.outerProp?.innerProp"; - assertEquals("val", cx.evaluateString(scope, script2, sourceName, 1, null)); - - String script3 = - "var a = {outerProp: {innerProp: { innerInnerProp: {name: 'val' } } } }; " - + "a.outerProp?.innerProp?.missingProp?.name"; - assertEquals( - Undefined.instance, - cx.evaluateString(scope, script3, sourceName, 1, null)); - - String script4 = - " var a = {outerProp: {innerProp: { innerInnerProp: {name: 'val' } } } }; " - + "a.outerProp?.innerProp?.innerInnerProp?.name"; - assertEquals("val", cx.evaluateString(scope, script4, sourceName, 1, null)); - - String script5 = " var a = {}; a.someNonExistentMethod?.()"; - assertEquals( - Undefined.instance, - cx.evaluateString(scope, script5, sourceName, 1, null)); - assertEquals( - Undefined.instance, - cx.evaluateString( - scope, - "function fn3 () {\n" - + " return () => {\n" - + " return null;\n" - + " };\n" - + "}" - + " fn3()()?.a", - sourceName, - 1, - null)); - assertEquals( - Undefined.instance, - cx.evaluateString( - scope, - " var a = {}; a.someNonExistentMethod?.()", - sourceName, - 1, - null)); - - // SpecialRef and Optional Chaining operator - assertEquals( - Undefined.instance, - cx.evaluateString( - scope, " var a = null; a?.__proto__", sourceName, 1, null)); - assertEquals( - Undefined.instance, - cx.evaluateString(scope, "a?.__proto__", sourceName, 1, null)); - - assertEquals( - Undefined.instance, - cx.evaluateString(scope, "a?.__parent__", sourceName, 1, null)); - - var e = - Assert.assertThrows( - EvaluatorException.class, - () -> - cx.evaluateString( - scope, - "var y = {};\n" - + "0, { x: y?.z = 42 } = { x: 23 };", - sourceName, - 1, - null)); - Assert.assertTrue( - e.getMessage().contains("Invalid left-hand side in assignment")); - - e = - Assert.assertThrows( - EvaluatorException.class, - () -> - cx.evaluateString( - scope, "y?.z = 42", sourceName, 1, null)); - Assert.assertTrue( - e.getMessage().contains("Invalid left-hand side in assignment")); - - e = - Assert.assertThrows( - EvaluatorException.class, - () -> - cx.evaluateString( - scope, "y.z?.x = 42", sourceName, 1, null)); - Assert.assertTrue( - e.getMessage().contains("Invalid left-hand side in assignment")); - - e = - Assert.assertThrows( - EvaluatorException.class, - () -> - cx.evaluateString( - scope, "y?.z.x = 42", sourceName, 1, null)); - Assert.assertTrue( - e.getMessage().contains("Invalid left-hand side in assignment")); - - return null; - }); - } -} diff --git a/tests/testsrc/test262.properties b/tests/testsrc/test262.properties index 598762f67c..57c5324e89 100644 --- a/tests/testsrc/test262.properties +++ b/tests/testsrc/test262.properties @@ -5866,15 +5866,13 @@ language/expressions/object 809/1169 (69.2%) language/expressions/optional-chaining 25/38 (65.79%) call-expression.js - early-errors-tail-position-null-optchain-template-string.js - early-errors-tail-position-null-optchain-template-string-esi.js - early-errors-tail-position-optchain-template-string.js - early-errors-tail-position-optchain-template-string-esi.js eval-optional-call.js + iteration-statement-do.js iteration-statement-for.js iteration-statement-for-await-of.js {unsupported: [async]} iteration-statement-for-in.js iteration-statement-for-of-type-error.js + iteration-statement-while.js member-expression.js member-expression-async-identifier.js {unsupported: [async]} member-expression-async-literal.js {unsupported: [async]} @@ -5887,7 +5885,9 @@ language/expressions/optional-chaining 25/38 (65.79%) optional-chain-expression-optional-expression.js optional-chain-prod-arguments.js optional-chain-prod-expression.js - punctuator-decimal-lookahead.js + optional-chain-prod-identifiername.js + optional-expression.js + runtime-semantics-evaluation.js short-circuiting.js super-property-optional-call.js