JS: fix parsing of wrong delete operation in js function.
See KT-15294
This commit is contained in:
@@ -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);
|
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")
|
@TestMetadata("error.kt")
|
||||||
public void testError() throws Exception {
|
public void testError() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/jsCode/error.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/jsCode/error.kt");
|
||||||
|
|||||||
@@ -392,9 +392,7 @@ public class JsAstMapper {
|
|||||||
JsUnaryOperator.DELETE, to);
|
JsUnaryOperator.DELETE, to);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw createParserException(
|
return new JsNullLiteral();
|
||||||
"'delete' can only operate on property names and array elements",
|
|
||||||
from);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,5 +81,7 @@ public class MessagesBundle extends ListResourceBundle {
|
|||||||
{"msg.catch.unreachable", "any catch clauses following an unqualified catch are unreachable"},
|
{"msg.catch.unreachable", "any catch clauses following an unqualified catch are unreachable"},
|
||||||
{"msg.no.name.after.dot", "missing name after . operator"},
|
{"msg.no.name.after.dot", "missing name after . operator"},
|
||||||
{"msg.jsni.expected.identifier", "Expected an identifier in JSNI reference"},
|
{"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;
|
package com.google.gwt.dev.js.rhino;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -890,8 +892,13 @@ public class Parser {
|
|||||||
case TokenStream.DEC:
|
case TokenStream.DEC:
|
||||||
return nf.createUnary(tt, TokenStream.PRE, memberExpr(ts, true), position);
|
return nf.createUnary(tt, TokenStream.PRE, memberExpr(ts, true), position);
|
||||||
|
|
||||||
case TokenStream.DELPROP:
|
case TokenStream.DELPROP: {
|
||||||
return nf.createUnary(TokenStream.DELPROP, unaryExpr(ts), position);
|
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:
|
case TokenStream.ERROR:
|
||||||
break;
|
break;
|
||||||
@@ -922,6 +929,10 @@ public class Parser {
|
|||||||
return nf.createName("err", position); // Only reached on error. Try to continue.
|
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 {
|
private Node argumentList(TokenStream ts, Node listNode) throws IOException, JavaScriptException {
|
||||||
boolean matched;
|
boolean matched;
|
||||||
ts.flags |= TokenStream.TSF_REGEXP;
|
ts.flags |= TokenStream.TSF_REGEXP;
|
||||||
|
|||||||
Reference in New Issue
Block a user