JS: fix parsing of wrong delete operation in js function.

See KT-15294
This commit is contained in:
Alexey Andreev
2017-09-26 19:26:16 +03:00
parent bad50c03a7
commit 0269c3309a
6 changed files with 33 additions and 5 deletions
@@ -0,0 +1,8 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun foo(x: Any) {
js("delete x.foo;")
js("delete x['bar'];")
js("delete x.baz<!JSCODE_ERROR!>()<!>;")
js("delete <!JSCODE_ERROR!>this<!>;")
}
@@ -0,0 +1,3 @@
package
public fun foo(/*0*/ x: kotlin.Any): kotlin.Unit
@@ -368,6 +368,12 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
doTest(fileName);
}
@TestMetadata("deleteOperation.kt")
public void testDeleteOperation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/jsCode/deleteOperation.kt");
doTest(fileName);
}
@TestMetadata("error.kt")
public void testError() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/jsCode/error.kt");
@@ -392,9 +392,7 @@ public class JsAstMapper {
JsUnaryOperator.DELETE, to);
}
else {
throw createParserException(
"'delete' can only operate on property names and array elements",
from);
return new JsNullLiteral();
}
}
@@ -81,5 +81,7 @@ public class MessagesBundle extends ListResourceBundle {
{"msg.catch.unreachable", "any catch clauses following an unqualified catch are unreachable"},
{"msg.no.name.after.dot", "missing name after . operator"},
{"msg.jsni.expected.identifier", "Expected an identifier in JSNI reference"},
{"msg.wrong.delete argument", "Wrong argument for ''delete'' operation. " +
"Must be either property reference or array subscript expression."},
};
}
@@ -37,6 +37,8 @@
package com.google.gwt.dev.js.rhino;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -890,8 +892,13 @@ public class Parser {
case TokenStream.DEC:
return nf.createUnary(tt, TokenStream.PRE, memberExpr(ts, true), position);
case TokenStream.DELPROP:
return nf.createUnary(TokenStream.DELPROP, unaryExpr(ts), position);
case TokenStream.DELPROP: {
Node argument = unaryExpr(ts);
if (!isValidDeleteArgument(argument)) {
Context.reportError("msg.wrong.delete argument", argument.getPosition(), ts.lastPosition);
}
return nf.createUnary(TokenStream.DELPROP, argument, position);
}
case TokenStream.ERROR:
break;
@@ -922,6 +929,10 @@ public class Parser {
return nf.createName("err", position); // Only reached on error. Try to continue.
}
private static boolean isValidDeleteArgument(@NotNull Node node) {
return node.type == TokenStream.GETPROP || node.type == TokenStream.GETELEM;
}
private Node argumentList(TokenStream ts, Node listNode) throws IOException, JavaScriptException {
boolean matched;
ts.flags |= TokenStream.TSF_REGEXP;