blob: 5d27b57a4aa1fefc0bff6954714fc4d4e52d05dc [file] [log] [blame]
/*
* Copyright 2014 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.dev.jjs.optimized;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.junit.DoNotRunWith;
import com.google.gwt.junit.Platform;
import java.util.Random;
import jsinterop.annotations.JsPackage;
import jsinterop.annotations.JsType;
/**
* Tests cast checks are optimized out when cast checking is disabled.
*/
@DoNotRunWith(Platform.Devel)
public class CastOptimizationTest extends OptimizationTestBase {
private static class TestObject { }
@JsType(isNative = true)
private interface JsTypeTestInterface { }
private interface DualJsoTestInterface { }
private static class JsoTestObject extends JavaScriptObject implements DualJsoTestInterface {
protected JsoTestObject() { }
}
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
static class NativeObject {
}
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Function")
static class NativeFunction {
}
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Array")
static class NativeArray {
}
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Number")
static class NativeNumber {
}
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "String")
static class NativeString {
}
private static Object field;
private static double doubleField = new Random().nextDouble();
private static int randomNumber = new Random().nextInt(42);
@Override
protected void gwtSetUp() throws Exception {
field = createField();
}
private static Object createField() {
// Makes sure that field type is not upgradable even the compiler becomes really smart and also
// no types are pruned otherwise casts can be statically evaluated.
switch (randomNumber) {
case 0:
return new TestObject();
case 1:
return JavaScriptObject.createObject();
case 2:
return new DualJsoTestInterface() { };
case 3:
return "Some string";
default:
return null;
}
}
public static TestObject castOp() {
return ((TestObject) field);
}
public static JavaScriptObject castOpJso() {
return ((JavaScriptObject) field);
}
public static DualJsoTestInterface castOpDualJso() {
return ((DualJsoTestInterface) field);
}
public static JavaScriptObject castOpJsType() {
return ((JavaScriptObject) field);
}
public static String castOpString() {
return ((String) field);
}
public static NativeFunction castNativeFunction() {
return ((NativeFunction) field);
}
public static NativeObject castNativeObject() {
return ((NativeObject) field);
}
public static NativeArray castNativeArray() {
return ((NativeArray) field);
}
public static NativeNumber castNativeNumber() {
return ((NativeNumber) field);
}
public static void castInt() {
int num = ((int) doubleField);
}
private static native String getGeneratedCastFunctionDefinition() /*-{
return function() {
@CastOptimizationTest::castOp()();
@CastOptimizationTest::castOpJso()();
@CastOptimizationTest::castOpDualJso()();
@CastOptimizationTest::castOpJsType()();
@CastOptimizationTest::castOpString()();
@CastOptimizationTest::castNativeFunction()();
@CastOptimizationTest::castNativeNumber()();
@CastOptimizationTest::castNativeArray()();
@CastOptimizationTest::castNativeObject()();
@CastOptimizationTest::castInt()();
}.toString();
}-*/;
public void testCastsAreRemoved() throws Exception {
String functionDef = getGeneratedCastFunctionDefinition();
assertFunctionMatches(functionDef, "");
}
private static native String getGeneratedNullnessPropagationFunctionDefinition() /*-{
return function() {
@CastOptimizationTest::castNonNullnessCheck()();
}.toString();
}-*/;
public static void castNonNullnessCheck() {
if ((String) (randomNumber == 1 ? "uniqueCastString" : new Object()) == null) {
throw new RuntimeException();
}
}
public void testCastsPropagatesNullness() throws Exception {
String functionDef = getGeneratedNullnessPropagationFunctionDefinition();
// Means that the function was inlined but the throw was optimized away.
assertFunctionMatches(functionDef, "<obf>==1?'uniqueCastString':new<obf>()");
}
}