mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8174840: Elements.overrides does not check the return type of the methods
Co-authored-by: Pavel Rappo <prappo@openjdk.org> Reviewed-by: liach, darcy
This commit is contained in:
parent
2a4f37cc16
commit
606f2012b0
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -778,6 +778,12 @@ public interface Elements {
|
||||
* elements.getTypeElement("I"));
|
||||
* }
|
||||
*
|
||||
* @apiNote This method examines the method's name, signature, subclass relationship, and accessibility
|
||||
* in determining whether one method overrides another, as specified in JLS {@jls 8.4.8.1}.
|
||||
* In addition, an implementation may have stricter checks including method modifiers, return types and
|
||||
* exception types as described in JLS {@jls 8.4.8.1} and {@jls 8.4.8.3}.
|
||||
* Note that such additional compile-time checks are not guaranteed and may vary between implementations.
|
||||
*
|
||||
* @param overrider the first method, possible overrider
|
||||
* @param overridden the second method, possibly being overridden
|
||||
* @param type the class or interface of which the first method is a member
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file models a few cases where Elements.overrides produces a false
|
||||
* positive which warrants @apiNote.
|
||||
*/
|
||||
|
||||
// S.java does not compile because it violates the JLS rules for overrides
|
||||
class S {
|
||||
|
||||
public void m() { }
|
||||
}
|
||||
|
||||
// `protected` is a weaker modifier than `public`
|
||||
class T1 extends S {
|
||||
|
||||
protected void m() { }
|
||||
}
|
||||
|
||||
// `package-private` is a weaker modifier than `public`
|
||||
class T2 extends S {
|
||||
|
||||
void m() { }
|
||||
}
|
||||
|
||||
// `private` methods cannot override public method
|
||||
class T3 extends S {
|
||||
|
||||
private void m() { }
|
||||
}
|
||||
|
||||
// return type int is not compatible with void
|
||||
class T4 extends S {
|
||||
|
||||
public int m() { return 0; }
|
||||
}
|
||||
|
||||
// adding a checked exception violates the override rule
|
||||
class T5 extends S {
|
||||
|
||||
public void m() throws Exception { }
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code 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 General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8174840
|
||||
* @library /tools/javac/lib
|
||||
* @build JavacTestingAbstractProcessor TestOverrides
|
||||
* @compile -processor TestOverrides -proc:only S.java
|
||||
*/
|
||||
|
||||
import java.util.Set;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
import static javax.lang.model.element.ElementKind.METHOD;
|
||||
|
||||
public class TestOverrides extends JavacTestingAbstractProcessor {
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment round) {
|
||||
if (!round.processingOver()) {
|
||||
var sm = mIn(elements.getTypeElement("S"));
|
||||
for (var subtypeName : new String[]{"T1", "T2", "T3", "T4", "T5"}) {
|
||||
var t = elements.getTypeElement(subtypeName);
|
||||
var tm = mIn(t);
|
||||
if (!elements.overrides(tm, sm, t))
|
||||
messager.printError(String.format(
|
||||
"%s does not override from %s method %s", tm, t.getQualifiedName(), sm));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ExecutableElement mIn(TypeElement t) {
|
||||
return t.getEnclosedElements().stream()
|
||||
.filter(e -> e.getKind() == METHOD)
|
||||
.filter(e -> e.getSimpleName().toString().equals("m"))
|
||||
.map(e -> (ExecutableElement) e)
|
||||
.findAny()
|
||||
.get();
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user