1 /* 2 * Copyright 2019 Google Inc. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.turbine.processing; 18 19 import static com.google.common.truth.Truth.assertWithMessage; 20 import static com.google.common.truth.TruthJUnit.assume; 21 import static org.junit.Assert.assertThrows; 22 23 import com.google.common.base.Joiner; 24 import com.google.common.collect.ImmutableSet; 25 import com.google.turbine.types.Deannotate; 26 import javax.lang.model.type.PrimitiveType; 27 import javax.lang.model.type.TypeKind; 28 import javax.lang.model.type.TypeMirror; 29 import javax.lang.model.util.Types; 30 import org.junit.Test; 31 import org.junit.runner.RunWith; 32 import org.junit.runners.Parameterized; 33 import org.junit.runners.Parameterized.Parameters; 34 35 @RunWith(Parameterized.class) 36 public class TurbineTypesUnaryTest extends AbstractTurbineTypesTest { 37 38 @Parameters(name = "{index}: {0}") parameters()39 public static Iterable<Object[]> parameters() throws Exception { 40 return unaryParameters(); 41 } 42 43 final String testDescription; 44 final Types javacTypes; 45 final TypeMirror javacA; 46 final Types turbineTypes; 47 final TypeMirror turbineA; 48 TurbineTypesUnaryTest( String testDescription, Types javacTypes, TypeMirror javacA, Types turbineTypes, TypeMirror turbineA)49 public TurbineTypesUnaryTest( 50 String testDescription, 51 Types javacTypes, 52 TypeMirror javacA, 53 Types turbineTypes, 54 TypeMirror turbineA) { 55 this.testDescription = testDescription; 56 this.javacTypes = javacTypes; 57 this.javacA = javacA; 58 this.turbineTypes = turbineTypes; 59 this.turbineA = turbineA; 60 } 61 62 @Test unboxedType()63 public void unboxedType() { 64 IllegalArgumentException thrown = null; 65 String expectedType = null; 66 try { 67 expectedType = javacTypes.unboxedType(javacA).toString(); 68 } catch (IllegalArgumentException e) { 69 thrown = e; 70 } 71 if (thrown != null) { 72 assertThrows( 73 String.format("expected unboxedType(`%s`) to throw", turbineA), 74 IllegalArgumentException.class, 75 () -> turbineTypes.unboxedType(turbineA).toString()); 76 } else { 77 String actual = turbineTypes.unboxedType(turbineA).toString(); 78 assertWithMessage("unboxedClass(`%s`) = unboxedClass(`%s`)", javacA, turbineA) 79 .that(actual) 80 .isEqualTo(expectedType); 81 } 82 } 83 84 @Test boxedClass()85 public void boxedClass() { 86 assume().that(javacA).isInstanceOf(PrimitiveType.class); 87 assume().that(turbineA).isInstanceOf(PrimitiveType.class); 88 89 String expected = javacTypes.boxedClass((PrimitiveType) javacA).toString(); 90 String actual = turbineTypes.boxedClass((PrimitiveType) turbineA).toString(); 91 assertWithMessage("boxedClass(`%s`) = boxedClass(`%s`)", javacA, turbineA) 92 .that(actual) 93 .isEqualTo(expected); 94 } 95 96 @Test erasure()97 public void erasure() { 98 String expected = javacTypes.erasure(javacA).toString(); 99 String actual = turbineTypes.erasure(turbineA).toString(); 100 // Work around javac bug https://bugs.openjdk.org/browse/JDK-8042981 until it is fixed. 101 // The erasure of `@A int @B []` should be just `int[]`, but pre-bugfix javac will report 102 // `@A int @B []`. So for this specific case, change the expected string to what javac *should* 103 // return. 104 switch (turbineA.toString()) { 105 case "@p.Test0.A int @p.Test0.B []": 106 expected = "int[]"; 107 break; 108 case "@p.Test0.A int": 109 expected = "int"; 110 break; 111 default: // fall out 112 } 113 assertWithMessage("erasure(`%s`) = erasure(`%s`)", javacA, turbineA) 114 .that(actual) 115 .isEqualTo(expected); 116 } 117 118 private static final ImmutableSet<TypeKind> UNSUPPORTED_BY_DIRECT_SUPERTYPES = 119 ImmutableSet.of(TypeKind.EXECUTABLE, TypeKind.PACKAGE); 120 121 @Test directSupertypes()122 public void directSupertypes() { 123 assume().that(UNSUPPORTED_BY_DIRECT_SUPERTYPES).doesNotContain(javacA.getKind()); 124 125 String expected = Joiner.on(", ").join(javacTypes.directSupertypes(javacA)); 126 String actual = Joiner.on(", ").join(turbineTypes.directSupertypes(turbineA)); 127 // Work around javac bug https://bugs.openjdk.org/browse/JDK-8042981 until it is fixed. 128 // See comment in the erasure() test method. 129 switch (turbineA.toString()) { 130 case "java.util.@p.Test0.A List<@p.Test0.A int @p.Test0.B []>": 131 expected = "java.lang.Object, java.util.SequencedCollection<int[]>"; 132 break; 133 default: // fall out 134 } 135 assertWithMessage("directSupertypes(`%s`) = directSupertypes(`%s`)", javacA, turbineA) 136 .that(actual) 137 .isEqualTo(expected); 138 } 139 140 @Test directSupertypesThrows()141 public void directSupertypesThrows() { 142 assume().that(UNSUPPORTED_BY_DIRECT_SUPERTYPES).contains(javacA.getKind()); 143 144 assertThrows(IllegalArgumentException.class, () -> javacTypes.directSupertypes(turbineA)); 145 assertThrows(IllegalArgumentException.class, () -> turbineTypes.directSupertypes(turbineA)); 146 } 147 148 @Test asElement()149 public void asElement() { 150 // TODO(cushon): this looks like a javac bug 151 assume().that(javacA.getKind()).isNotEqualTo(TypeKind.INTERSECTION); 152 153 String expected = String.valueOf(javacTypes.asElement(javacA)); 154 String actual = String.valueOf(turbineTypes.asElement(turbineA)); 155 assertWithMessage("asElement(`%s`) = asElement(`%s`)", javacA, turbineA) 156 .that(actual) 157 .isEqualTo(expected); 158 } 159 160 @Test deannotate()161 public void deannotate() { 162 String toString = turbineA.toString(); 163 String deannotated = 164 Deannotate.deannotate(((TurbineTypeMirror) turbineA).asTurbineType()).toString(); 165 if (toString.contains("@")) { 166 assertWithMessage("deannotate(`%s`) = `%s`", toString, deannotated) 167 .that(deannotated) 168 .doesNotContain("@"); 169 } 170 } 171 } 172