ResolvedArrayTypeTest.java
/*
* Copyright (C) 2015-2016 Federico Tomassetti
* Copyright (C) 2017-2024 The JavaParser Team.
*
* This file is part of JavaParser.
*
* JavaParser can be used either under the terms of
* a) the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* b) the terms of the Apache License
*
* You should have received a copy of both licenses in LICENCE.LGPL and
* LICENCE.APACHE. Please refer to those files for details.
*
* JavaParser is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*/
package com.github.javaparser.symbolsolver.resolution.types;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.github.javaparser.JavaParserAdapter;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.resolution.model.typesystem.NullType;
import com.github.javaparser.resolution.types.ResolvedArrayType;
import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
import com.github.javaparser.resolution.types.ResolvedType;
import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
class ResolvedArrayTypeTest extends AbstractResolutionTest {
JavaParserAdapter parser = JavaParserAdapter.of(createParserWithResolver(defaultTypeSolver()));
ResolvedType rByte = getType("class A {java.lang.Byte x;}");
ResolvedType rShort = getType("class A {java.lang.Short x;}");
ResolvedType rChar = getType("class A {java.lang.Character x;}");
ResolvedType rInteger = getType("class A {java.lang.Integer x;}");
ResolvedType rLong = getType("class A {java.lang.Long x;}");
ResolvedType rFloat = getType("class A {java.lang.Float x;}");
ResolvedType rDouble = getType("class A {java.lang.Double x;}");
ResolvedType rString = getType("class A {java.lang.String x;}");
ResolvedType rCharSequence = getType("class A {java.lang.CharSequence x;}");
ResolvedType rObject = getType("class A {java.lang.Object x;}");
ResolvedType rCloneable = getType("class A {java.lang.Cloneable x;}");
ResolvedType rSerializable = getType("class A {java.io.Serializable x;}");
ResolvedType rArrayList = getType("class A {java.util.ArrayList x;}");
@Test
// An array of primitive type can be assigned another array of primitive type
// if primitive type are the same.
void arrayOfPrimitiveIsAssignableByArrayOfSamePrimitiveType() {
assertTrue(array(ResolvedPrimitiveType.DOUBLE).isAssignableBy(array(ResolvedPrimitiveType.DOUBLE)));
assertTrue(array(ResolvedPrimitiveType.FLOAT).isAssignableBy(array(ResolvedPrimitiveType.FLOAT)));
assertTrue(array(ResolvedPrimitiveType.LONG).isAssignableBy(array(ResolvedPrimitiveType.LONG)));
assertTrue(array(ResolvedPrimitiveType.INT).isAssignableBy(array(ResolvedPrimitiveType.INT)));
assertTrue(array(ResolvedPrimitiveType.BYTE).isAssignableBy(array(ResolvedPrimitiveType.BYTE)));
assertTrue(array(ResolvedPrimitiveType.SHORT).isAssignableBy(array(ResolvedPrimitiveType.SHORT)));
assertTrue(array(ResolvedPrimitiveType.CHAR).isAssignableBy(array(ResolvedPrimitiveType.CHAR)));
}
@Test
void arrayOfPrimitiveIsNotAssignableByArrayOfDifferentPrimitiveType() {
assertFalse(isAssignableBy(
array(ResolvedPrimitiveType.DOUBLE),
arrays(
ResolvedPrimitiveType.FLOAT,
ResolvedPrimitiveType.LONG,
ResolvedPrimitiveType.INT,
ResolvedPrimitiveType.BYTE,
ResolvedPrimitiveType.SHORT,
ResolvedPrimitiveType.CHAR)));
assertFalse(isAssignableBy(
array(ResolvedPrimitiveType.FLOAT),
arrays(
ResolvedPrimitiveType.DOUBLE,
ResolvedPrimitiveType.LONG,
ResolvedPrimitiveType.INT,
ResolvedPrimitiveType.BYTE,
ResolvedPrimitiveType.SHORT,
ResolvedPrimitiveType.CHAR)));
assertFalse(isAssignableBy(
array(ResolvedPrimitiveType.LONG),
arrays(
ResolvedPrimitiveType.DOUBLE,
ResolvedPrimitiveType.FLOAT,
ResolvedPrimitiveType.INT,
ResolvedPrimitiveType.BYTE,
ResolvedPrimitiveType.SHORT,
ResolvedPrimitiveType.CHAR)));
assertFalse(isAssignableBy(
array(ResolvedPrimitiveType.INT),
arrays(
ResolvedPrimitiveType.DOUBLE,
ResolvedPrimitiveType.FLOAT,
ResolvedPrimitiveType.LONG,
ResolvedPrimitiveType.BYTE,
ResolvedPrimitiveType.SHORT,
ResolvedPrimitiveType.CHAR)));
assertFalse(isAssignableBy(
array(ResolvedPrimitiveType.BYTE),
arrays(
ResolvedPrimitiveType.DOUBLE,
ResolvedPrimitiveType.FLOAT,
ResolvedPrimitiveType.LONG,
ResolvedPrimitiveType.INT,
ResolvedPrimitiveType.SHORT,
ResolvedPrimitiveType.CHAR)));
assertFalse(isAssignableBy(
array(ResolvedPrimitiveType.SHORT),
arrays(
ResolvedPrimitiveType.DOUBLE,
ResolvedPrimitiveType.FLOAT,
ResolvedPrimitiveType.LONG,
ResolvedPrimitiveType.INT,
ResolvedPrimitiveType.BYTE,
ResolvedPrimitiveType.CHAR)));
assertFalse(isAssignableBy(
array(ResolvedPrimitiveType.CHAR),
arrays(
ResolvedPrimitiveType.DOUBLE,
ResolvedPrimitiveType.FLOAT,
ResolvedPrimitiveType.LONG,
ResolvedPrimitiveType.INT,
ResolvedPrimitiveType.BYTE,
ResolvedPrimitiveType.SHORT)));
}
@Test
// An array of primitive type cannot be assigned to a Boxed type variable,
// because Boxed type is a class type other than Object
void arrayOfPrimitiveIsNotAssignableByArrayOfBoxedType() {
assertFalse(array(ResolvedPrimitiveType.DOUBLE).isAssignableBy(array(rDouble)));
assertFalse(array(ResolvedPrimitiveType.FLOAT).isAssignableBy(array(rFloat)));
assertFalse(array(ResolvedPrimitiveType.LONG).isAssignableBy(array(rLong)));
assertFalse(array(ResolvedPrimitiveType.INT).isAssignableBy(array(rInteger)));
assertFalse(array(ResolvedPrimitiveType.BYTE).isAssignableBy(array(rByte)));
assertFalse(array(ResolvedPrimitiveType.SHORT).isAssignableBy(array(rShort)));
assertFalse(array(ResolvedPrimitiveType.CHAR).isAssignableBy(array(rChar)));
}
@Test
void arrayOfPrimitiveIsAssignableByNullType() {
assertTrue(array(ResolvedPrimitiveType.DOUBLE).isAssignableBy(NullType.INSTANCE));
assertTrue(array(ResolvedPrimitiveType.FLOAT).isAssignableBy(NullType.INSTANCE));
assertTrue(array(ResolvedPrimitiveType.LONG).isAssignableBy(NullType.INSTANCE));
assertTrue(array(ResolvedPrimitiveType.INT).isAssignableBy(NullType.INSTANCE));
assertTrue(array(ResolvedPrimitiveType.BYTE).isAssignableBy(NullType.INSTANCE));
assertTrue(array(ResolvedPrimitiveType.SHORT).isAssignableBy(NullType.INSTANCE));
assertTrue(array(ResolvedPrimitiveType.CHAR).isAssignableBy(NullType.INSTANCE));
}
@Test
// An array can be assigned only to a variable of a compatible array type, or to
// a variable of type Object, Cloneable or java.io.Serializable.
void objectIsAssignableByAnyArrayOfPrimitiveTypeOrReference() {
assertTrue(rObject.isAssignableBy(array(ResolvedPrimitiveType.DOUBLE)));
assertTrue(rObject.isAssignableBy(array(ResolvedPrimitiveType.FLOAT)));
assertTrue(rObject.isAssignableBy(array(ResolvedPrimitiveType.LONG)));
assertTrue(rObject.isAssignableBy(array(ResolvedPrimitiveType.INT)));
assertTrue(rObject.isAssignableBy(array(ResolvedPrimitiveType.BYTE)));
assertTrue(rObject.isAssignableBy(array(ResolvedPrimitiveType.SHORT)));
assertTrue(rObject.isAssignableBy(array(ResolvedPrimitiveType.CHAR)));
assertTrue(rObject.isAssignableBy(array(rString)));
}
@Test
void cloneableIsAssignableByAnyArrayOfPrimitiveTypeOrReference() {
assertTrue(rCloneable.isAssignableBy(array(ResolvedPrimitiveType.DOUBLE)));
assertTrue(rCloneable.isAssignableBy(array(ResolvedPrimitiveType.FLOAT)));
assertTrue(rCloneable.isAssignableBy(array(ResolvedPrimitiveType.LONG)));
assertTrue(rCloneable.isAssignableBy(array(ResolvedPrimitiveType.INT)));
assertTrue(rCloneable.isAssignableBy(array(ResolvedPrimitiveType.BYTE)));
assertTrue(rCloneable.isAssignableBy(array(ResolvedPrimitiveType.SHORT)));
assertTrue(rCloneable.isAssignableBy(array(ResolvedPrimitiveType.CHAR)));
assertTrue(rCloneable.isAssignableBy(array(rString)));
}
@Test
void serializableIsAssignableByAnyArrayOfPrimitiveTypeOrReference() {
assertTrue(rSerializable.isAssignableBy(array(ResolvedPrimitiveType.DOUBLE)));
assertTrue(rSerializable.isAssignableBy(array(ResolvedPrimitiveType.FLOAT)));
assertTrue(rSerializable.isAssignableBy(array(ResolvedPrimitiveType.LONG)));
assertTrue(rSerializable.isAssignableBy(array(ResolvedPrimitiveType.INT)));
assertTrue(rSerializable.isAssignableBy(array(ResolvedPrimitiveType.BYTE)));
assertTrue(rSerializable.isAssignableBy(array(ResolvedPrimitiveType.SHORT)));
assertTrue(rSerializable.isAssignableBy(array(ResolvedPrimitiveType.CHAR)));
assertTrue(rSerializable.isAssignableBy(array(rString)));
}
@Test
void arrayOfSubTypeIsAssignableByArrayOfSuperType() {
assertTrue(array(rCharSequence).isAssignableBy(array(rString)));
}
@Test
void arrayOfReferenceIsNotAssignableByArrayOfOtherReference() {
assertFalse(array(rString).isAssignableBy(array(rCharSequence)));
}
@Test
void arrayOfObjectIsAssignableByArrayOfReference() {
assertTrue(array(rObject).isAssignableBy(array(rLong)));
}
@Test
void arrayOfObjectIsNotAssignableByArrayOfPrimitiveType() {
assertFalse(array(rObject).isAssignableBy(array(ResolvedPrimitiveType.LONG)));
}
private boolean isAssignableBy(ResolvedType type, ResolvedType... types) {
return Arrays.stream(types).anyMatch(t -> type.isAssignableBy(t));
}
private ResolvedArrayType[] arrays(ResolvedType... types) {
return Arrays.stream(types)
.map(t -> array(t))
.collect(Collectors.toList())
.toArray(new ResolvedArrayType[] {});
}
private ResolvedArrayType array(ResolvedType type) {
return new ResolvedArrayType(type);
}
private ResolvedType getType(String code) {
return parser.parse(code)
.findFirst(FieldDeclaration.class)
.get()
.resolve()
.getType();
}
}