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:
Alexey Andreev
2016-04-28 19:29:27 +03:00
parent 0f6a6a3ba4
commit 6454613b51
8 changed files with 113 additions and 20 deletions
@@ -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;