/*
* SonarQube Java
* Copyright (C) 2012-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of 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.
*
* This program 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.java.model.declaration;
import com.google.common.collect.Lists;
import com.sonar.sslr.api.typed.ActionParser;
import org.junit.Test;
import org.sonar.java.ast.parser.JavaParser;
import org.sonar.java.resolve.Flags;
import org.sonar.java.resolve.JavaSymbol;
import org.sonar.java.resolve.SemanticModel;
import org.sonar.plugins.java.api.tree.ClassTree;
import org.sonar.plugins.java.api.tree.CompilationUnitTree;
import java.io.File;
import java.nio.charset.StandardCharsets;
import static org.assertj.core.api.Assertions.assertThat;
public class MethodTreeImplTest {
private final ActionParser p = JavaParser.createParser(StandardCharsets.UTF_8);
@Test
public void override_without_annotation_should_be_detected() {
CompilationUnitTree cut = createTree("interface T { int m(); } class A implements T { int m(){return 0;}}");
ClassTree interfaze = (ClassTree) cut.types().get(0);
MethodTreeImpl methodInterface = (MethodTreeImpl) interfaze.members().get(0);
ClassTree clazz = (ClassTree) cut.types().get(1);
MethodTreeImpl methodClazz = (MethodTreeImpl) clazz.members().get(0);
assertThat(methodInterface.isOverriding()).isFalse();
assertThat(methodClazz.isOverriding()).isTrue();
}
@Test
public void override_with_generic_parameters_should_be_detected() throws Exception {
CompilationUnitTree cut = createTree("public class ReferenceQueue<T> {\n" +
"\n" +
" private static class Null extends ReferenceQueue {\n" +
" boolean enqueue(Reference r) {\n" +
" return false;\n" +
" }\n" +
" }\n" +
" boolean enqueue(Reference<? extends T> r) {}}" +
"public abstract class Reference<T> {}");
ClassTree innerClass = (ClassTree) cut.types().get(0);
MethodTreeImpl methodInterface = (MethodTreeImpl) ((ClassTree) innerClass.members().get(0)).members().get(0);
assertThat(methodInterface.isOverriding()).isTrue();
}
@Test
public void hiding_of_static_methods() {
CompilationUnitTree cut = createTree("class A { static void foo() {} } class B extends A { void foo(){} } ");
ClassTree clazz = (ClassTree) cut.types().get(1);
MethodTreeImpl methodTree = (MethodTreeImpl) clazz.members().get(0);
assertThat(methodTree.isOverriding()).isFalse();
}
@Test
public void override_from_object_should_be_detected() {
MethodTreeImpl method = getUniqueMethod("class A { String toString(){return \"\";}}");
assertThat(method.isOverriding()).isTrue();
}
@Test
public void override_unknown() {
MethodTreeImpl method = getUniqueMethod("class A extends Unknown { void foo(){}}");
assertThat(method.isOverriding()).isNull();
}
@Test
public void static_method_cannot_be_overriden() {
assertThat(getUniqueMethod("class A{ static void m(){}}").isOverriding()).isFalse();
}
@Test
public void private_method_cannot_be_overriden() {
assertThat(getUniqueMethod("class A{ private void m(){}}").isOverriding()).isFalse();
}
@Test
public void override_annotated_method_should_be_overriden() {
assertThat(getUniqueMethod("class A{ @Override void m(){}}").isOverriding()).isTrue();
assertThat(getUniqueMethod("class A{ @Foo @Override void m(){}}").isOverriding()).isTrue();
assertThat(getUniqueMethod("class A{ @java.lang.Override void m(){}}").isOverriding()).isTrue();
assertThat(getUniqueMethod("class A{ @cutom.namespace.Override void m(){}}").isOverriding()).isFalse();
assertThat(getUniqueMethod("class A{ @foo.bar.lang.Override void m(){}}").isOverriding()).isFalse();
assertThat(getUniqueMethod("class A{ @foo.lang.Override void m(){}}").isOverriding()).isFalse();
assertThat(getUniqueMethod("class A{ @Foo void m(){}}").isOverriding()).isFalse();
}
@Test
public void symbol_not_set_should_lead_to_null_result() throws Exception {
CompilationUnitTree cut = (CompilationUnitTree) p.parse("class A { String toString(){return \"\";}}");
MethodTreeImpl methodTree = (MethodTreeImpl) ((ClassTree) cut.types().get(0)).members().get(0);
assertThat(methodTree.isOverriding()).isNull();
}
@Test
public void has_all_syntax_token() {
MethodTreeImpl method = getUniqueMethod("class A { public void foo(int arg) throws Exception {} }");
assertThat(method.openParenToken()).isNotNull();
assertThat(method.closeParenToken()).isNotNull();
assertThat(method.semicolonToken()).isNull();
assertThat(method.throwsToken()).isNotNull();
method = getUniqueMethod("abstract class A { public abstract void foo(int arg); }");
assertThat(method.openParenToken()).isNotNull();
assertThat(method.closeParenToken()).isNotNull();
assertThat(method.semicolonToken()).isNotNull();
assertThat(method.throwsToken()).isNull();
}
@Test
public void is_main_method() throws Exception {
assertThat(getUniqueMethod("class A { public static void main(String[] args){} }").isMainMethod()).isTrue();
assertThat(getUniqueMethod("class A { public static void main(String... args){} }").isMainMethod()).isTrue();
assertThat(getUniqueMethod("class A { public void main(String[] args){} }").isMainMethod()).isFalse();
assertThat(getUniqueMethod("class A { static void main(String[] args){} }").isMainMethod()).isFalse();
assertThat(getUniqueMethod("class A { public static void amain(String[] args){} }").isMainMethod()).isFalse();
assertThat(getUniqueMethod("class A { public static void main(String args){} }").isMainMethod()).isFalse();
assertThat(getUniqueMethod("class A { public static int main(String[] args){} }").isMainMethod()).isFalse();
assertThat(getUniqueMethod("class A { public static void main(String[] args, String[] second){} }").isMainMethod()).isFalse();
}
@Test
public void is_equals_method() throws Exception {
assertThat(getUniqueMethod("class A { public boolean equals(Object o){} }").isEqualsMethod()).isTrue();
assertThat(getUniqueMethod("class A { private boolean equals(Object o){} }").isEqualsMethod()).isFalse();
assertThat(getUniqueMethod("class A { public static boolean equals(Object o){} }").isEqualsMethod()).isFalse();
assertThat(getUniqueMethod("class A { public boolean equal(Object o){} }").isEqualsMethod()).isFalse();
assertThat(getUniqueMethod("class A { public boolean equals(Object o, int a){} }").isEqualsMethod()).isFalse();
assertThat(getUniqueMethod("class A { public boolean equals(int a){} }").isEqualsMethod()).isFalse();
assertThat(getUniqueMethod("class equals { public equals(Object o){} }").isEqualsMethod()).isFalse();
assertThat(getUniqueMethod("interface I { public abstract boolean equals(Object o); }").isEqualsMethod()).isTrue();
}
@Test
public void is_hashcode_method() throws Exception {
assertThat(getUniqueMethod("class A { public int hashCode(){} }").isHashCodeMethod()).isTrue();
assertThat(getUniqueMethod("class A { public static int hashCode(){} }").isHashCodeMethod()).isFalse();
assertThat(getUniqueMethod("class A { private int hashCode(){} }").isHashCodeMethod()).isFalse();
assertThat(getUniqueMethod("class A { public int hashcode(){} }").isHashCodeMethod()).isFalse();
assertThat(getUniqueMethod("class A { public boolean hashCode(){} }").isHashCodeMethod()).isFalse();
assertThat(getUniqueMethod("class A { public int hashCode(int a){} }").isHashCodeMethod()).isFalse();
}
@Test
public void is_toString_method() throws Exception {
assertThat(getUniqueMethod("class A { public String toString(){} }").isToStringMethod()).isTrue();
assertThat(getUniqueMethod("class A { public java.lang.String toString(){} }").isToStringMethod()).isTrue();
assertThat(getUniqueMethod("class A { public static String toString(){} }").isToStringMethod()).isFalse();
assertThat(getUniqueMethod("class A { private String toString(){} }").isToStringMethod()).isFalse();
assertThat(getUniqueMethod("class A { public String tostring(){} }").isToStringMethod()).isFalse();
assertThat(getUniqueMethod("class A { public int toString(){} }").isToStringMethod()).isFalse();
assertThat(getUniqueMethod("class A { public String toString(String foo){} }").isToStringMethod()).isFalse();
}
@Test
public void varargs_flag() {
JavaSymbol.MethodJavaSymbol methodSymbol = (JavaSymbol.MethodJavaSymbol) getUniqueMethod("class A { public static void main(String[] args){} }").symbol();
assertThat((methodSymbol.flags() & Flags.VARARGS) != 0).isFalse();
methodSymbol = (JavaSymbol.MethodJavaSymbol) getUniqueMethod("class A { public static void main(String... args){} }").symbol();
assertThat((methodSymbol.flags() & Flags.VARARGS) != 0).isTrue();
}
private MethodTreeImpl getUniqueMethod(String code) {
CompilationUnitTree cut = createTree(code);
return (MethodTreeImpl) ((ClassTree) cut.types().get(0)).members().get(0);
}
private CompilationUnitTree createTree(String code) {
CompilationUnitTree compilationUnitTree = (CompilationUnitTree) p.parse(code);
SemanticModel.createFor(compilationUnitTree, Lists.<File>newArrayList());
return compilationUnitTree;
}
}