diff --git a/java-frontend/src/main/java/org/sonar/java/model/JTypeSymbol.java b/java-frontend/src/main/java/org/sonar/java/model/JTypeSymbol.java index 923210d7afc..681b6338614 100644 --- a/java-frontend/src/main/java/org/sonar/java/model/JTypeSymbol.java +++ b/java-frontend/src/main/java/org/sonar/java/model/JTypeSymbol.java @@ -67,7 +67,8 @@ public Type type() { // for "T.super.foo()", if T is an interface, 'super' keyword is used to access method of the interface itself return JTypeSymbol.this.type(); } - return JTypeSymbol.this.superClass(); + Type superClass = JTypeSymbol.this.superClass(); + return superClass == null ? Symbols.unknownType : superClass; } }; diff --git a/java-frontend/src/test/java/org/sonar/java/model/JSymbolTest.java b/java-frontend/src/test/java/org/sonar/java/model/JSymbolTest.java index 10a407b0445..b0ac4236915 100644 --- a/java-frontend/src/test/java/org/sonar/java/model/JSymbolTest.java +++ b/java-frontend/src/test/java/org/sonar/java/model/JSymbolTest.java @@ -30,9 +30,12 @@ import org.sonar.plugins.java.api.semantic.Symbol; import org.sonar.plugins.java.api.semantic.Type; import org.sonar.plugins.java.api.tree.ClassTree; +import org.sonar.plugins.java.api.tree.ExpressionStatementTree; import org.sonar.plugins.java.api.tree.IdentifierTree; import org.sonar.plugins.java.api.tree.LambdaExpressionTree; import org.sonar.plugins.java.api.tree.MemberSelectExpressionTree; +import org.sonar.plugins.java.api.tree.MethodInvocationTree; +import org.sonar.plugins.java.api.tree.MethodTree; import org.sonar.plugins.java.api.tree.VariableTree; import static org.assertj.core.api.Assertions.assertThat; @@ -217,6 +220,23 @@ void record_enclosingClass() { .hasEnclosingClass(cu.sema.typeSymbol(c2.typeBinding)); } + @Test + void super_keyword_in_the_java_lang_Object_scope_has_unknown_type_instead_of_null() { + JavaTree.CompilationUnitTreeImpl cu = test("" + + "package java.lang;\n" + + "class Object {\n" + + " void foo() { super.hashCode(); }\n" + + "}"); + ClassTree objectClass = (ClassTree) cu.types().get(0); + MethodTree fooMethod = (MethodTree) objectClass.members().get(0); + ExpressionStatementTree firstStatement = (ExpressionStatementTree) fooMethod.block().body().get(0); + MethodInvocationTree hashCodeInvocation = (MethodInvocationTree) firstStatement.expression(); + MemberSelectExpressionTree methodSelect = (MemberSelectExpressionTree) hashCodeInvocation.methodSelect(); + KeywordSuper keywordSuper = (KeywordSuper) methodSelect.expression(); + + assertThat(keywordSuper.symbolType()).isEqualTo(Symbols.unknownType); + } + private void variable_in_class_initializer(boolean isStatic) { String src = "enum E { C; " + (isStatic ? "static " : "") + "{ int i; } }"; JavaTree.CompilationUnitTreeImpl cu = test(src);