Merge "Avoid some duplicate bridge methods" into main
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
index 36d3a2b..116a17c 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
@@ -76,6 +76,8 @@
private final Resolve resolve;
private final CompileStates compileStates;
+ private final boolean skipDuplicateBridges;
+
@SuppressWarnings("this-escape")
protected TransTypes(Context context) {
context.put(transTypesKey, this);
@@ -87,6 +89,8 @@
types = Types.instance(context);
make = TreeMaker.instance(context);
resolve = Resolve.instance(context);
+ Source source = Source.instance(context);
+ skipDuplicateBridges = Options.instance(context).getBoolean("skipDuplicateBridges", false);
annotate = Annotate.instance(context);
attr = Attr.instance(context);
}
@@ -358,6 +362,9 @@
MethodSymbol impl,
Type dest) {
if (impl != method) {
+ if (skipBridge(method, impl, dest)) {
+ return false;
+ }
// If either method or impl have different erasures as
// members of dest, a bridge is needed.
Type method_erasure = method.erasure(types);
@@ -398,6 +405,41 @@
return types.isSameType(erasure(types.memberType(type, method)),
erasure);
}
+ /**
+ * Returns true if a bridge should be skipped because we expect it to be declared in
+ * a super-type.
+ *
+ * @param method The symbol for which a bridge might have to be added
+ * @param impl The implementation of method
+ * @param dest The type in which the bridge would go
+ */
+ private boolean skipBridge(MethodSymbol method,
+ MethodSymbol impl,
+ Type dest) {
+ if (!skipDuplicateBridges) {
+ return false;
+ }
+ if (dest.tsym == impl.owner) {
+ // the method is implemented in the current class; we need to bridge it here
+ return false;
+ }
+ if (!types.isSubtype(
+ types.erasure(impl.owner.type), types.erasure(method.owner.type))) {
+ // the method is implemented in some supertype that is not a subtype of
+ // the declaring type, so the bridge will not have been created in the
+ // implementing class
+ return false;
+ }
+ if (!impl.overrides(method, (TypeSymbol) impl.owner, types, true)) {
+ // the method is implementing in a supertype that is also a subtype
+ // of the declaring type, but the method's signature in the implementing
+ // class does not override its signature in the declaring class
+ return false;
+ }
+ // we don't need to consider visibility for accessibility bridges, because
+ // that happens on a separate code path
+ return true;
+ }
void addBridges(DiagnosticPosition pos,
TypeSymbol i,