Skip to content

Commit

Permalink
Disable overriding methods in final classes. (square#626)
Browse files Browse the repository at this point in the history
  • Loading branch information
NightlyNexus authored and swankjesse committed Mar 4, 2018
1 parent b314337 commit ee82208
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/main/java/com/squareup/javapoet/MethodSpec.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Map;
import java.util.Set;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeParameterElement;
Expand Down Expand Up @@ -188,6 +189,11 @@ public static Builder constructorBuilder() {
public static Builder overriding(ExecutableElement method) {
checkNotNull(method, "method == null");

Element enclosingClass = method.getEnclosingElement();
if (enclosingClass.getModifiers().contains(Modifier.FINAL)) {
throw new IllegalArgumentException("Cannot override method on final class " + enclosingClass);
}

Set<Modifier> modifiers = method.getModifiers();
if (modifiers.contains(Modifier.PRIVATE)
|| modifiers.contains(Modifier.FINAL)
Expand Down
17 changes: 17 additions & 0 deletions src/test/java/com/squareup/javapoet/MethodSpecTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ interface ExtendsOthers extends Callable<Integer>, Comparable<ExtendsOthers> {
interface ExtendsIterableWithDefaultMethods extends Iterable<Object> {
}

final class FinalClass {
void method() {
}
}

@Test public void overrideEverything() {
TypeElement classElement = getElement(Everything.class);
ExecutableElement methodElement = getOnlyElement(methodsIn(classElement.getEnclosedElements()));
Expand Down Expand Up @@ -177,6 +182,18 @@ interface ExtendsIterableWithDefaultMethods extends Iterable<Object> {
+ "}\n");
}

@Test public void overrideFinalClassMethod() {
TypeElement classElement = getElement(FinalClass.class);
List<ExecutableElement> methods = methodsIn(elements.getAllMembers(classElement));
try {
MethodSpec.overriding(findFirst(methods, "method"));
fail();
} catch (IllegalArgumentException expected) {
assertThat(expected).hasMessageThat().isEqualTo(
"Cannot override method on final class com.squareup.javapoet.MethodSpecTest.FinalClass");
}
}

@Test public void overrideInvalidModifiers() {
ExecutableElement method = mock(ExecutableElement.class);
when(method.getModifiers()).thenReturn(ImmutableSet.of(Modifier.FINAL));
Expand Down

0 comments on commit ee82208

Please sign in to comment.