JS/RTTI: in expressions like a as T when inferred type for a is S, where S <: T, don't generate type checking
This commit is contained in:
@@ -77,6 +77,12 @@ public class CastTestGenerated extends AbstractCastTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noRuntimeTypeCheck.kt")
|
||||
public void testNoRuntimeTypeCheck() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/expression/cast/cases/noRuntimeTypeCheck.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("reifiedToNotNull.kt")
|
||||
public void testReifiedToNotNull() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/expression/cast/cases/reifiedToNotNull.kt");
|
||||
|
||||
@@ -41,7 +41,7 @@ public class CallCounter extends RecursiveJsVisitor {
|
||||
return visitor;
|
||||
}
|
||||
|
||||
CallCounter(@NotNull Set<String> exceptFunctionNames) {
|
||||
private CallCounter(@NotNull Set<String> exceptFunctionNames) {
|
||||
this.exceptFunctionNames = exceptFunctionNames;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,19 @@ public class CallCounter extends RecursiveJsVisitor {
|
||||
return count;
|
||||
}
|
||||
|
||||
public int getUnqualifiedCallsCount(String expectedName) {
|
||||
int count = 0;
|
||||
|
||||
for (JsNameRef callNameRef : callsNameRefs) {
|
||||
JsName name = callNameRef.getName();
|
||||
if (name != null && name.getIdent().equals(expectedName)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInvocation(@NotNull JsInvocation invocation) {
|
||||
super.visitInvocation(invocation);
|
||||
|
||||
@@ -67,6 +67,13 @@ public class DirectiveTestUtils {
|
||||
}
|
||||
};
|
||||
|
||||
private static final DirectiveHandler METHOD_NOT_CALLED_IN_SCOPE = new DirectiveHandler("CHECK_METHOD_NOT_CALLED_IN_SCOPE") {
|
||||
@Override
|
||||
void processEntry(@NotNull JsNode ast, @NotNull ArgumentsHelper arguments) throws Exception {
|
||||
checkMethodNotCalledInScope(ast, arguments.getNamedArgument("function"), arguments.getNamedArgument("scope"));
|
||||
}
|
||||
};
|
||||
|
||||
private static final DirectiveHandler FUNCTIONS_HAVE_SAME_LINES = new DirectiveHandler("CHECK_FUNCTIONS_HAVE_SAME_LINES") {
|
||||
@Override
|
||||
void processEntry(@NotNull JsNode ast, @NotNull ArgumentsHelper arguments) throws Exception {
|
||||
@@ -189,6 +196,7 @@ public class DirectiveTestUtils {
|
||||
FUNCTION_NOT_CALLED,
|
||||
FUNCTION_CALLED_IN_SCOPE,
|
||||
FUNCTION_NOT_CALLED_IN_SCOPE,
|
||||
METHOD_NOT_CALLED_IN_SCOPE,
|
||||
FUNCTIONS_HAVE_SAME_LINES,
|
||||
COUNT_LABELS,
|
||||
COUNT_VARS,
|
||||
@@ -241,6 +249,15 @@ public class DirectiveTestUtils {
|
||||
assertTrue(errorMessage, isCalledInScope(node, functionName, scopeFunctionName));
|
||||
}
|
||||
|
||||
private static void checkMethodNotCalledInScope(
|
||||
@NotNull JsNode node,
|
||||
@NotNull String functionName,
|
||||
@NotNull String scopeFunctionName
|
||||
) throws Exception {
|
||||
String errorMessage = functionName + " is called inside " + scopeFunctionName;
|
||||
assertTrue(errorMessage, isMethodCalledInScope(node, functionName, scopeFunctionName));
|
||||
}
|
||||
|
||||
private static boolean isCalledInScope(
|
||||
@NotNull JsNode node,
|
||||
@NotNull String functionName,
|
||||
@@ -252,6 +269,17 @@ public class DirectiveTestUtils {
|
||||
return counter.getQualifiedCallsCount(functionName) == 0;
|
||||
}
|
||||
|
||||
private static boolean isMethodCalledInScope(
|
||||
@NotNull JsNode node,
|
||||
@NotNull String functionName,
|
||||
@NotNull String scopeFunctionName
|
||||
) throws Exception {
|
||||
JsNode scope = AstSearchUtil.getFunction(node, scopeFunctionName);
|
||||
|
||||
CallCounter counter = CallCounter.countCalls(scope);
|
||||
return counter.getUnqualifiedCallsCount(functionName) == 0;
|
||||
}
|
||||
|
||||
private abstract static class DirectiveHandler {
|
||||
@NotNull private final String directive;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user