Skip to content

Commit d1e2465

Browse files
SONARJAVA-6268 Fix issue in primitveType() and primitiveWrapperType() when the sema is incomplete (#5579)
Co-authored-by: Lucien Bart <lucien.bart@sonarsource.com>
1 parent 6fb40a9 commit d1e2465

2 files changed

Lines changed: 56 additions & 4 deletions

File tree

java-frontend/src/main/java/org/sonar/java/model/JType.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,11 @@ public Type primitiveWrapperType() {
137137
if (name == null) {
138138
return null;
139139
}
140-
primitiveWrapperType = sema.type(sema.resolveType(name));
140+
ITypeBinding resolvedType = sema.resolveType(name);
141+
if (resolvedType == null) {
142+
return null;
143+
}
144+
primitiveWrapperType = sema.type(resolvedType);
141145
}
142146
return primitiveWrapperType;
143147
}
@@ -150,7 +154,11 @@ public Type primitiveType() {
150154
if (name == null) {
151155
return null;
152156
}
153-
primitiveType = sema.type(sema.resolveType(name));
157+
ITypeBinding resolvedType = sema.resolveType(name);
158+
if (resolvedType == null) {
159+
return null;
160+
}
161+
primitiveType = sema.type(resolvedType);
154162
}
155163
return primitiveType;
156164
}

java-frontend/src/test/java/org/sonar/java/model/JTypeTest.java

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,50 @@ void primitiveType(){
145145
assertThat(byteType.primitiveType()).isNotEqualTo(type("boolean"));
146146
}
147147

148+
@Test
149+
void primitiveWrapperType(){
150+
Type booleanType = type("boolean");
151+
assertThat(booleanType.primitiveWrapperType()).isEqualTo(type("java.lang.Boolean"));
152+
assertThat(booleanType.primitiveWrapperType()).isNotEqualTo(type("java.lang.Byte"));
153+
}
154+
155+
@Test
156+
void non_primitive_type_has_no_primitive() {
157+
Type stringType = type("java.lang.String");
158+
assertThat(stringType.primitiveType()).isNull();
159+
}
160+
161+
@Test
162+
void non_primitive_wrapper_tpe_has_no_primitive_wrapper() {
163+
Type stringType = type("java.lang.String");
164+
assertThat(stringType.primitiveWrapperType()).isNull();
165+
}
166+
167+
@Test
168+
void primitiveWrapperType_returns_null_when_semantic_cannot_resolve_wrapper_type() {
169+
// Sema that can resolve primitives, but fails to resolve wrapper types, which can happen when the classpath is not correctly set up
170+
var brokenSema = spy(sema);
171+
when(brokenSema.resolveType("java.lang.Byte")).thenReturn(null);
172+
173+
var primitiveBinding = sema.resolveType("byte");
174+
var primitiveType = new JType(brokenSema, primitiveBinding);
175+
176+
assertThat(primitiveType.primitiveWrapperType()).isNull();
177+
}
178+
179+
@Test
180+
void primitiveType_returns_null_when_semantic_cannot_resolve_primitive_type() {
181+
// Sema that can resolve wrapper types, but fails to resolve a primitive, this should never happen in practice,
182+
// but we want to make sure it doesn't throw an exception and returns null instead
183+
var brokenSema = spy(sema);
184+
when(brokenSema.resolveType("byte")).thenReturn(null);
185+
186+
var wrapperBinding = sema.resolveType("java.lang.Byte");
187+
var wrapperType = new JType(brokenSema, wrapperBinding);
188+
189+
assertThat(wrapperType.primitiveType()).isNull();
190+
}
191+
148192
@Test
149193
void declaringType(){
150194
Type byteType = type("java.lang.Byte");
@@ -166,15 +210,15 @@ void isNumerical() {
166210
}
167211

168212
@ParameterizedTest
169-
@MethodSource("names")
213+
@MethodSource("fullyQualifiedNamesToNames")
170214
void names(String expectedFullyQualifiedName, String expectedName) {
171215
assertThat(type(expectedFullyQualifiedName))
172216
.is(expectedFullyQualifiedName)
173217
.hasName(expectedName)
174218
.hasToString(expectedName);
175219
}
176220

177-
private static Stream<Arguments> names() {
221+
private static Stream<Arguments> fullyQualifiedNamesToNames() {
178222
return Stream.of(
179223
Arguments.of("int", "int"),
180224
Arguments.of("int[][]", "int[][]"),

0 commit comments

Comments
 (0)