/* * 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.impl; import com.google.gwt.core.ext.UnableToCompleteException; import com.google.gwt.dev.javac.testing.impl.JavaResourceBase; import com.google.gwt.dev.jjs.ast.JArrayType; import com.google.gwt.dev.jjs.ast.JCastMap; import com.google.gwt.dev.jjs.ast.JDeclaredType; import com.google.gwt.dev.jjs.ast.JProgram; import com.google.gwt.dev.jjs.ast.JReferenceType; import com.google.gwt.dev.jjs.ast.JRuntimeTypeReference; import com.google.gwt.thirdparty.guava.common.base.Function; import com.google.gwt.thirdparty.guava.common.collect.Iterables; import com.google.gwt.thirdparty.guava.common.collect.Lists; import com.google.gwt.thirdparty.guava.common.collect.Sets; import java.util.List; import java.util.Set; /** * Tests {@code ComputeExhaustiveCastabilityInformation}. */ public class ComputeExhaustiveCastabilityInformationTest extends JJSTestBase { public void testArrayClassCastabilityIsExhaustive() throws UnableToCompleteException { registerCompilableResources(); // Compiles and gets a reference to the String[] type. JProgram program = compileSnippet(null, "void", "", "", true); ComputeExhaustiveCastabilityInformation.exec(program); JDeclaredType stringType = program.getIndexedType("String"); JArrayType stringArrayType = program.getTypeArray(stringType); // Verifies that String[] casts to the exhaustive list of related array types and Object. assertSourceCastsToTargets(program, stringArrayType, Sets.newHashSet("java.lang.String[]", "java.lang.CharSequence[]", "java.lang.Comparable[]", "java.lang.Object[]", "java.io.Serializable[]", "java.lang.Object", "java.io.Serializable", "java.lang.Cloneable")); } public void testRegularClassCastabilityIsExhaustive() throws UnableToCompleteException { registerCompilableResources(); // Compiles and verifies that the String type casts to the exhaustive list of related types. assertSourceCastsToTargets("String", Sets.newHashSet("java.lang.String", "java.lang.CharSequence", "java.lang.Comparable", "java.lang.Object", "java.io.Serializable")); } private void assertSourceCastsToTargets(JProgram program, JReferenceType sourceType, Set<String> expectedTargetTypeNames) { // Gets the castmap for the given source type. JCastMap castMap = program.getCastMap(sourceType); // Converts the castmap entries to runtime type references. List<JRuntimeTypeReference> runtimeTypeReferences = Lists.newArrayList( Iterables.filter(castMap.getCanCastToTypes(), JRuntimeTypeReference.class)); // Makes a set of the names of the runtime type references. Set<String> actualTargetTypeNames = Sets.newHashSet( Lists.transform(runtimeTypeReferences, new Function<JRuntimeTypeReference, String>() { @Override public String apply(JRuntimeTypeReference runtimeTypeReference) { return runtimeTypeReference.getReferredType().getName(); } })); assertEquals(expectedTargetTypeNames, actualTargetTypeNames); } private void assertSourceCastsToTargets(String sourceTypeName, Set<String> expectedTargetTypeNames) throws UnableToCompleteException { JProgram program = compileSnippet(null, "void", "", "", true); ComputeExhaustiveCastabilityInformation.exec(program); JDeclaredType sourceType = program.getIndexedType(sourceTypeName); assertSourceCastsToTargets(program, sourceType, expectedTargetTypeNames); } private void registerCompilableResources() { sourceOracle.addOrReplace(JavaResourceBase.OBJECT); sourceOracle.addOrReplace(JavaResourceBase.CLONEABLE); sourceOracle.addOrReplace(JavaResourceBase.STRING); sourceOracle.addOrReplace(JavaResourceBase.COMPARABLE); sourceOracle.addOrReplace(JavaResourceBase.CHAR_SEQUENCE); sourceOracle.addOrReplace(JavaResourceBase.SERIALIZABLE); sourceOracle.addOrReplace(JavaResourceBase.SUPPRESS_WARNINGS); } }