1 /* 2 * Copyright 2016 Federico Tomassetti 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.github.javaparser.symbolsolver.model.typesystem; 18 19 import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration; 20 import com.github.javaparser.resolution.types.ResolvedTypeVariable; 21 import com.github.javaparser.resolution.types.ResolvedWildcard; 22 import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; 23 import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration; 24 import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; 25 import org.junit.jupiter.api.BeforeEach; 26 import org.junit.jupiter.api.Test; 27 28 import java.util.Collections; 29 30 import static org.junit.jupiter.api.Assertions.assertEquals; 31 import static org.junit.jupiter.api.Assertions.assertTrue; 32 import static org.junit.jupiter.api.Assertions.assertThrows; 33 34 class WildcardUsageTest { 35 36 class Foo { 37 } 38 39 class Bar extends Foo { 40 } 41 42 private TypeSolver typeSolver; 43 private ReferenceTypeImpl foo; 44 private ReferenceTypeImpl bar; 45 private ReferenceTypeImpl object; 46 private ReferenceTypeImpl string; 47 private ResolvedWildcard unbounded = ResolvedWildcard.UNBOUNDED; 48 private ResolvedWildcard superFoo; 49 private ResolvedWildcard superBar; 50 private ResolvedWildcard extendsFoo; 51 private ResolvedWildcard extendsBar; 52 private ResolvedWildcard superA; 53 private ResolvedWildcard extendsA; 54 private ResolvedWildcard superString; 55 private ResolvedWildcard extendsString; 56 private ResolvedTypeVariable a; 57 58 @BeforeEach setup()59 void setup() { 60 typeSolver = new ReflectionTypeSolver(); 61 foo = new ReferenceTypeImpl(new ReflectionClassDeclaration(Foo.class, typeSolver), typeSolver); 62 bar = new ReferenceTypeImpl(new ReflectionClassDeclaration(Bar.class, typeSolver), typeSolver); 63 object = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver); 64 string = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver); 65 superFoo = ResolvedWildcard.superBound(foo); 66 superBar = ResolvedWildcard.superBound(bar); 67 extendsFoo = ResolvedWildcard.extendsBound(foo); 68 extendsBar = ResolvedWildcard.extendsBound(bar); 69 a = new ResolvedTypeVariable(ResolvedTypeParameterDeclaration.onType("A", "foo.Bar", Collections.emptyList())); 70 superA = ResolvedWildcard.superBound(a); 71 extendsA = ResolvedWildcard.extendsBound(a); 72 superString = ResolvedWildcard.superBound(string); 73 extendsString = ResolvedWildcard.extendsBound(string); 74 } 75 76 @Test testIsArray()77 void testIsArray() { 78 assertEquals(false, unbounded.isArray()); 79 assertEquals(false, superFoo.isArray()); 80 assertEquals(false, superBar.isArray()); 81 assertEquals(false, extendsFoo.isArray()); 82 assertEquals(false, extendsBar.isArray()); 83 } 84 85 @Test testIsPrimitive()86 void testIsPrimitive() { 87 assertEquals(false, unbounded.isPrimitive()); 88 assertEquals(false, superFoo.isPrimitive()); 89 assertEquals(false, superBar.isPrimitive()); 90 assertEquals(false, extendsFoo.isPrimitive()); 91 assertEquals(false, extendsBar.isPrimitive()); 92 } 93 94 @Test testIsNull()95 void testIsNull() { 96 assertEquals(false, unbounded.isNull()); 97 assertEquals(false, superFoo.isNull()); 98 assertEquals(false, superBar.isNull()); 99 assertEquals(false, extendsFoo.isNull()); 100 assertEquals(false, extendsBar.isNull()); 101 } 102 103 @Test testIsReference()104 void testIsReference() { 105 assertEquals(true, unbounded.isReference()); 106 assertEquals(true, superFoo.isReference()); 107 assertEquals(true, superBar.isReference()); 108 assertEquals(true, extendsFoo.isReference()); 109 assertEquals(true, extendsBar.isReference()); 110 } 111 112 @Test testIsReferenceType()113 void testIsReferenceType() { 114 assertEquals(false, unbounded.isReferenceType()); 115 assertEquals(false, superFoo.isReferenceType()); 116 assertEquals(false, superBar.isReferenceType()); 117 assertEquals(false, extendsFoo.isReferenceType()); 118 assertEquals(false, extendsBar.isReferenceType()); 119 } 120 121 @Test testIsVoid()122 void testIsVoid() { 123 assertEquals(false, unbounded.isVoid()); 124 assertEquals(false, superFoo.isVoid()); 125 assertEquals(false, superBar.isVoid()); 126 assertEquals(false, extendsFoo.isVoid()); 127 assertEquals(false, extendsBar.isVoid()); 128 } 129 130 @Test testIsTypeVariable()131 void testIsTypeVariable() { 132 assertEquals(false, unbounded.isTypeVariable()); 133 assertEquals(false, superFoo.isTypeVariable()); 134 assertEquals(false, superBar.isTypeVariable()); 135 assertEquals(false, extendsFoo.isTypeVariable()); 136 assertEquals(false, extendsBar.isTypeVariable()); 137 } 138 139 @Test testIsWildcard()140 void testIsWildcard() { 141 assertEquals(true, unbounded.isWildcard()); 142 assertEquals(true, superFoo.isWildcard()); 143 assertEquals(true, superBar.isWildcard()); 144 assertEquals(true, extendsFoo.isWildcard()); 145 assertEquals(true, extendsBar.isWildcard()); 146 } 147 148 @Test testAsArrayTypeUsage()149 void testAsArrayTypeUsage() { 150 assertThrows(UnsupportedOperationException.class, () -> unbounded.asArrayType()); 151 } 152 153 @Test testAsReferenceTypeUsage()154 void testAsReferenceTypeUsage() { 155 assertThrows(UnsupportedOperationException.class, () -> unbounded.asReferenceType()); 156 } 157 158 @Test testAsTypeParameter()159 void testAsTypeParameter() { 160 assertThrows(UnsupportedOperationException.class, () -> unbounded.asTypeParameter()); 161 } 162 163 @Test testAsPrimitive()164 void testAsPrimitive() { 165 assertThrows(UnsupportedOperationException.class, () -> unbounded.asPrimitive()); 166 } 167 168 @Test testAsWildcard()169 void testAsWildcard() { 170 assertTrue(unbounded == unbounded.asWildcard()); 171 assertTrue(superFoo == superFoo.asWildcard()); 172 assertTrue(superBar == superBar.asWildcard()); 173 assertTrue(extendsFoo == extendsFoo.asWildcard()); 174 assertTrue(extendsBar == extendsBar.asWildcard()); 175 } 176 177 @Test testAsDescribe()178 void testAsDescribe() { 179 assertEquals("?", unbounded.describe()); 180 assertEquals("? super com.github.javaparser.symbolsolver.model.typesystem.WildcardUsageTest.Foo", superFoo.describe()); 181 assertEquals("? super com.github.javaparser.symbolsolver.model.typesystem.WildcardUsageTest.Bar", superBar.describe()); 182 assertEquals("? extends com.github.javaparser.symbolsolver.model.typesystem.WildcardUsageTest.Foo", extendsFoo.describe()); 183 assertEquals("? extends com.github.javaparser.symbolsolver.model.typesystem.WildcardUsageTest.Bar", extendsBar.describe()); 184 } 185 186 @Test testReplaceParam()187 void testReplaceParam() { 188 ResolvedTypeParameterDeclaration tpA = ResolvedTypeParameterDeclaration.onType("A", "foo.Bar", Collections.emptyList()); 189 ResolvedTypeParameterDeclaration tpB = ResolvedTypeParameterDeclaration.onType("B", "foo.Bar", Collections.emptyList()); 190 assertTrue(unbounded == unbounded.replaceTypeVariables(tpA, string)); 191 assertTrue(superFoo == superFoo.replaceTypeVariables(tpA, string)); 192 assertTrue(extendsFoo == extendsFoo.replaceTypeVariables(tpA, string)); 193 assertEquals(superString, superA.replaceTypeVariables(tpA, string)); 194 assertEquals(extendsString, extendsA.replaceTypeVariables(tpA, string)); 195 assertTrue(superA == superA.replaceTypeVariables(tpB, string)); 196 assertTrue(extendsA == extendsA.replaceTypeVariables(tpB, string)); 197 } 198 199 @Test testIsAssignableBySimple()200 void testIsAssignableBySimple() { 201 assertEquals(false, unbounded.isAssignableBy(object)); 202 assertEquals(true, object.isAssignableBy(unbounded)); 203 assertEquals(false, string.isAssignableBy(unbounded)); 204 assertEquals(true, superFoo.isAssignableBy(foo)); 205 assertEquals(false, foo.isAssignableBy(superFoo)); 206 assertEquals(false, extendsFoo.isAssignableBy(foo)); 207 assertEquals(true, foo.isAssignableBy(extendsFoo)); 208 } 209 210 /*@Test 211 public void testIsAssignableByGenerics() { 212 assertEquals(false, listOfStrings.isAssignableBy(listOfWildcardExtendsString)); 213 assertEquals(false, listOfStrings.isAssignableBy(listOfWildcardExtendsString)); 214 assertEquals(true, listOfWildcardExtendsString.isAssignableBy(listOfStrings)); 215 assertEquals(false, listOfWildcardExtendsString.isAssignableBy(listOfWildcardSuperString)); 216 assertEquals(true, listOfWildcardSuperString.isAssignableBy(listOfStrings)); 217 assertEquals(false, listOfWildcardSuperString.isAssignableBy(listOfWildcardExtendsString)); 218 } 219 220 @Test 221 public void testIsAssignableByGenericsInheritance() { 222 assertEquals(true, collectionOfString.isAssignableBy(collectionOfString)); 223 assertEquals(true, collectionOfString.isAssignableBy(listOfStrings)); 224 assertEquals(true, collectionOfString.isAssignableBy(linkedListOfString)); 225 226 assertEquals(false, listOfStrings.isAssignableBy(collectionOfString)); 227 assertEquals(true, listOfStrings.isAssignableBy(listOfStrings)); 228 assertEquals(true, listOfStrings.isAssignableBy(linkedListOfString)); 229 230 assertEquals(false, linkedListOfString.isAssignableBy(collectionOfString)); 231 assertEquals(false, linkedListOfString.isAssignableBy(listOfStrings)); 232 assertEquals(true, linkedListOfString.isAssignableBy(linkedListOfString)); 233 } 234 235 @Test 236 public void testGetAllAncestorsConsideringTypeParameters() { 237 assertTrue(linkedListOfString.getAllAncestors().contains(object)); 238 assertTrue(linkedListOfString.getAllAncestors().contains(listOfStrings)); 239 assertTrue(linkedListOfString.getAllAncestors().contains(collectionOfString)); 240 assertFalse(linkedListOfString.getAllAncestors().contains(listOfA)); 241 } 242 243 @Test 244 public void testGetAllAncestorsConsideringGenericsCases() { 245 ReferenceTypeUsage foo = new ReferenceTypeUsage(new ReflectionClassDeclaration(Foo.class, typeSolver), typeSolver); 246 ReferenceTypeUsage bar = new ReferenceTypeUsage(new ReflectionClassDeclaration(Bar.class, typeSolver), typeSolver); 247 ReferenceTypeUsage left, right; 248 249 //YES MoreBazzing<Foo, Bar> e1 = new MoreBazzing<Foo, Bar>(); 250 assertEquals(true, 251 new ReferenceTypeUsage( 252 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 253 ImmutableList.of(foo, bar), typeSolver) 254 .isAssignableBy(new ReferenceTypeUsage( 255 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 256 ImmutableList.of(foo, bar), typeSolver)) 257 ); 258 259 //YES MoreBazzing<? extends Foo, Bar> e2 = new MoreBazzing<Foo, Bar>(); 260 assertEquals(true, 261 new ReferenceTypeUsage( 262 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 263 ImmutableList.of(WildcardUsage.extendsBound(foo), bar), typeSolver) 264 .isAssignableBy(new ReferenceTypeUsage( 265 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 266 ImmutableList.of(foo, bar), typeSolver)) 267 ); 268 269 //YES MoreBazzing<Foo, ? extends Bar> e3 = new MoreBazzing<Foo, Bar>(); 270 assertEquals(true, 271 new ReferenceTypeUsage( 272 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 273 ImmutableList.of(foo, WildcardUsage.extendsBound(bar)), typeSolver) 274 .isAssignableBy(new ReferenceTypeUsage( 275 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 276 ImmutableList.of(foo, bar), typeSolver)) 277 ); 278 279 //YES MoreBazzing<? extends Foo, ? extends Foo> e4 = new MoreBazzing<Foo, Bar>(); 280 assertEquals(true, 281 new ReferenceTypeUsage( 282 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 283 ImmutableList.of(WildcardUsage.extendsBound(foo), WildcardUsage.extendsBound(foo)), typeSolver) 284 .isAssignableBy(new ReferenceTypeUsage( 285 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 286 ImmutableList.of(foo, bar), typeSolver)) 287 ); 288 289 //YES MoreBazzing<? extends Foo, ? extends Foo> e5 = new MoreBazzing<Bar, Bar>(); 290 left = new ReferenceTypeUsage( 291 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 292 ImmutableList.of(WildcardUsage.extendsBound(foo), WildcardUsage.extendsBound(foo)), typeSolver); 293 right = new ReferenceTypeUsage( 294 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 295 ImmutableList.of(bar, bar), typeSolver); 296 assertEquals(true, left.isAssignableBy(right)); 297 298 //YES Bazzer<Object, String, String> e6 = new MoreBazzing<String, Object>(); 299 left = new ReferenceTypeUsage( 300 new ReflectionClassDeclaration(Bazzer.class, typeSolver), 301 ImmutableList.of(object, string, string), typeSolver); 302 right = new ReferenceTypeUsage( 303 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 304 ImmutableList.of(string, object), typeSolver); 305 assertEquals(true, left.isAssignableBy(right)); 306 307 //YES Bazzer<String,String,String> e7 = new MoreBazzing<String, String>(); 308 assertEquals(true, 309 new ReferenceTypeUsage( 310 new ReflectionClassDeclaration(Bazzer.class, typeSolver), 311 ImmutableList.of(string, string, string), typeSolver) 312 .isAssignableBy(new ReferenceTypeUsage( 313 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 314 ImmutableList.of(string, string), typeSolver)) 315 ); 316 317 //YES Bazzer<Bar,String,Foo> e8 = new MoreBazzing<Foo, Bar>(); 318 assertEquals(true, 319 new ReferenceTypeUsage( 320 new ReflectionClassDeclaration(Bazzer.class, typeSolver), 321 ImmutableList.of(bar, string, foo), typeSolver) 322 .isAssignableBy(new ReferenceTypeUsage( 323 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 324 ImmutableList.of(foo, bar), typeSolver)) 325 ); 326 327 //YES Bazzer<Foo,String,Bar> e9 = new MoreBazzing<Bar, Foo>(); 328 assertEquals(true, 329 new ReferenceTypeUsage( 330 new ReflectionClassDeclaration(Bazzer.class, typeSolver), 331 ImmutableList.of(foo, string, bar), typeSolver) 332 .isAssignableBy(new ReferenceTypeUsage( 333 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 334 ImmutableList.of(bar, foo), typeSolver)) 335 ); 336 337 //NO Bazzer<Bar,String,Foo> n1 = new MoreBazzing<Bar, Foo>(); 338 assertEquals(false, 339 new ReferenceTypeUsage( 340 new ReflectionClassDeclaration(Bazzer.class, typeSolver), 341 ImmutableList.of(bar,string,foo), typeSolver) 342 .isAssignableBy(new ReferenceTypeUsage( 343 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 344 ImmutableList.of(bar, foo), typeSolver)) 345 ); 346 347 //NO Bazzer<Bar,String,Bar> n2 = new MoreBazzing<Bar, Foo>(); 348 assertEquals(false, 349 new ReferenceTypeUsage( 350 new ReflectionClassDeclaration(Bazzer.class, typeSolver), 351 ImmutableList.of(bar, string, foo), typeSolver) 352 .isAssignableBy(new ReferenceTypeUsage( 353 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 354 ImmutableList.of(bar, foo), typeSolver)) 355 ); 356 357 //NO Bazzer<Foo,Object,Bar> n3 = new MoreBazzing<Bar, Foo>(); 358 assertEquals(false, 359 new ReferenceTypeUsage( 360 new ReflectionClassDeclaration(Bazzer.class, typeSolver), 361 ImmutableList.of(foo, object, bar), typeSolver) 362 .isAssignableBy(new ReferenceTypeUsage( 363 new ReflectionClassDeclaration(MoreBazzing.class, typeSolver), 364 ImmutableList.of(bar, foo), typeSolver)) 365 ); 366 } 367 368 @Test 369 public void charSequenceIsAssignableToObject() { 370 TypeSolver typeSolver = new JreTypeSolver(); 371 ReferenceTypeUsage charSequence = new ReferenceTypeUsage(new ReflectionInterfaceDeclaration(CharSequence.class, typeSolver), typeSolver); 372 ReferenceTypeUsage object = new ReferenceTypeUsage(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver); 373 assertEquals(false, charSequence.isAssignableBy(object)); 374 assertEquals(true, object.isAssignableBy(charSequence)); 375 } 376 377 @Test 378 public void testGetFieldTypeExisting() { 379 class Foo<A> { 380 List<A> elements; 381 } 382 383 TypeSolver typeSolver = new JreTypeSolver(); 384 ReferenceTypeUsage ref = new ReferenceTypeUsage(new ReflectionClassDeclaration(Foo.class, typeSolver), typeSolver); 385 386 assertEquals(true, ref.getFieldType("elements").isPresent()); 387 assertEquals(true, ref.getFieldType("elements").get().isReferenceType()); 388 assertEquals(List.class.getCanonicalName(), ref.getFieldType("elements").get().asReferenceType().getQualifiedName()); 389 assertEquals(1, ref.getFieldType("elements").get().asReferenceType().typeParametersValues().size()); 390 assertEquals(true, ref.getFieldType("elements").get().asReferenceType().typeParametersValues().get(0).isTypeParameter()); 391 assertEquals("A", ref.getFieldType("elements").get().asReferenceType().typeParametersValues().get(0).asTypeParameter().getName()); 392 393 ref = new ReferenceTypeUsage(new ReflectionClassDeclaration(Foo.class, typeSolver), 394 ImmutableList.of(new ReferenceTypeUsage(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver)), 395 typeSolver); 396 397 assertEquals(true, ref.getFieldType("elements").isPresent()); 398 assertEquals(true, ref.getFieldType("elements").get().isReferenceType()); 399 assertEquals(List.class.getCanonicalName(), ref.getFieldType("elements").get().asReferenceType().getQualifiedName()); 400 assertEquals(1, ref.getFieldType("elements").get().asReferenceType().typeParametersValues().size()); 401 assertEquals(true, ref.getFieldType("elements").get().asReferenceType().typeParametersValues().get(0).isReferenceType()); 402 assertEquals(String.class.getCanonicalName(), ref.getFieldType("elements").get().asReferenceType().typeParametersValues().get(0).asReferenceType().getQualifiedName()); 403 } 404 405 @Test 406 public void testGetFieldTypeUnexisting() { 407 class Foo<A> { 408 List<A> elements; 409 } 410 411 TypeSolver typeSolver = new JreTypeSolver(); 412 ReferenceTypeUsage ref = new ReferenceTypeUsage(new ReflectionClassDeclaration(Foo.class, typeSolver), typeSolver); 413 414 assertEquals(false, ref.getFieldType("bar").isPresent()); 415 416 ref = new ReferenceTypeUsage(new ReflectionClassDeclaration(Foo.class, typeSolver), 417 ImmutableList.of(new ReferenceTypeUsage(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver)), 418 typeSolver); 419 420 assertEquals(false, ref.getFieldType("bar").isPresent()); 421 }*/ 422 423 } 424