--- old/test/TEST.groups 2015-04-17 16:07:50.753361120 -0400 +++ new/test/TEST.groups 2015-04-17 16:07:50.629359685 -0400 @@ -411,6 +411,7 @@ -runtime/Metaspace/FragmentMetaspace.java \ -runtime/Metaspace/FragmentMetaspaceSimple.java \ -runtime/Thread/TestThreadDumpMonitorContention.java \ + -runtime/Selection/Resolution \ -runtime/SharedArchiveFile/SharedBaseAddress.java \ -runtime/memory/ReserveMemory.java \ -runtime/Unsafe/RangeCheck.java \ --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/Builder.java 2015-04-17 16:07:51.165365888 -0400 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013, 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. + * + */ + +import java.util.HashMap; + +abstract class Builder { + protected final SelectionResolutionTestCase testcase; + protected final HierarchyShape hier; + protected final HashMap classdata; + + public Builder(SelectionResolutionTestCase testcase) { + this.testcase = testcase; + this.hier = testcase.hier; + this.classdata = testcase.classdata; + } + + protected String getName(int id) { + StringBuilder name = new StringBuilder(); + + name.append(getPackageName(classdata.get(id).packageId.ordinal())); + + // Name classes C and interfaces I + name.append(getClassName(id)); + + return name.toString(); + } + + protected String getPackageName(int packageId) { + return "P" + packageId + "/"; + } + + protected String getClassName(int id) { + // Name classes C and interfaces I + if (isClass(id)) { + return "C" + id; + } else { + return "I" + id; + } + } + + protected boolean isClass(int id) { + return hier.isClass(id); + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/ByteCodeClassLoader.java 2015-04-17 16:07:51.576370645 -0400 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014, 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. + * + */ + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; + + +public class ByteCodeClassLoader extends ClassLoader { + ArrayList classes = new ArrayList<>(); + HashMap loadedClasses = new HashMap<>(); + + public void addClasses(ClassConstruct... classes) { + this.classes.addAll(Arrays.asList(classes)); + } + + public void loadAll() throws ClassNotFoundException { + for (ClassConstruct clazz : classes) { + findClass(clazz.getDottedName()); + } + } + + + @Override + public Class findClass(String name) throws ClassNotFoundException { + + Class cls = loadedClasses.get(name); + + if (cls != null) { + return cls; + } + + for (ClassConstruct clazz : classes) { + if (clazz.getDottedName().equals(name)) { + return load(clazz); + } + } + + throw new ClassNotFoundException(name); + } + + @Override + public Class loadClass(String name) throws ClassNotFoundException { + try { + return findClass(name); + } catch (ClassNotFoundException e) { + return super.loadClass(name); + } + } + + private Class load(ClassConstruct clazz) { + byte[] bytecode = clazz.generateBytes(); + Class loadedClass = defineClass(clazz.getDottedName(), bytecode, 0, bytecode.length); + loadedClasses.put(clazz.getDottedName(), loadedClass); + return loadedClass; + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/ClassBuilder.java 2015-04-17 16:07:51.977375286 -0400 @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2013, 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. + * + */ + +import static jdk.internal.org.objectweb.asm.Opcodes.*; + +import java.util.ArrayList; +import java.util.Iterator; + +/** + * Constructs classes and interfaces based on the information from a + * DefaultMethodTestCase + * + */ +public class ClassBuilder extends Builder { + private final ArrayList classes; + + // Add a class in every package to be able to instantiate package + // private classes from outside the package + private final Clazz[] helpers = new Clazz[4]; + private ClassConstruct callsiteClass; + + public enum ExecutionMode { DIRECT, INDY, MH_INVOKE_EXACT, MH_INVOKE_GENERIC} + private final ExecutionMode execMode; + + public ClassBuilder(SelectionResolutionTestCase testcase, + ExecutionMode execMode) { + super(testcase); + this.classes = new ArrayList<>(); + this.execMode = execMode; + } + + public ClassConstruct[] build() throws Exception { + buildClassConstructs(); + return classes.toArray(new ClassConstruct[0]); + } + + public ClassConstruct getCallsiteClass() { + return callsiteClass; + } + + private void buildClassConstructs() throws Exception { + TestBuilder tb = new TestBuilder(testcase.methodref, testcase); + + classes.add(new Clazz("Test", ACC_PUBLIC, -1)); + + for (int classId = 0; classId < classdata.size(); classId++) { + ClassConstruct C; + String[] interfaces = getInterfaces(classId); + ClassData data = classdata.get(classId); + + if (isClass(classId)) { + C = new Clazz(getName(classId), + getExtending(classId), + getClassModifiers(data), + classId, + interfaces); + + addHelperMethod(classId); + + } else { + C = new Interface(getName(classId), + getAccessibility(data.access), + classId, interfaces); + } + + // Add a method "m()LTestObject;" if applicable + if (containsMethod(data)) { + // Method will either be abstract or concrete depending on the + // abstract modifier + C.addTestMethod(getMethodModifiers(data)); + } + + if (classId == testcase.callsite) { + // Add test() method + tb.addTest(C, execMode); + callsiteClass = C; + } + + classes.add(C); + } + classes.add(tb.getMainTestClass()); + + } + + private void addHelperMethod(int classId) { + int packageId = classdata.get(classId).packageId.ordinal(); + Clazz C = helpers[packageId]; + if (C == null) { + C = new Clazz(getPackageName(packageId) + "Helper", -1, ACC_PUBLIC); + helpers[packageId] = C; + classes.add(C); + } + + Method m = C.addMethod("get" + getClassName(classId), + "()L" + getName(classId) + ";", + ACC_PUBLIC + ACC_STATIC); + m.makeInstantiateMethod(getName(classId)); + } + + private String[] getInterfaces(int classId) { + ArrayList interfaces = new ArrayList<>(); + + // Figure out if we're extending/implementing an interface + for (final int intf : hier.interfaces()) { + if (hier.inherits(classId, intf)) { + interfaces.add(getName(intf)); + } + } + return interfaces.toArray(new String[0]); + } + + private String getExtending(int classId) { + int extending = -1; + + // See if we're extending another class + for (final int extendsClass : hier.classes()) { + if (hier.inherits(classId, extendsClass)) { + // Sanity check that we haven't already found an extending class + if (extending != -1) { + throw new RuntimeException("Multiple extending classes"); + } + extending = extendsClass; + } + } + + return extending == -1 ? null : getName(extending); + } + + /** + * Returns modifiers for a Class + * @param cd ClassData for the Class + * @return ASM modifiers for a Class + */ + private int getClassModifiers(ClassData cd) { + // For Classes we only care about accessibility (public, private etc) + return getAccessibility(cd.access) | getAbstraction(cd.abstraction); + } + + /** + * Returns modifiers for Method type + * @param cd ClassData for the Class or Interface where the Method resides + * @return ASM modifiers for the Method + */ + private int getMethodModifiers(ClassData cd) { + int mod = 0; + + // For methods we want everything + mod += getAccessibility(cd.methoddata.access); + mod += getAbstraction(cd.methoddata.context); + mod += getContext(cd.methoddata.context); + mod += getExtensibility(); + return mod; + } + + + /** + * Convert ClassData access type to ASM + * @param access + * @return ASM version of accessibility (public / private / protected) + */ + private int getAccessibility(MethodData.Access access) { + switch(access) { + case PACKAGE: + //TODO: Do I need to set this or will this be the default? + return 0; + case PRIVATE: + return ACC_PRIVATE; + case PROTECTED: + return ACC_PROTECTED; + case PUBLIC: + return ACC_PUBLIC; + default: + throw new RuntimeException("Illegal accessibility modifier: " + access); + } + } + + /** + * Convert ClassData abstraction type to ASM + * @param abstraction + * @return ASM version of abstraction (abstract / non-abstract) + */ + private int getAbstraction(MethodData.Context context) { + return context == MethodData.Context.ABSTRACT ? ACC_ABSTRACT : 0; + } + + /** + * Convert ClassData context type to ASM + * @param context + * @return ASM version of context (static / non-static) + */ + private int getContext(MethodData.Context context) { + return context == MethodData.Context.STATIC ? ACC_STATIC : 0; + } + + /** + * Convert ClassData extensibility type to ASM + * @param extensibility + * @return ASM version of extensibility (final / non-final) + */ + private int getExtensibility() { + return 0; + } + + /** + * Determine if we need a method at all, abstraction is set to null if this + * Class/Interface should not have a test method + * @param cd + * @return + */ + private boolean containsMethod(ClassData cd) { + return cd.methoddata != null; + } + +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/ClassConstruct.java 2015-04-17 16:07:52.327379337 -0400 @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2014, 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. + * + */ + +import java.io.File; +import java.io.FileOutputStream; +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.Opcodes; + +public abstract class ClassConstruct { + private final ClassWriter cw; + private final String name; + private final boolean isInterface; + private final int index; + + /** + * Base constructor for building a Class or Interface + * @param name Name of Class/Interface, including package name + * @param extending Name of extending Class if any + * @param access Access for Class/Interface + * @param classFileVersion Class file version + * @param interfaces Interface implemented + */ + public ClassConstruct(String name, + String extending, + int access, + int classFileVersion, + int index, + String... interfaces) { + this.name = name; + isInterface = (access & Opcodes.ACC_INTERFACE) == Opcodes.ACC_INTERFACE; + cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); + cw.visit(classFileVersion, access, name, null, extending, interfaces == null ? new String[] { } : interfaces); + this.index = index; + } + + /** + * Get full Class/Interface name including package name, as it + * should appear in a classfile. + * + * @return The full Class/Interface name including package name + */ + public String getName() { + return name; + } + + /** + * Get the name of the class, including package as it would appear + * in Java source. + * + * @return The name of the class as it would appear in Java source. + */ + public String getDottedName() { + return name.replace("/", "."); + } + + public String getPackageName() { + final int idx = name.lastIndexOf('/'); + if (idx != -1) { + return name.substring(0, name.indexOf('/')); + } else { + return null; + } + } + + public String getClassName() { + final int idx = name.lastIndexOf('/'); + if (idx != -1) { + return name.substring(name.indexOf('/')); + } else { + return name; + } + } + + /** + * Add a method, no code associated with it yet + * @param name Name of method + * @param descriptor Descriptor for method + * @param access Access for the method + * @return Method object that can be used for constructing a method body + */ + public Method addMethod(String name, + String descriptor, + int access) { + return addMethod(name, descriptor, access, null); + } + + /** + * Add a method, no code associated with it yet + * @param name Name of method + * @param descriptor Descriptor for method + * @param access Access for the method + * @param execMode The execution mode for the method. + * @return Method object that can be used for constructing a method body + */ + public Method addMethod(String name, + String descriptor, + int access, + ClassBuilder.ExecutionMode execMode) { + return new Method(this, cw, name, descriptor, access, execMode); + } + + /** + * Adds a m()LTestObject; method which returns null unless the method is abstract + * @param access Access for the method + */ + public void addTestMethod(int access) { + Method m = new Method(this, cw, Method.defaultMethodName, Method.defaultMethodDescriptor, access, null); + if ((access & Opcodes.ACC_ABSTRACT) != Opcodes.ACC_ABSTRACT) { + m.makeDefaultMethod(); + } + } + + /** + * Construct the class to a byte[] + * @return byte[] with class file + */ + public byte[] generateBytes() { + cw.visitEnd(); + return cw.toByteArray(); + } + + /** + * Write out a class to a file in the specified directory. + * + * @param dir Directory to which to write out the file. + */ + public void writeClass(final File dir) throws Exception { + final String pkgname = getPackageName(); + final File pkgdir = pkgname != null ? new File(dir, getPackageName()) : dir; + pkgdir.mkdirs(); + final File out = new File(pkgdir, getClassName() + ".class"); + out.createNewFile(); + try (final FileOutputStream fos = new FileOutputStream(out)) { + fos.write(generateBytes()); + } + } + + public boolean isInterface() { + return isInterface; + } + + public Integer getIndex() { + return index; + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/ClassData.java 2015-04-17 16:07:52.731384013 -0400 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014, 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. + */ + +/** + * A representation of information about a class. Note that classes + * here define only one method. + */ +public class ClassData { + + public enum Package { + /** + * Same package as the callsite. + */ + SAME, + /** + * Different package from the callsite. + */ + DIFFERENT, + /** + * Same as DIFFERENT, and also implies that the class access + * is package-private. + */ + INACCESSIBLE, + /** + * Different from everything else. Used in selection only, to + * test skipping package-private definitions. + */ + OTHER, + /** + * Placeholder, used solely by the template dumper for + * printing out the effects of templates. Don't use for + * anything else. + */ + PLACEHOLDER; + } + + /** + * The package ID for the class. + */ + public final Package packageId; + + /** + * The method data for the method definition. If there is no + * method definition, this will be null. + */ + public final MethodData methoddata; + + /** + * The class access. Note that this is controlled by the packageId. + */ + public final MethodData.Access access; + + // This is a hardwired value necessary for ClassBuilder + public final MethodData.Context abstraction = MethodData.Context.INSTANCE; + + public ClassData(final Package packageId, + final MethodData methoddata) { + this.packageId = packageId; + this.methoddata = methoddata; + + if (packageId == Package.INACCESSIBLE) + access = MethodData.Access.PACKAGE; + else + access = MethodData.Access.PUBLIC; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(" { "); + + if (methoddata != null) { + sb.append(methoddata); + } + + sb.append(" }\n\n"); + + return sb.toString(); + } + +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/Clazz.java 2015-04-17 16:07:53.070387937 -0400 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, 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. + * + */ + +import static jdk.internal.org.objectweb.asm.Opcodes.*; + +class Clazz extends ClassConstruct { + + /** + * Construct a Class + * @param name Name of Class + * @param access Access for the Class + */ + public Clazz(String name, int access, int index) { + this(name, null, access, V1_8, index, new String[] { }); + } + + /** + * Construct a Class + * @param name Name of Class + * @param extending Class being extended + * @param access Access for the Class + */ + public Clazz(String name, String extending, int access, int index) { + this(name, extending, access, V1_8, index, new String[] { }); + } + + /** + * Construct a Class + * @param name Name of Class + * @param extending Class being extended + * @param access access for the Class + * @param implementing Interfaces implemented + */ + public Clazz(String name, String extending, int access, int index, String... implementing) { + this(name, extending, access, V1_8, index, implementing); + } + + /** + * Construct a Class + * @param name Name of Class + * @param extending Class being extended + * @param access Access for the Class + * @param classFileVersion Class file version + * @param implementing Interfaces implemented + */ + public Clazz(String name, String extending, int access, int classFileVersion, int index, String... implementing) { + super(name, extending == null ? "java/lang/Object" : extending, access + ACC_SUPER, classFileVersion, index, implementing); + // Add the default constructor + addMethod("", "()V", ACC_PUBLIC).makeConstructor(extending); + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/HierarchyShape.java 2015-04-17 16:07:53.448392311 -0400 @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2014, 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. + * + */ + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.Map; + +/** + * A representation of a class/interface hierarchy graph (just the + * graph; the class data is represented elsewhere). + */ +public class HierarchyShape { + public static final int OBJECT_CLASS = -1; + + protected int maxId; + + /** + * The names of all the classes. + */ + private final HashSet classes; + + /** + * The names of all the interfaces. + */ + private final HashSet interfaces; + private final HashMap> extensions; + + /** + * Create an empty hierarchy shape. + */ + public HierarchyShape() { + this(0, new HashSet<>(), new HashSet<>(), new HashMap<>()); + } + + private HierarchyShape(final int maxId, + final HashSet classes, + final HashSet interfaces, + final HashMap> extensions) { + this.maxId = maxId; + this.classes = classes; + this.interfaces = interfaces; + this.extensions = extensions; + } + + /** + * Make a copy of this hierarchy shape. + */ + public HierarchyShape copy() { + final HashMap> newextensions = new HashMap<>(); + + for(final Map.Entry> entry : + extensions.entrySet()) { + newextensions.put(entry.getKey(), + (HashSet)entry.getValue().clone()); + } + + return new HierarchyShape(maxId, (HashSet) classes.clone(), + (HashSet) interfaces.clone(), + newextensions); + } + + /** + * Add a class, and return its id. + * + * @return The new class id. + */ + public int addClass() { + final int id = maxId++; + classes.add(id); + return id; + } + + /** + * Add an interface, and return its id. + * + * @return The new interface id. + */ + public int addInterface() { + final int id = maxId++; + interfaces.add(id); + return id; + } + + /** + * Add an inheritance. + * + * @param sub The sub class/interface. + * @param sup The super class/interface + */ + public void addInherit(final int sub, + final int sup) { + HashSet ext = extensions.get(sub); + + if (ext == null) { + ext = new HashSet<>(); + extensions.put(sub, ext); + } + + ext.add(sup); + } + + @Override + public String toString() { + String out = ""; + for(int i = maxId - 1; i >= 0; i--) { + out += i + ": "; + for(int j = 0; j < maxId; j++) { + out += "[" + (inherits(i, j) ? "1" : "0") + "]"; + } + out += "\n"; + } + return out; + } + + /** + * Indicate whether the first class inherits from the second. + * + * @param sub The possible subtype. + * @param sup The possible supertype. + * @return Whether or not {@code sub} inherits from {@code sup}. + */ + public boolean inherits(final int sub, final int sup) { + final Set ext = extensions.get(sub); + if (ext != null) { + return ext.contains(sup); + } else { + return false; + } + } + + /** + * Indicate whether a given type name is a class. + * + * @param id The type in question. + * @return Whether or not the type is a class. + */ + public boolean isClass(final int id) { + if (id == OBJECT_CLASS) return true; + return classes.contains(id); + } + + /** + * Indicate whether a given type name is an interface. + * + * @param id The type in question. + * @return Whether or not the type is an interface. + */ + public boolean isInterface(final int id) { + if (id == OBJECT_CLASS) return false; + return interfaces.contains(id); + } + + /** + * Get an iterator over the classes. + * + * @return An iterator over classes. + */ + public Collection classes() { + return classes; + } + + /** + * Get an iterator over the interfaces. + * + * @return An iterator over interfaces. + */ + public Collection interfaces() { + return interfaces; + } + + /** + * Get an iterator over all types. + * + * @return An iterator over all types. + */ + public Collection types() { + final Set combined = new HashSet(classes); + combined.addAll(interfaces); + return combined; + } + + public int numClasses() { + return classes.size(); + } + + public int numInterfaces() { + return interfaces.size(); + } + + public int numTypes() { + return numClasses() + numInterfaces(); + } + +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/IllegalAccessErrorTest.java 2015-04-17 16:07:53.810396501 -0400 @@ -0,0 +1,510 @@ +/* + * Copyright (c) 2014, 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 + * @summary Test of method selection and resolution cases that + * generate IllegalAccessErrorTest + * @run main IllegalAccessErrorTest + */ + +import java.util.function.Consumer; +import java.util.Collection; +import java.util.Collections; +import java.util.Arrays; +import java.util.EnumSet; + +public class IllegalAccessErrorTest extends SelectionResolutionTest { + + private static final SelectionResolutionTestCase.Builder initBuilder = + new SelectionResolutionTestCase.Builder(); + + static { + initBuilder.setResult(Result.IAE); + } + + private static final Collection testgroups = + Arrays.asList( + /* invokestatic tests */ + /* Group 125 : callsite = methodref, methodref != + * expected, expected is class + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME)), + Template.MethodrefNotEqualsExpectedClass, + Template.CallsiteEqualsMethodref, + Template.TrivialObjectref), + /* Group 126: callsite :> methodref, methodref = expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME)), + Template.MethodrefEqualsExpected, + Template.CallsiteSubclassMethodref, + Template.TrivialObjectref), + /* Group 127: callsite :> methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME)), + Template.MethodrefNotEqualsExpectedClass, + Template.CallsiteSubclassMethodref, + Template.TrivialObjectref), + /* Group 128: callsite unrelated to methodref, methodref = expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME)), + Template.MethodrefEqualsExpected, + Template.CallsiteUnrelatedToMethodref, + Template.TrivialObjectref), + /* Group 129: callsite unrelated to methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME)), + Template.MethodrefNotEqualsExpectedClass, + Template.CallsiteUnrelatedToMethodref, + Template.TrivialObjectref), + /* Group 130: callsite = methodref, methodref != expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE, + MethodData.Access.PACKAGE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.MethodrefNotEqualsExpectedClass, + Template.CallsiteEqualsMethodref, + Template.TrivialObjectref), + /* Group 131: callsite :> methodref, methodref = expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE, + MethodData.Access.PACKAGE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.MethodrefEqualsExpected, + Template.CallsiteSubclassMethodref, + Template.TrivialObjectref), + /* Group 132: callsite :> methodref, methodref != expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE, + MethodData.Access.PACKAGE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.MethodrefNotEqualsExpectedClass, + Template.CallsiteSubclassMethodref, + Template.TrivialObjectref), + /* Group 133: callsite unrelated to methodref, methodref = expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE, + MethodData.Access.PROTECTED, + MethodData.Access.PACKAGE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.MethodrefEqualsExpected, + Template.CallsiteUnrelatedToMethodref, + Template.TrivialObjectref), + /* Group 134: callsite unrelated to methodref, methodref != expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE, + MethodData.Access.PROTECTED, + MethodData.Access.PACKAGE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.MethodrefNotEqualsExpectedClass, + Template.CallsiteUnrelatedToMethodref, + Template.TrivialObjectref), + + /* invokevirtual tests */ + /* Group 135: callsite = methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.MethodrefSelectionResolvedIsClass), + /* Group 136: callsite :> methodref, methodref = expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.MethodrefSelectionResolvedIsClass), + /* Group 137: callsite :> methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.MethodrefSelectionResolvedIsClass), + /* Group 138: callsite unrelated to methodref, methodref = expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.MethodrefSelectionResolvedIsClass), + /* Group 139: callsite unrelated to methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.MethodrefSelectionResolvedIsClass), + /* Group 140: callsite = methodref, methodref != expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PACKAGE, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.MethodrefSelectionResolvedIsClass), + /* Group 141: callsite :> methodref, methodref = expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PACKAGE, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.MethodrefSelectionResolvedIsClass), + /* Group 142: callsite :> methodref, methodref = expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PACKAGE, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.MethodrefSelectionResolvedIsClass), + /* Group 143: callsite unrelated to methodref, methodref = expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PACKAGE, + // protected causes verifier error. + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.MethodrefSelectionResolvedIsClass), + /* Group 144: callsite unrelated to methodref, methodref != expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PACKAGE, + // protected causes verifier error. + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.MethodrefSelectionResolvedIsClass), + + /* invokeinterface tests */ + /* Group 145: callsite = methodref = expected */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.IfaceMethodrefSelectionOverrideNonPublic), + /* Group 146: callsite = methodref, methodref != expected */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.IfaceMethodrefNotEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.IfaceMethodrefSelectionOverrideNonPublic), + /* Group 147: callsite :> methodref, methodref = expected */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.IfaceMethodrefSelectionOverrideNonPublic), + /* Group 148: callsite :> methodref, methodref != expected */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.IfaceMethodrefNotEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.IfaceMethodrefSelectionOverrideNonPublic), + /* Group 149: callsite unrelated to methodref, methodref = expected */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.IfaceMethodrefSelectionOverrideNonPublic), + /* Group 150: callsite unrelated to methodref, methodref != expected */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.IfaceMethodrefNotEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.IfaceMethodrefSelectionOverrideNonPublic), + + /* invokespecial tests */ + /* Group 151: callsite = methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.ObjectrefAssignableToCallsite), + /* Group 152: callsite :> methodref, methodref = expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.ObjectrefAssignableToCallsite), + /* Group 153: callsite :> methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.ObjectrefAssignableToCallsite), + /* Group 154: callsite = methodref, methodref != expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PACKAGE, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.ObjectrefExactSubclassOfCallsite), + /* Group 155: callsite :> methodref, methodref = expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PACKAGE, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.ObjectrefExactSubclassOfCallsite), + /* Group 156: callsite :> methodref, methodref != expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PACKAGE, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.ObjectrefExactSubclassOfCallsite) + ); + + private IllegalAccessErrorTest() { + super(testgroups); + } + + public static void main(final String... args) { + new IllegalAccessErrorTest().run(); + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/Interface.java 2015-04-17 16:07:54.200401015 -0400 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, 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. + * + */ + +import static jdk.internal.org.objectweb.asm.Opcodes.*; + +class Interface extends ClassConstruct { + + public Interface(String name, int access, int index) { + this(name, V1_8, access, index, (String)null); + } + + public Interface(String name, int index) { + this(name, V1_8, index, (String)null); + } + + + public Interface(String name, int access, int index, String... extending) { + this(name, V1_8, access, index, extending); + } + + public Interface(String name, int classFileVersion, int access, int index, String... extending) { + super(name, "java/lang/Object", access + ACC_ABSTRACT + ACC_INTERFACE, classFileVersion, index, extending); + } + +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/InvokeInterfaceICCE.java 2015-04-17 16:07:54.614405806 -0400 @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2014, 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 + * @summary Test of method selection and resolution cases that + * generate IncompatibleClassChangeError + * @run main InvokeInterfaceICCE + */ + +import java.util.function.Consumer; +import java.util.Collection; +import java.util.Collections; +import java.util.Arrays; +import java.util.EnumSet; + +public class InvokeInterfaceICCE extends SelectionResolutionTest { + + private static final SelectionResolutionTestCase.Builder initBuilder = + new SelectionResolutionTestCase.Builder(); + + static { + initBuilder.setResult(Result.ICCE); + } + + private static final Collection testgroups = + Arrays.asList( + /* invokeinterface tests */ + + /* resolved method is static*/ + /* Group 168: methodref = expected */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.AllCallsiteCases, + Template.IfaceMethodrefSelection), + /* Group 169: methodref != expected */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.IfaceMethodrefNotEqualsExpected, + Template.IgnoredAbstract, + Template.AllCallsiteCases, + Template.IfaceMethodrefSelection), + + /* methodref is a class */ + /* Group 170: methodref = expected */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.AllCallsiteCases, + Template.MethodrefSelectionResolvedIsClass), + /* Group 171: methodref != expected, expected is class */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.AllCallsiteCases, + Template.MethodrefSelectionResolvedIsClass), + /* Group 172: methodref != expected expected is interface */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefNotEqualsExpectedIface, + Template.IgnoredAbstract, + Template.AllCallsiteCases, + Template.MethodrefSelectionResolvedIsIface), + /* Group 173: ambiguous resolution */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.IfaceMethodrefAmbiguous, + Template.IgnoredAbstract, + Template.AllCallsiteCases, + Template.IfaceMethodrefSelectionNoOverride), + /* Group 174: ambiguous selection */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.IfaceMethodrefNotEqualsExpected, + Template.IgnoredAbstract, + Template.AllCallsiteCases, + Template.IfaceMethodrefAmbiguousResolvedIsIface), + + /* Group 175: private method in interface */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.IfaceMethodrefSelection) + ); + + private InvokeInterfaceICCE() { + super(testgroups); + } + + public static void main(final String... args) { + new InvokeInterfaceICCE().run(); + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/InvokeInterfaceSuccessTest.java 2015-04-17 16:07:55.015410447 -0400 @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2014, 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 + * @summary Test of method selection and resolution cases that + * generate InvokeInterfaceSuccessTest + * @run main InvokeInterfaceSuccessTest + */ + +import java.util.function.Consumer; +import java.util.Collection; +import java.util.Collections; +import java.util.Arrays; +import java.util.EnumSet; + +public class InvokeInterfaceSuccessTest extends SelectionResolutionTest { + + private static final SelectionResolutionTestCase.Builder initBuilder = + new SelectionResolutionTestCase.Builder(); + + static { + initBuilder.invoke = SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE; + } + + private static final Collection testgroups = + Arrays.asList( + /* invokeinterface tests */ + + /* Group 40: callsite = methodref = expected */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.IfaceMethodrefSelection, + Template.SelectionOverrideAbstract), + /* Group 41: callsite = methodref, methodref != expected */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.IfaceMethodrefNotEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.IfaceMethodrefSelection, + Template.SelectionOverrideAbstract), + /* Group 42: callsite :> methodref, methodref = expected */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.IfaceMethodrefSelection, + Template.SelectionOverrideAbstract), + /* Group 43: callsite :> methodref, methodref != expected */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.IfaceMethodrefNotEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.IfaceMethodrefSelection, + Template.SelectionOverrideAbstract), + /* Group 44: callsite unrelated to methodref, methodref = expected */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.IfaceMethodrefSelection, + Template.SelectionOverrideAbstract), + /* Group 45: callsite unrelated to methodref, methodref != expected */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.IfaceMethodrefNotEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.IfaceMethodrefSelection, + Template.SelectionOverrideAbstract) + ); + + private InvokeInterfaceSuccessTest() { + super(testgroups); + } + + public static void main(final String... args) { + new InvokeInterfaceSuccessTest().run(); + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/InvokeSpecialICCE.java 2015-04-17 16:07:55.390414787 -0400 @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2014, 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 + * @summary Test of method selection and resolution cases that + * generate IncompatibleClassChangeError + * @run main InvokeSpecialICCE + */ + +import java.util.function.Consumer; +import java.util.Collection; +import java.util.Collections; +import java.util.Arrays; +import java.util.EnumSet; + +public class InvokeSpecialICCE extends SelectionResolutionTest { + + private static final SelectionResolutionTestCase.Builder initBuilder = + new SelectionResolutionTestCase.Builder(); + + static { + initBuilder.setResult(Result.ICCE); + } + + private static final Collection testgroups = + Arrays.asList( + /* invokespecial tests */ + /* resolved method is static*/ + /* Group 170: methodref = expected */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.InvokespecialCallsiteCases, + Template.ObjectrefAssignableToCallsite), + /* Group 171: methodref != expected, expected is class */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.InvokespecialCallsiteCases, + Template.ObjectrefAssignableToCallsite), + /* Group 172: methodref != expected, expected is interface */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefNotEqualsExpectedIface, + Template.IgnoredAbstract, + Template.InvokespecialCallsiteCases, + Template.ObjectrefAssignableToCallsite), + + /* Group 173: Ambiguous resolution */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PRIVATE), + EnumSet.allOf(MethodData.Context.class), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefAmbiguous, + Template.IgnoredAbstract, + Template.InvokespecialCallsiteCases, + Template.ObjectrefAssignableToCallsite) + ); + + private InvokeSpecialICCE() { + super(testgroups); + } + + public static void main(final String... args) { + new InvokeSpecialICCE().run(); + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/InvokeSpecialSuccessTest.java 2015-04-17 16:07:55.789419405 -0400 @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2014, 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 + * @summary Test of method selection and resolution cases that + * generate InvokeSpecialSuccessTest + * @run main InvokeSpecialSuccessTest + */ + +import java.util.function.Consumer; +import java.util.Collection; +import java.util.Collections; +import java.util.Arrays; +import java.util.EnumSet; + +public class InvokeSpecialSuccessTest extends SelectionResolutionTest { + + private static final SelectionResolutionTestCase.Builder initBuilder = + new SelectionResolutionTestCase.Builder(); + + static { + initBuilder.invoke = SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL; + } + + private static final Collection testgroups = + Arrays.asList( + /* Group 46: callsite = methodref = expected */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.ObjectrefAssignableToCallsite), + /* Group 47: callsite = methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.ObjectrefAssignableToCallsite), + /* Group 48: callsite = methodref, methodref != expected, + * expected is interface, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefNotEqualsExpectedIface, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.ObjectrefAssignableToCallsite), + /* Group 49: callsite :> methodref, methodref = expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.ObjectrefAssignableToCallsite), + /* Group 50: callsite :> methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.ObjectrefAssignableToCallsite), + /* Group 51: callsite :> methodref, methodref != expected, + * expected is interface, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefNotEqualsExpectedIface, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.ObjectrefAssignableToCallsite), + /* Group 52: callsite = methodref, methodref != expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.ObjectrefAssignableToCallsite), + /* Group 53: callsite = methodref, methodref != expected, + * expected is interface, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefNotEqualsExpectedIface, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.ObjectrefAssignableToCallsite), + /* Group 54: callsite :> methodref, methodref = expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.ObjectrefAssignableToCallsite), + + /* Group 55: callsite :> methodref, methodref != expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.ObjectrefAssignableToCallsite), + /* Group 56: callsite :> methodref, methodref != expected, + * expected is interface, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefNotEqualsExpectedIface, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.ObjectrefAssignableToCallsite), + + /* Funny cases */ + /* Group 57: callsite = methodref, methodref = + * expected expected is interface, expected and + * callsite in a different package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.ObjectrefEqualsOrExactSubclassOfCallsite), + /* Group 58: callsite = methodref, methodref \!= + * expected expected is interface, expected and + * callsite in a different package */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.ObjectrefEqualsOrExactSubclassOfCallsite), + /* Group 59: callsite subclass methodref, methodref = + * expected expected is interface, expected and + * callsite in a different package */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.ObjectrefEqualsOrExactSubclassOfCallsite), + /* Group 60: callsite subclass methodref, methodref + * \!= expected expected is interface, expected and + * callsite in a different package */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.ObjectrefEqualsOrExactSubclassOfCallsite), + + /* Methodref is an interface */ + /* Group 61: callsite :> methodref, methodref = expected, + * expected is interface, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.ObjectrefAssignableToCallsite), + /* Group 62: callsite :> methodref, methodref != expected, + * expected is interface, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.IfaceMethodrefNotEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.ObjectrefAssignableToCallsite) + ); + + private InvokeSpecialSuccessTest() { + super(testgroups); + } + + public static void main(final String... args) { + new InvokeSpecialSuccessTest().run(); + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/InvokeStaticICCE.java 2015-04-17 16:07:56.167423780 -0400 @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2014, 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 + * @summary Test of invokestatic method selection and resolution cases that + * generate IncompatibleClassChangeError + * @run main InvokeStaticICCE + */ + +import java.util.function.Consumer; +import java.util.Collection; +import java.util.Collections; +import java.util.Arrays; +import java.util.EnumSet; + +public class InvokeStaticICCE extends SelectionResolutionTest { + + private static final SelectionResolutionTestCase.Builder initBuilder = + new SelectionResolutionTestCase.Builder(); + + static { + initBuilder.setResult(Result.ICCE); + } + + private static final Collection testgroups = + Arrays.asList( + /* invokestatic tests */ + /* Group 157: methodref = expected */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.AllCallsiteCases, + Template.TrivialObjectref), + /* Group 158: methodref = expected, expected is interface */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefEqualsExpected, + Template.AllCallsiteCases, + Template.TrivialObjectref), + /* Group 159: methodref != expected, expected is class + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.AllCallsiteCases, + Template.TrivialObjectref), + /* Group 160: methodref = expected, expected is interface */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefNotEqualsExpectedIface, + Template.AllCallsiteCases, + Template.TrivialObjectref) + ); + + private InvokeStaticICCE() { + super(testgroups); + } + + public static void main(final String... args) { + new InvokeStaticICCE().run(); + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/InvokeStaticSuccessTest.java 2015-04-17 16:07:56.457427136 -0400 @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2014, 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 + * @summary Test of method selection and resolution cases that + * generate InvokeStaticSuccessTest + * @run main InvokeStaticSuccessTest + */ + +import java.util.function.Consumer; +import java.util.Collection; +import java.util.Collections; +import java.util.Arrays; +import java.util.EnumSet; + +public class InvokeStaticSuccessTest extends SelectionResolutionTest { + + private static final SelectionResolutionTestCase.Builder initBuilder = + new SelectionResolutionTestCase.Builder(); + + static { + initBuilder.invoke = SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC; + } + + private static final Collection testgroups = + Arrays.asList( + /* invokestatic tests */ + /* Group 1: callsite = methodref = expected */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME)), + Template.MethodrefEqualsExpected, + Template.CallsiteEqualsMethodref, + Template.TrivialObjectref), + /* Group 2: callsite = methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME)), + Template.MethodrefNotEqualsExpectedClass, + Template.CallsiteEqualsMethodref, + Template.TrivialObjectref), + /* Group 3: callsite :> methodref, methodref = expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME)), + Template.MethodrefEqualsExpected, + Template.CallsiteSubclassMethodref, + Template.TrivialObjectref), + /* Group 4: callsite :> methodref, methodref = expected, + * expected is interface, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME)), + Template.MethodrefEqualsExpected, + Template.CallsiteSubclassMethodref, + Template.TrivialObjectref), + /* Group 5: callsite :> methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME)), + Template.MethodrefNotEqualsExpectedClass, + Template.CallsiteSubclassMethodref, + Template.TrivialObjectref), + /* Group 6: callsite unrelated to methodref, methodref = expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME)), + Template.MethodrefEqualsExpected, + Template.CallsiteUnrelatedToMethodref, + Template.TrivialObjectref), + /* Group 7: callsite unrelated to methodref, methodref = expected, + * expected is interface, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME)), + Template.MethodrefEqualsExpected, + Template.CallsiteUnrelatedToMethodref, + Template.TrivialObjectref), + /* Group 8: callsite unrelated to methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME)), + Template.MethodrefNotEqualsExpectedClass, + Template.CallsiteUnrelatedToMethodref, + Template.TrivialObjectref), + /* Group 9: callsite = methodref, methodref != expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.MethodrefNotEqualsExpectedClass, + Template.CallsiteEqualsMethodref, + Template.TrivialObjectref), + /* Group 10: callsite :> methodref, methodref = expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.MethodrefEqualsExpected, + Template.CallsiteSubclassMethodref, + Template.TrivialObjectref), + /* Group 11: callsite :> methodref, methodref = expected, + * expected is interface, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.MethodrefEqualsExpected, + Template.CallsiteSubclassMethodref, + Template.TrivialObjectref), + /* Group 12: callsite :> methodref, methodref != expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.MethodrefNotEqualsExpectedClass, + Template.CallsiteSubclassMethodref, + Template.TrivialObjectref), + /* Group 13: callsite unrelated to methodref, methodref = expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.MethodrefEqualsExpected, + Template.CallsiteUnrelatedToMethodref, + Template.TrivialObjectref), + /* Group 14: callsite unrelated to methodref, methodref = expected, + * expected is interface, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.MethodrefEqualsExpected, + Template.CallsiteUnrelatedToMethodref, + Template.TrivialObjectref), + /* Group 15: callsite unrelated to methodref, methodref != expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.MethodrefNotEqualsExpectedClass, + Template.CallsiteUnrelatedToMethodref, + Template.TrivialObjectref) + ); + + private InvokeStaticSuccessTest() { + super(testgroups); + } + + public static void main(final String... args) { + new InvokeStaticSuccessTest().run(); + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/InvokeVirtualICCE.java 2015-04-17 16:07:56.788430966 -0400 @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2014, 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 + * @summary Test of method selection and resolution cases that + * generate IncompatibleClassChangeError + * @run main InvokeVirtualICCE + */ + +import java.util.function.Consumer; +import java.util.Collection; +import java.util.Collections; +import java.util.Arrays; +import java.util.EnumSet; + +public class InvokeVirtualICCE extends SelectionResolutionTest { + + private static final SelectionResolutionTestCase.Builder initBuilder = + new SelectionResolutionTestCase.Builder(); + + static { + initBuilder.setResult(Result.ICCE); + } + + private static final Collection testgroups = + Arrays.asList( + /* invokevirtual tests */ + + /* resolved method is static*/ + /* Group 161: callsite = methodref = expected */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.AllCallsiteCases, + Template.MethodrefSelectionResolvedIsClass), + /* Group 162: callsite = methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PACKAGE, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.AllCallsiteCases, + Template.MethodrefSelectionResolvedIsClass), + /* Group 163: callsite = methodref, methodref != expected, + * expected is interface, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.STATIC), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefNotEqualsExpectedIface, + Template.IgnoredAbstract, + Template.AllCallsiteCases, + Template.MethodrefSelectionResolvedIsIface), + + /* methodref is an interface */ + /* Group 164: callsite = methodref = expected */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PRIVATE), + EnumSet.allOf(MethodData.Context.class), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.AllCallsiteCases, + Template.IfaceMethodrefSelection), + /* Group 165: callsite = methodref, methodref != expected, + * expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PRIVATE), + EnumSet.allOf(MethodData.Context.class), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.IfaceMethodrefNotEqualsExpected, + Template.IgnoredAbstract, + Template.AllCallsiteCases, + Template.IfaceMethodrefSelection), + + /* Group 166: Ambiguous resolution tests */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.allOf(MethodData.Context.class), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefAmbiguous, + Template.IgnoredAbstract, + Template.AllCallsiteCases, + Template.MethodrefSelectionResolvedIsIfaceNoOverride), + /* Group 167: ambiguous selection */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefNotEqualsExpectedIface, + Template.IgnoredAbstract, + Template.AllCallsiteCases, + Template.MethodrefAmbiguousResolvedIsIface) + ); + + private InvokeVirtualICCE() { + super(testgroups); + } + + public static void main(final String... args) { + new InvokeVirtualICCE().run(); + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/InvokeVirtualSuccessTest.java 2015-04-17 16:07:57.124434855 -0400 @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2014, 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 + * @summary Test of method selection and resolution cases that + * generate InvokeVirtualSuccessTest + * @run main InvokeVirtualSuccessTest + */ + +import java.util.function.Consumer; +import java.util.Collection; +import java.util.Collections; +import java.util.Arrays; +import java.util.EnumSet; + +public class InvokeVirtualSuccessTest extends SelectionResolutionTest { + + private static final SelectionResolutionTestCase.Builder initBuilder = + new SelectionResolutionTestCase.Builder(); + + static { + initBuilder.invoke = SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL; + } + + private static final Collection testgroups = + Arrays.asList( + /* invokevirtual tests */ + /* Group 16: callsite = methodref = expected, no override */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.MethodrefSelectionResolvedIsClassNoOverride), + /* Group 17: callsite = methodref = expected, override allowed */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PROTECTED, + MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.MethodrefSelectionResolvedIsClass, + Template.SelectionOverrideAbstract), + /* Group 18: callsite = methodref = resolved, possibly + * skip different package in selection. + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PACKAGE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.MethodrefSelectionPackageSkip, + Template.SelectionOverrideAbstract), + /* Group 19: callsite = methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.MethodrefSelectionResolvedIsClass, + Template.SelectionOverrideAbstract), + /* Group 20: callsite = methodref, methodref \!= + * expected, possibly skip different package in + * selection. + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PACKAGE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.MethodrefSelectionPackageSkip, + Template.SelectionOverrideAbstract), + /* Group 21: callsite = methodref, methodref != expected, + * expected is interface, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefNotEqualsExpectedIface, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.MethodrefSelectionResolvedIsIface, + Template.SelectionOverrideAbstract), + /* Group 22: callsite :> methodref, methodref = expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.MethodrefSelectionResolvedIsClass, + Template.SelectionOverrideAbstract), + /* Group 23: callsite :>, methodref = expected, + * possibly skip different package in selection + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PACKAGE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.MethodrefSelectionPackageSkip, + Template.SelectionOverrideAbstract), + /* Group 24: callsite :> methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.MethodrefSelectionResolvedIsClass, + Template.SelectionOverrideAbstract), + /* Group 25: callsite :>, methodref = expected, + * possibly skip different package in selection + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PACKAGE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.MethodrefSelectionPackageSkip, + Template.SelectionOverrideAbstract), + /* Group 26: callsite :> methodref, methodref != expected, + * expected is interface, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefNotEqualsExpectedIface, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.MethodrefSelectionResolvedIsIface, + Template.SelectionOverrideAbstract), + /* Group 27: callsite unrelated to methodref, methodref = expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.MethodrefSelectionResolvedIsClass, + Template.SelectionOverrideAbstract), + /* Group 28: callsite unrelated to methodref, + * methodref = expected, possibly skip different + * package in selection + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PACKAGE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.MethodrefSelectionPackageSkip, + Template.SelectionOverrideAbstract), + /* Group 29: callsite unrelated to methodref, methodref != expected, + * expected is class, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.MethodrefSelectionResolvedIsClass, + Template.SelectionOverrideAbstract), + /* Group 30: callsite unrelated to methodref, + * methodref \!= expected, possibly skip different + * package in selection + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PACKAGE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.MethodrefSelectionPackageSkip, + Template.SelectionOverrideAbstract), + /* Group 31: callsite unrelated to methodref, methodref != expected, + * expected is interface, expected and callsite in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefNotEqualsExpectedIface, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.MethodrefSelectionResolvedIsIface, + Template.SelectionOverrideAbstract), + /* Group 32: callsite = methodref, methodref != expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC, + MethodData.Access.PROTECTED), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.MethodrefSelectionResolvedIsClass, + Template.SelectionOverrideAbstract), + /* Group 33: callsite = methodref, methodref != expected, + * expected is interface, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefNotEqualsExpectedIface, + Template.IgnoredAbstract, + Template.CallsiteEqualsMethodref, + Template.MethodrefSelectionResolvedIsIface, + Template.SelectionOverrideAbstract), + /* Group 34: callsite :> methodref, methodref = expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.MethodrefSelectionResolvedIsClass, + Template.SelectionOverrideAbstract), + + /* Group 35: callsite :> methodref, methodref != expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.MethodrefSelectionResolvedIsClass, + Template.SelectionOverrideAbstract), + /* Group 36: callsite :> methodref, methodref != expected, + * expected is interface, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefNotEqualsExpectedIface, + Template.IgnoredAbstract, + Template.CallsiteSubclassMethodref, + Template.MethodrefSelectionResolvedIsIface, + Template.SelectionOverrideAbstract), + /* Group 37: callsite unrelated to methodref, methodref = expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefEqualsExpected, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.MethodrefSelectionResolvedIsClass, + Template.SelectionOverrideAbstract), + /* Group 38: callsite unrelated to methodref, methodref != expected, + * expected is class, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.CLASS), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedClass, + Template.MethodrefNotEqualsExpectedClass, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.MethodrefSelectionResolvedIsClass, + Template.SelectionOverrideAbstract), + /* Group 39: callsite unrelated to methodref, methodref != expected, + * expected is interface, expected and callsite not in the same package + */ + new TestGroup.Simple(initBuilder, + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.DIFFERENT)), + Template.OverrideAbstractExpectedIface, + Template.MethodrefNotEqualsExpectedIface, + Template.IgnoredAbstract, + Template.CallsiteUnrelatedToMethodref, + Template.MethodrefSelectionResolvedIsIface, + Template.SelectionOverrideAbstract) + ); + + private InvokeVirtualSuccessTest() { + super(testgroups); + } + + public static void main(final String... args) { + new InvokeVirtualSuccessTest().run(); + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/Method.java 2015-04-17 16:07:57.488439068 -0400 @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2014, 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. + * + */ + +import jdk.internal.org.objectweb.asm.ClassVisitor; +import jdk.internal.org.objectweb.asm.Handle; +import jdk.internal.org.objectweb.asm.MethodVisitor; + +import java.lang.invoke.CallSite; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +import static jdk.internal.org.objectweb.asm.Opcodes.*; + +class Method { + public static final String defaultMethodName = "m"; + public static final String defaultMethodDescriptor = "()Ljava/lang/Integer;"; + public static final String methodDescriptorTemplate = "(L%s;)Ljava/lang/Integer;"; + private final ClassConstruct ownerClass; + private final String ownerClassName; + private final ClassVisitor cv; + private final MethodVisitor mv; + private final boolean isInterface; + private final ClassBuilder.ExecutionMode execMode; + + public Method(ClassConstruct ownerClass, ClassVisitor cv, String name, String descriptor, int access, + ClassBuilder.ExecutionMode execMode) { + this.ownerClassName = ownerClass.getName(); + this.ownerClass = ownerClass; + this.isInterface = ownerClass.isInterface(); + this.execMode = execMode; + this.cv = cv; + mv = cv.visitMethod(access, name, descriptor, null, null); + mv.visitCode(); + } + /** + * Add code for the m()Ljava/lang/Integer; method, always returns null + */ + public void makeDefaultMethod() { + mv.visitTypeInsn(NEW, "java/lang/Integer"); + mv.visitInsn(DUP); + mv.visitLdcInsn(ownerClass.getIndex()); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Integer", "", "(I)V"); + mv.visitInsn(ARETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + + public void makePrivateCallMethod(String className) { + makeSuperCallMethod(INVOKESPECIAL, className); + } + + public void makeSuperCallMethod(int invokeInstruction, String className) { + mv.visitVarInsn(ALOAD, 0); + makeCall(invokeInstruction, className); + mv.visitInsn(POP); + done(); + } + + public void defaultInvoke(int instr, String className, String objectRef) { + switch (instr) { + case INVOKEVIRTUAL: + defaultInvokeVirtual(className, objectRef); + break; + case INVOKEINTERFACE: + defaultInvokeInterface(className, objectRef); + break; + case INVOKESTATIC: + defaultInvokeStatic(className); + break; + case INVOKESPECIAL: + defaultInvokeSpecial(className, objectRef); + break; + default: + break; + } + mv.visitInsn(ARETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + + public void defaultInvokeVirtual(String className, String objectRef) { + String objectRefPackageName = objectRef.substring(0, objectRef.lastIndexOf("/")); + makeNewObject(objectRef, objectRefPackageName); + makeCall(INVOKEVIRTUAL, className, false); + } + + public void defaultInvokeInterface(String className, String objectRef) { + String objectRefPackageName = objectRef.substring(0, objectRef.lastIndexOf("/")); + makeNewObject(objectRef, objectRefPackageName); + makeCall(INVOKEINTERFACE, className, true); + } + + public void defaultInvokeSpecial(String className, String objectRef) { + String objectRefPackageName = objectRef.substring(0, objectRef.lastIndexOf("/")); + makeNewObject(objectRef, objectRefPackageName); + makeCall(INVOKESPECIAL, className, false); + } + + public void defaultInvokeStatic(String className) { + makeCall(INVOKESTATIC, className); + } + + private Method makeCall(int invokeInstruction, String className) { + return makeCall(invokeInstruction, className, isInterface); + } + + private Method makeCall(int invokeInstruction, String className, boolean isInterface) { + switch(execMode) { + case DIRECT: { + mv.visitMethodInsn(invokeInstruction, className, defaultMethodName, defaultMethodDescriptor, isInterface); + break; + } + case INDY: { + Handle m = convertToHandle(invokeInstruction, className, defaultMethodName, defaultMethodDescriptor); + Handle bsm = generateBootstrapMethod(m); + mv.visitInvokeDynamicInsn(defaultMethodName, defaultMethodDescriptor, bsm); + break; + } + case MH_INVOKE_EXACT: + case MH_INVOKE_GENERIC: { + String invokerName = execMode == ClassBuilder.ExecutionMode.MH_INVOKE_GENERIC + ? "invoke" : "invokeExact"; + + Handle m = convertToHandle(invokeInstruction, className, defaultMethodName, defaultMethodDescriptor); + mv.visitLdcInsn(m); + mv.visitInsn(SWAP); + mv.visitMethodInsn(INVOKEVIRTUAL, + "java/lang/invoke/MethodHandle", + invokerName, + String.format(methodDescriptorTemplate, className), + false); + break; + } + default: + throw new Error("Unknown execution mode: " + execMode); + + } + return this; + } + + private Handle generateBootstrapMethod(Handle h) { + String bootstrapName = "bootstrapMethod"; + MethodType bootstrapType = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class); + + MethodVisitor bmv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, bootstrapName, bootstrapType.toMethodDescriptorString(), null, null); + bmv.visitCode(); + + String constCallSite = "java/lang/invoke/ConstantCallSite"; + bmv.visitTypeInsn(NEW, constCallSite); + bmv.visitInsn(DUP); + + bmv.visitLdcInsn(h); + + bmv.visitMethodInsn(INVOKESPECIAL, constCallSite, "", "(Ljava/lang/invoke/MethodHandle;)V", false); + bmv.visitInsn(ARETURN); + + bmv.visitMaxs(0,0); + bmv.visitEnd(); + + return new Handle(H_INVOKESTATIC, ownerClassName, bootstrapName, bootstrapType.toMethodDescriptorString()); + } + + + private static Handle convertToHandle(int invokeInstruction, String className, String methodName, String methodDesc) { + int tag; + switch (invokeInstruction) { + case INVOKEVIRTUAL: tag = H_INVOKEVIRTUAL; break; + case INVOKEINTERFACE: tag = H_INVOKEINTERFACE; break; + case INVOKESPECIAL: tag = H_INVOKESPECIAL; break; + case INVOKESTATIC: tag = H_INVOKESTATIC; break; + default: + throw new Error("Unknown invoke instruction: "+invokeInstruction); + } + + return new Handle(tag, className, methodName, methodDesc); + } + + private void makeNewObject(String objectRef, String objectRefPackageName) { + String className = objectRef.substring(objectRef.lastIndexOf("/") + 1); + makeStaticCall( objectRefPackageName + "/Helper", + "get" + className, + "()L" + objectRef + ";"); + mv.visitVarInsn(ASTORE, 1); + mv.visitVarInsn(ALOAD, 1); + } + + public void makeTestCall(String className) { + mv.visitTypeInsn(NEW, className); + mv.visitInsn(DUP); + mv.visitMethodInsn(INVOKESPECIAL, className, "", "()V", false); + mv.visitVarInsn(ASTORE, 1); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, className, "test", "()Ljava/lang/Integer;", false); + mv.visitInsn(RETURN); + mv.visitMaxs(2, 2); + mv.visitEnd(); + } + + public Method makeStaticCall(String classname, String method, String descriptor) { + mv.visitMethodInsn(INVOKESTATIC, classname, method, descriptor, isInterface); + return this; + } + + public void makeConstructor(String extending) { + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, extending == null ? "java/lang/Object" : extending, "", "()V", isInterface); + mv.visitInsn(RETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + + public void makeInstantiateMethod(String className) { + mv.visitTypeInsn(NEW, className); + mv.visitInsn(DUP); + mv.visitMethodInsn(INVOKESPECIAL, className, "", "()V", false); + mv.visitInsn(ARETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + + public void done() { + mv.visitInsn(RETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/MethodData.java 2015-04-17 16:07:57.916444021 -0400 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2014, 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. + * + */ + +/** + * A representation of a method definition. + */ +public class MethodData { + + public enum Access { + PUBLIC(1), + PACKAGE(0), + PROTECTED(4), + PRIVATE(2), + /** + * Placeholder, used solely for printing out the effects of + * templates. Don't use. + */ + PLACEHOLDER(-1); + + public final int flag; + + Access(int flag) { + this.flag = flag; + } + } + + public enum Context { + ABSTRACT, + INSTANCE, + STATIC, + /** + * Placeholder, used solely for printing out the effects of + * templates. Don't use. + */ + PLACEHOLDER; + }; + + /** + * Access for the method. + */ + public final Access access; + + /** + * Context (static, instance, abstract) for the method. + */ + public final Context context; + + /** + * Create method data. + */ + public MethodData(final Access access, + final Context context) { + + this.access = access; + this.context = context; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + switch (access) { + case PUBLIC: sb.append("public"); break; + case PACKAGE: sb.append("package"); break; + case PROTECTED: sb.append("protected"); break; + case PRIVATE: sb.append("private"); break; + case PLACEHOLDER: sb.append(" _"); break; + default: throw new RuntimeException("Impossible case"); + } + + switch (context) { + case STATIC: sb.append(" static"); break; + case INSTANCE: sb.append(" instance"); break; + case ABSTRACT: sb.append(" abstract"); break; + case PLACEHOLDER: sb.append(" _"); break; + default: throw new RuntimeException("Impossible case"); + } + sb.append(" Integer m();"); + + return sb.toString(); + } + +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/NoSuchMethodErrorTest.java 2015-04-17 16:07:58.409449726 -0400 @@ -0,0 +1,444 @@ +/* + * Copyright (c) 2014, 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 + * @summary Test of method selection and resolution cases that + * generate NoSuchMethodError + * @library /testlibrary/selection_resolution/ + * @run main NoSuchMethodErrorTest + */ + +import java.util.function.Consumer; +import java.util.Collection; +import java.util.Collections; +import java.util.Arrays; +import java.util.EnumSet; + +public class NoSuchMethodErrorTest extends SelectionResolutionTest { + + private static final SelectionResolutionTestCase.Builder initBuilder = + new SelectionResolutionTestCase.Builder(); + + static { + initBuilder.setResult(Result.NSME); + } + + private static final MethodData concreteMethod = + new MethodData(MethodData.Access.PUBLIC, MethodData.Context.INSTANCE); + + private static final MethodData staticMethod = + new MethodData(MethodData.Access.PUBLIC, MethodData.Context.STATIC); + + private static final MethodData privateMethod = + new MethodData(MethodData.Access.PRIVATE, MethodData.Context.INSTANCE); + + private static final ClassData withDef = + new ClassData(ClassData.Package.SAME, concreteMethod); + + private static final ClassData withStaticDef = + new ClassData(ClassData.Package.SAME, staticMethod); + + private static final ClassData withPrivateDef = + new ClassData(ClassData.Package.SAME, staticMethod); + + private static final Template NoMethodResolutionTemplateClassBottom = + new Template("NoMethodResolutionTemplate", + /* Empty single class + * + * C[]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + builder.methodref = C; + }, + /* Class bottom, inherit empty class + * + * C2[]() + * C1[C2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int C2 = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + builder.hier.addInherit(C1, C2); + builder.methodref = C1; + }, + /* Class bottom, inherit empty interface + * + * I[]() + * C[I]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int I = builder.addInterface(Template.emptyClass(ClassData.Package.SAME)); + builder.hier.addInherit(C, I); + builder.methodref = C; + }, + /* Class bottom, inherit empty class and interface + * + * C2[](), I[]() + * C1[C2,I]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int C2 = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int I = builder.addInterface(Template.emptyClass(ClassData.Package.SAME)); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I); + builder.methodref = C1; + }, + /* Class bottom, unrelated class defines + * + * C20[](con) + * C1[]() + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + builder.addClass(withDef); + builder.methodref = C; + }, + /* Class bottom, interface defines static + * + * I[](stat) + * C[]() + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int I = builder.addInterface(withStaticDef); + builder.hier.addInherit(C, I); + builder.methodref = C; + }, + /* Class bottom, interface defines private + * + * I[](priv) + * C[]() + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int I = builder.addInterface(withPrivateDef); + builder.hier.addInherit(C, I); + builder.methodref = C; + }); + + private static final Template NoMethodResolutionTemplateIfaceBottom = + new Template("NoMethodResolutionTemplate", + /* Empty single interface + * + * I[]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int I = builder.addInterface(Template.emptyClass(ClassData.Package.SAME)); + builder.methodref = I; + }, + /* Interface bottom, inherit empty interface + * + * I2[]() + * I1[I2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int I1 = builder.addInterface(Template.emptyClass(ClassData.Package.SAME)); + final int I2 = builder.addInterface(Template.emptyClass(ClassData.Package.SAME)); + builder.hier.addInherit(I1, I2); + builder.methodref = I1; + }, + /* Interface bottom, unrelated class defines + * + * C0[](con) + * I[]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int I = builder.addInterface(Template.emptyClass(ClassData.Package.SAME)); + builder.addClass(withDef); + builder.methodref = I; + }, + /* Interface bottom, interface defines static + * + * I2[](stat) + * I1[I2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int I1 = builder.addInterface(Template.emptyClass(ClassData.Package.SAME)); + final int I2 = builder.addInterface(withStaticDef); + builder.hier.addInherit(I1, I2); + builder.methodref = I1; + }, + /* Interface bottom, interface defines private + * + * I2[](stat) + * I1[I2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int I1 = builder.addInterface(Template.emptyClass(ClassData.Package.SAME)); + final int I2 = builder.addInterface(withPrivateDef); + builder.hier.addInherit(I1, I2); + builder.methodref = I1; + }); + + private static final Template NoMethodSelectionTemplateClassMethodref = + new Template("NoMethodSelectionTemplate", + /* objectref = methodref + * + * C[]() = mref = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + builder.objectref = builder.methodref; + }, + /* Inherit methodref + * + * C2[]() = mref + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int C2 = builder.methodref; + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Inherit methodref and interface + * + * C2[]() = mref, I[]() + * C1[C2,I]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C2 = builder.methodref; + final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int I = builder.addInterface(Template.emptyClass(ClassData.Package.SAME)); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I); + builder.objectref = C1; + }, + /* objectref = methodref, unrelated class defines + * + * C0[](def) + * C[]() = mref = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + builder.addClass(withDef); + builder.objectref = builder.methodref; + }, + /* Inherit methodref, unrelated class defines + * + * C0[](def) + * C2[]() = mref + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int C2 = builder.methodref; + builder.addClass(withDef); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Inherit methodref and interface, unrelated class defines. + * + * C0[](def) + * C2[]() = mref, I[]() + * C1[C2,I]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C2 = builder.methodref; + final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int I = builder.addInterface(Template.emptyClass(ClassData.Package.SAME)); + builder.addClass(withDef); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I); + builder.objectref = C1; + }, + /* objectref = methodref, unrelated interface defines + * + * I0[](def) + * C[]() = mref = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + builder.addInterface(withDef); + builder.objectref = builder.methodref; + }, + /* Inherit methodref, interface defines static + * + * C2[]() = mref, I0[](stat) + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int C2 = builder.methodref; + final int I0 = builder.addInterface(withStaticDef); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I0); + builder.objectref = C1; + }, + /* Inherit methodref, interface defines private + * + * C2[]() = mref, I0[](stat) + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int C2 = builder.methodref; + final int I0 = builder.addInterface(withPrivateDef); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I0); + builder.objectref = C1; + }); + + private static final Template NoMethodSelectionTemplateIfaceMethodref = + new Template("NoMethodSelectionTemplate", + /* Inherit methodref + * + * I[]() = mref + * C[I]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int I = builder.methodref; + builder.hier.addInherit(C, I); + builder.objectref = C; + }, + /* Inherit methodref and interface + * + * I1[]() = mref, I2[]() + * C[T,I]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int I1 = builder.methodref; + final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int I2 = builder.addInterface(Template.emptyClass(ClassData.Package.SAME)); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.objectref = C; + }, + /* Inherit methodref, unrelated class defines + * + * C0[](def) + * I[]() = mref + * C[I]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int I = builder.methodref; + builder.addClass(withDef); + builder.hier.addInherit(C, I); + builder.objectref = C; + }, + /* Inherit methodref and interface, unrelated class defines + * + * C0[](def) + * I1[]() = mref, I2[]() + * C[I1,I2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int I1 = builder.methodref; + final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int I2 = builder.addInterface(Template.emptyClass(ClassData.Package.SAME)); + builder.addClass(withDef); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.objectref = C; + }, + /* Inherit methodref, interface defines static + * + * I[]() = mref, I0[](stat) + * C[I,I0]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int I = builder.methodref; + final int I0 = builder.addInterface(withStaticDef); + builder.hier.addInherit(C, I); + builder.hier.addInherit(C, I0); + builder.objectref = C; + }, + /* Inherit methodref, unrelated class defines private + * + * I[]() = mref, I0[](priv) + * C[I,I0]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + final int I = builder.methodref; + final int I0 = builder.addInterface(withPrivateDef); + builder.hier.addInherit(C, I); + builder.hier.addInherit(C, I0); + builder.objectref = C; + }); + + private static final Collection testgroups = + Arrays.asList( + /* invokestatic tests */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + NoMethodResolutionTemplateClassBottom, + Template.AllCallsiteCases, + Template.TrivialObjectref), + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC), + NoMethodResolutionTemplateIfaceBottom, + Template.CallsiteNotEqualsMethodref, + Template.TrivialObjectref), + /* invokevirtual tests */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + NoMethodResolutionTemplateClassBottom, + Template.AllCallsiteCases, + NoMethodSelectionTemplateClassMethodref), + /* invokeinterface tests */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + NoMethodResolutionTemplateIfaceBottom, + Template.CallsiteNotEqualsMethodref, + NoMethodSelectionTemplateIfaceMethodref), + + /* Hiding of private interface methods */ + /* invokevirtual */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.MethodrefNotEqualsExpectedIface, + Template.AllCallsiteCases, + Template.TrivialObjectref), + /* invokeinterface */ + new TestGroup.Simple(initBuilder, + Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE), + Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PRIVATE), + EnumSet.of(MethodData.Context.INSTANCE, + MethodData.Context.ABSTRACT), + EnumSet.of(ClassData.Package.SAME, + ClassData.Package.DIFFERENT)), + Template.IfaceMethodrefNotEqualsExpected, + Template.AllCallsiteCases, + Template.TrivialObjectrefNotEqualMethodref) + ); + + private NoSuchMethodErrorTest() { + super(testgroups); + } + + public static void main(final String... args) { + new NoSuchMethodErrorTest().run(); + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/Result.java 2015-04-17 16:07:58.825454541 -0400 @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2014, 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. + */ + +import java.util.Arrays; +import java.util.HashSet; + +/** + * Representation of an expected result. + */ +public interface Result { + public static final Result ICCE = new Exception(IncompatibleClassChangeError.class); + public static final Result IAE = new Exception(IllegalAccessError.class); + public static final Result NSME = new Exception(NoSuchMethodError.class); + public static final Result AME = new Exception(AbstractMethodError.class); + + // Factories + + /** + * Create a result that expects the given class. + */ + public static Result is(int id) { + return new Single(id); + } + + /** + * Create a result that expects the given classes. + */ + public static Result is(int... multiple) { + assert multiple.length > 0; + + if (multiple.length == 1) { + return new Single(multiple[0]); + } else { + return new Any(multiple); + } + } + + /** + * Create a result that expects the given exception to be thrown. + */ + public static Result is(Class exType) { + return new Exception(exType); + } + + /** + * Create a result that expects the given exception to be thrown. + */ + public static Result is(Throwable ex) { + return Result.is(ex.getClass()); + } + + public static final Result EMPTY = new Empty(); + + /** + * Create an empty Result. + */ + public static Result empty() { + return EMPTY; + } + + + public boolean complyWith(int i); + public boolean complyWith(Throwable e); + public boolean complyWith(Result r); + + static class Empty implements Result { + @Override + public boolean complyWith(int i) { + return false; + } + + @Override + public boolean complyWith(Throwable e) { + return false; + } + + @Override + public boolean complyWith(Result r) { + return false; + } + } + + static class Single implements Result { + public int id; + + public Single(int id) { + this.id = id; + } + + @Override + public boolean complyWith(int i) { + return id == i; + } + + @Override + public boolean complyWith(Throwable e) { + return false; + } + + @Override + public boolean complyWith(Result r) { + if (r instanceof Single) { + return complyWith(((Single)r).id); + } else if (r instanceof Any) { + return r.complyWith(this); + } + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Single)) return false; + + Single single = (Single) o; + + return (id == single.id); + } + + @Override + public int hashCode() { + return id; + } + + @Override + public String toString() { + final StringBuffer sb = new StringBuffer("Result=Single{"); + sb.append("id=").append(id); + sb.append('}'); + return sb.toString(); + } + } + + static class Any implements Result { + public int[] ids; + public Any(int[] ids) { + this.ids = ids; + } + + @Override + public boolean complyWith(int i) { + return Arrays.stream(ids) + .anyMatch(j -> j == i); + } + + @Override + public boolean complyWith(Throwable e) { + return false; + } + + @Override + public boolean complyWith(Result r) { + if (r instanceof Single) { + return complyWith(((Single)r).id); + } + if (r instanceof Any) { + return Arrays.equals(ids, ((Any) r).ids); + } + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Any any = (Any) o; + + return Arrays.equals(ids, any.ids); + } + + @Override + public int hashCode() { + return Arrays.hashCode(ids); + } + + @Override + public String toString() { + final StringBuffer sb = new StringBuffer("Result=Any{"); + sb.append("ids="); + if (ids == null) sb.append("null"); + else { + sb.append('['); + for (int i = 0; i < ids.length; ++i) + sb.append(i == 0 ? "" : ", ").append(ids[i]); + sb.append(']'); + } + sb.append('}'); + return sb.toString(); + } + } + + static class Exception implements Result { + public Class exc; + public Exception(Class e) { + this.exc = e; + } + + @Override + public boolean complyWith(int i) { + return false; + } + + @Override + public boolean complyWith(Throwable e) { + return exc.isAssignableFrom(e.getClass()); + } + + @Override + public boolean complyWith(Result r) { + if (r instanceof Exception) { + return exc.isAssignableFrom(((Exception) r).exc); + } + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Exception)) return false; + + Exception exception = (Exception) o; + + return exc.equals(exception.exc); + } + + @Override + public int hashCode() { + return exc.hashCode(); + } + + @Override + public String toString() { + final StringBuffer sb = new StringBuffer("Result=Exception{"); + sb.append("exc=").append(exc); + sb.append('}'); + return sb.toString(); + } + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/SelectionResolutionTest.java 2015-04-17 16:07:59.176458603 -0400 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2014, 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. + */ + +import java.util.function.Consumer; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +/** + * A master superclass for all selection/resolution tests. Contains a + * couple of standard definitions that make writing these tests + * easier. + */ +public abstract class SelectionResolutionTest { + + /** + * A unified output function, to ensure that all output goes to + * the right string (System.err). + * + * @param str The line to print. + */ + protected void println(final String str) { + System.err.println(str); + } + + /** + * A test group is a generator for a set of tests that should + * share common characteristics. The Simple class provides a + * default implementation that should work for most purposes. + */ + public static interface TestGroup { + /** + * Given an action that runs a given test case, generate and + * run all cases in this test group. + */ + public void runCases(Consumer runner); + + /** + * The basic implementation of TestGroup. Produces one case + * for every possible combination of cases from each of its + * templates, by running them in order on an empty + * SelectionResolutionTestCase.Builder. This should be good + * enough for writing most tests. + */ + public static class Simple implements TestGroup { + private final Template[] templates; + private final SelectionResolutionTestCase.Builder initBuilder; + + public Simple(final SelectionResolutionTestCase.Builder initBuilder, + final Template... templates) { + this.templates = templates; + this.initBuilder = initBuilder; + } + + @Override + public void runCases(final Consumer runner) { + Consumer curr = (builder) -> { + runner.accept(builder.build()); + }; + + for(int i = templates.length - 1; i >= 0; i--) { + final Consumer next = curr; + final Template template = templates[i]; + curr = (builder) -> { + template.runCases(next, builder); + }; + } + + curr.accept(initBuilder); + } + } + } + + private final List errs = new LinkedList(); + + private final Collection testGroups; + + private int testcount = 0; + + /** + * Create a test from a set of test groups. Most actual tests can + * just define the test groups and pass them into this + * constructor, then call run. + */ + protected SelectionResolutionTest(final Collection testGroups) { + this.testGroups = testGroups; + } + + /** + * Run all the tests, report errors if they happen. + */ + protected void run() { + testGroups.stream().forEach( + (group) -> { + group.runCases((final SelectionResolutionTestCase testcase) -> { + testcount++; + final String err = testcase.run(); + + if (err != null) { + errs.add(err); + } + }); + }); + + println("Ran " + testcount + " cases"); + + if(!errs.isEmpty()) { + println("Errors occurred in test:"); + for(final String err : errs) { + println(err); + } + throw new RuntimeException("Errors occurred in test"); + } else { + println("All test cases succeeded"); + } + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/SelectionResolutionTestCase.java 2015-04-17 16:07:59.524462630 -0400 @@ -0,0 +1,434 @@ +/* + * Copyright (c) 2014, 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. + */ + +import java.io.File; +import java.io.FileWriter; +import java.util.HashMap; + +/** + * One individual test case. This class also defines a builder, which + * can be used to build up cases. + */ +public class SelectionResolutionTestCase { + + public enum InvokeInstruction { + INVOKESTATIC, + INVOKESPECIAL, + INVOKEINTERFACE, + INVOKEVIRTUAL; + } + + /** + * The class data (includes interface data). + */ + public final HashMap classdata; + /** + * The hierarchy shape. + */ + public final HierarchyShape hier; + /** + * The invoke instruction to use. + */ + public final InvokeInstruction invoke; + /** + * Which class is the methodref (or interface methodref). + */ + public final int methodref; + /** + * Which class is the objectref. + */ + public final int objectref; + /** + * Which class is the callsite (this must be a class, not an interface. + */ + public final int callsite; + /** + * The expected result. + */ + public final Result result; + + private SelectionResolutionTestCase(final HashMap classdata, + final HierarchyShape hier, + final InvokeInstruction invoke, + final int methodref, + final int objectref, + final int callsite, + final int expected) { + this.classdata = classdata; + this.hier = hier; + this.invoke = invoke; + this.methodref = methodref; + this.objectref = objectref; + this.callsite = callsite; + this.result = Result.is(expected); + } + + private SelectionResolutionTestCase(final HashMap classdata, + final HierarchyShape hier, + final InvokeInstruction invoke, + final int methodref, + final int objectref, + final int callsite, + final Result result) { + this.classdata = classdata; + this.hier = hier; + this.invoke = invoke; + this.methodref = methodref; + this.objectref = objectref; + this.callsite = callsite; + this.result = result; + } + + private static int currError = 0; + + private String dumpClasses(final ClassConstruct[] classes) + throws Exception { + final String errorDirName = "error_" + currError++; + final File errorDir = new File(errorDirName); + errorDir.mkdirs(); + for (int i = 0; i < classes.length; i++) { + classes[i].writeClass(errorDir); + } + try (final FileWriter fos = + new FileWriter(new File(errorDir, "description.txt"))) { + fos.write(this.toString()); + } + return errorDirName; + } + + /** + * Run this case, return an error message, or null. + * + * @return An error message, or null if the case succeeded. + */ + public String run() { + /* Uncomment this line to print EVERY case */ + //System.err.println("Running\n" + this); + final ClassBuilder builder = + new ClassBuilder(this, ClassBuilder.ExecutionMode.DIRECT); + try { + final ByteCodeClassLoader bcl = new ByteCodeClassLoader(); + final ClassConstruct[] classes = builder.build(); + + try { + bcl.addClasses(classes); + bcl.loadAll(); + + // Grab the callsite class. + final Class testclass = + bcl.findClass(builder.getCallsiteClass().getDottedName()); + + // Get the 'test' method out of it and call it. The + // return value tess which class that got selected. + final java.lang.reflect.Method method = + testclass.getDeclaredMethod("test"); + final int actual = (Integer) method.invoke(null); + // Check the result. + if (!result.complyWith(actual)) { + final String dump = dumpClasses(classes); + return "Failed:\n" + this + "\nExpected " + result + " got " + actual + "\nClasses written to " + dump; + } + } catch (Throwable t) { + // This catch block is handling exceptions that we + // might expect to see. + final Throwable actual = t.getCause(); + if (actual == null) { + final String dump = dumpClasses(classes); + System.err.println("Unexpected exception in test\n" + this + "\nClasses written to " + dump); + throw t; + } else if (result == null) { + final String dump = dumpClasses(classes); + return "Failed:\n" + this + "\nUnexpected exception " + actual + "\nClasses written to " + dump; + } else if (!result.complyWith(actual)) { + final String dump = dumpClasses(classes); + return "Failed:\n" + this + "\nExpected " + this.result + " got " + actual + "\nClasses written to " + dump; + } + } + } catch(Throwable e) { + throw new RuntimeException(e); + } + return null; + } + + private static void addPackage(final StringBuilder sb, + final ClassData cd) { + switch (cd.packageId) { + case SAME: sb.append("Same."); break; + case DIFFERENT: sb.append("Different."); break; + case OTHER: sb.append("Other."); break; + case PLACEHOLDER: sb.append("_."); break; + default: throw new RuntimeException("Impossible case"); + } + } + + public String toString() { + final StringBuilder sb = new StringBuilder(); + //sb.append("hierarchy:\n" + hier + "\n"); + sb.append("invoke: " + invoke + "\n"); + if (methodref != -1) { + if (hier.isClass(methodref)) { + sb.append("methodref: C" + methodref + "\n"); + } else { + sb.append("methodref: I" + methodref + "\n"); + } + } + if (objectref != -1) { + sb.append("objectref: C" + objectref + "\n"); + } + if (callsite != -1) { + sb.append("callsite: C" + callsite + "\n"); + } + sb.append("result: " + result + "\n"); + sb.append("classes:\n\n"); + + for(int i = 0; classdata.containsKey(i); i++) { + final ClassData cd = classdata.get(i); + + if (hier.isClass(i)) { + sb.append("class "); + addPackage(sb, cd); + sb.append("C" + i); + } else { + sb.append("interface "); + addPackage(sb, cd); + sb.append("I" + i); + } + + boolean first = true; + for(final int j : hier.classes()) { + if (hier.inherits(i, j)) { + if (first) { + sb.append(" extends C" + j); + } else { + sb.append(", C" + j); + } + } + } + + first = true; + for(final int j : hier.interfaces()) { + if (hier.inherits(i, j)) { + if (first) { + sb.append(" implements I" + j); + } else { + sb.append(", I" + j); + } + } + } + + sb.append(cd); + } + + return sb.toString(); + } + + /** + * A builder, facilitating building up test cases. + */ + public static class Builder { + /** + * A map from class (or interface) id's to ClassDatas + */ + public final HashMap classdata; + /** + * The hierarchy shape. + */ + public final HierarchyShape hier; + /** + * Which invoke instruction to use. + */ + public InvokeInstruction invoke; + /** + * The id of the methodref (or interface methodref). + */ + public int methodref = -1; + /** + * The id of the object ref. Note that for the generator + * framework to work, this must be set to something. If an + * objectref isn't used, just set it to the methodref. + */ + public int objectref = -1; + /** + * The id of the callsite. + */ + public int callsite = -1; + /** + * The id of the expected result. This is used to store the + * expected resolution result. + */ + public int expected; + /** + * The expected result. This needs to be set before the final + * test case is built. + */ + public Result result; + + /** + * Create an empty Builder object. + */ + public Builder() { + classdata = new HashMap<>(); + hier = new HierarchyShape(); + } + + private Builder(final HashMap classdata, + final HierarchyShape hier, + final InvokeInstruction invoke, + final int methodref, + final int objectref, + final int callsite, + final int expected, + final Result result) { + this.classdata = classdata; + this.hier = hier; + this.invoke = invoke; + this.methodref = methodref; + this.objectref = objectref; + this.callsite = callsite; + this.expected = expected; + this.result = result; + } + + private Builder(final Builder other) { + this((HashMap) other.classdata.clone(), + other.hier.copy(), other.invoke, other.methodref, other.objectref, + other.callsite, other.expected, other.result); + } + + public SelectionResolutionTestCase build() { + if (result != null) { + return new SelectionResolutionTestCase(classdata, hier, invoke, + methodref, objectref, + callsite, result); + } else { + return new SelectionResolutionTestCase(classdata, hier, invoke, + methodref, objectref, + callsite, expected); + } + } + + /** + * Set the expected result. + */ + public void setResult(final Result result) { + this.result = result; + } + + /** + * Add a class, and return its id. + * + * @return The new class' id. + */ + public int addClass(final ClassData data) { + final int id = hier.addClass(); + classdata.put(id, data); + return id; + } + + /** + * Add an interface, and return its id. + * + * @return The new class' id. + */ + public int addInterface(final ClassData data) { + final int id = hier.addInterface(); + classdata.put(id, data); + return id; + } + + /** + * Make a copy of this builder. + */ + public Builder copy() { + return new Builder(this); + } + + public String toString() { + final StringBuilder sb = new StringBuilder(); + //sb.append("hierarchy:\n" + hier + "\n"); + sb.append("invoke: " + invoke + "\n"); + if (methodref != -1) { + if (hier.isClass(methodref)) { + sb.append("methodref: C" + methodref + "\n"); + } else { + sb.append("methodref: I" + methodref + "\n"); + } + } + if (objectref != -1) { + sb.append("objectref: C" + objectref + "\n"); + } + if (callsite != -1) { + sb.append("callsite: C" + callsite + "\n"); + } + if (expected != -1) { + if (hier.isClass(expected)) { + sb.append("expected: C" + expected + "\n"); + } else { + sb.append("expected: I" + expected + "\n"); + } + } + sb.append("result: " + result + "\n"); + sb.append("classes:\n\n"); + + for(int i = 0; classdata.containsKey(i); i++) { + final ClassData cd = classdata.get(i); + + if (hier.isClass(i)) { + sb.append("class "); + addPackage(sb, cd); + sb.append("C" + i); + } else { + sb.append("interface "); + addPackage(sb, cd); + sb.append("I" + i); + } + + boolean first = true; + for(final int j : hier.classes()) { + if (hier.inherits(i, j)) { + if (first) { + sb.append(" extends C" + j); + } else { + sb.append(", C" + j); + } + } + } + + first = true; + for(final int j : hier.interfaces()) { + if (hier.inherits(i, j)) { + if (first) { + sb.append(" implements I" + j); + } else { + sb.append(", I" + j); + } + } + } + + sb.append(cd); + } + + return sb.toString(); + } + } +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/Template.java 2015-04-17 16:07:59.902467005 -0400 @@ -0,0 +1,5003 @@ +/* + * Copyright (c) 2014, 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 + * @library /testlibrary/selection_resolution/ + * @run main Template + */ + +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.LinkedList; + +/** + * Templates are sets of transformations that are applied to a + * SelectionResolutionTestCase.Builder as part of building up a test + * case. Templates should contain a collection of different + * transforms, all of which represent an "interesting" case in a + * general category of cases. + * + */ +public class Template { + + public enum Kind { CLASS, INTERFACE; } + + public final Collection> cases; + public final String name; + + /** + * Create a template from a collection of lambdas that modify a Builder. + * + * @param name The name of the template. + * @param cases The cases in the template. + */ + public Template(final String name, + final Collection> cases) { + this.cases = cases; + this.name = name; + } + + /** + * Build a template out of a set of lambdas that modify a Builder. + * + * @param name The name of the template. + * @param cases The cases in the template. + */ + public Template(final String name, + final Consumer... cases) { + this(name, Arrays.asList(cases)); + } + + /** + * Build a template out of a set of lambdas that modify a Builder. + * Also include all cases from another template. + * + * @param name The name of the template. + * @param include Include all cases from this template. + * @param cases The cases in the template. + */ + public Template(final String name, + final Template include, + final Consumer... cases) { + this(name, new LinkedList(include.cases)); + this.cases.addAll(Arrays.asList(cases)); + } + + /** + * Build a template out of a set of lambdas that modify a Builder. + * Also include all cases from another template. + * + * @param name The name of the template. + * @param include Include all cases from this template. + * @param cases The cases in the template. + */ + public Template(final String name, + final Template... others) { + this(name, new LinkedList()); + + for(final Template template : others) { + cases.addAll(template.cases); + } + } + + /** + * Run all cases in the template. This will run each action in + * the template and then call the next action on a separate copy + * of the builder parameter. + * + * @param The next action to perform of the Builder. + * @param The Builder to modify. + */ + public void runCases(final Consumer next, + final SelectionResolutionTestCase.Builder builder) { + for(final Consumer thiscase : cases) { + final SelectionResolutionTestCase.Builder localbuilder = builder.copy(); + thiscase.accept(localbuilder); + next.accept(localbuilder); + } + } + + public void printCases(final SelectionResolutionTestCase.Builder builder) { + int i = 1; + System.err.println("Template " + name + ":\n"); + for(final Consumer thiscase : cases) { + final SelectionResolutionTestCase.Builder localbuilder = builder.copy(); + thiscase.accept(localbuilder); + System.err.println("Case " + i++); + System.err.println(localbuilder); + } + } + + /* Create an empty class in the given package */ + public static final ClassData emptyClass(final ClassData.Package pck) { + return new ClassData(pck, null); + } + + /* These are functions that are used to build callsite templates */ + public static void callsiteIsMethodref(final SelectionResolutionTestCase.Builder builder) { + builder.callsite = builder.methodref; + } + + public static void callsiteSubclassMethodref(final SelectionResolutionTestCase.Builder builder) { + final int callsite = + builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + builder.hier.addInherit(callsite, builder.methodref); + builder.callsite = callsite; + } + + public static void callsiteUnrelatedMethodref(final SelectionResolutionTestCase.Builder builder) { + final int callsite = + builder.addClass(Template.emptyClass(ClassData.Package.SAME)); + builder.callsite = callsite; + } + + public static void methodrefIsExpected(final SelectionResolutionTestCase.Builder builder) { + builder.methodref = builder.expected; + } + + public static final Template MethodrefEqualsExpected = + new Template("MethodrefEqualsExpected", + Template::methodrefIsExpected); + + /***************************** + * Set Invoke Template * + *****************************/ + + public static final Template SetInvoke(final SelectionResolutionTestCase.InvokeInstruction invoke) { + return new Template("SetInvoke(" + invoke + ")", + Collections.singleton((builder) -> { + builder.invoke = invoke; + })); + } + + /***************************** + * Result Combo Template * + *****************************/ + public static Template ResultCombo(final EnumSet kinds, + final EnumSet accesses, + final EnumSet contexts, + final EnumSet packages) { + final LinkedList> cases = + new LinkedList<>(); + + for (final Kind kind : kinds) { + for (final MethodData.Access acc : accesses) { + for (final MethodData.Context ctx : contexts) { + if (!(acc == MethodData.Access.PRIVATE && + ctx == MethodData.Context.ABSTRACT)) { + for (final ClassData.Package pck : packages) { + cases.add((builder) -> { + final MethodData meth = new MethodData(acc, ctx); + final ClassData cls = new ClassData(pck, meth); + switch(kind) { + case CLASS: + builder.expected = builder.addClass(cls); + break; + case INTERFACE: + builder.expected = builder.addInterface(cls); + break; + } + }); + } + } + } + } + } + + return new Template("ResultCombo", cases); + } + + public static Template ResolutionOverride(final EnumSet kinds, + final EnumSet accesses, + final EnumSet contexts, + final EnumSet packages) { + final LinkedList> cases = + new LinkedList<>(); + + for (final Kind kind : kinds) { + for (final MethodData.Access acc : accesses) { + for (final MethodData.Context ctx : contexts) { + if (!(acc == MethodData.Access.PRIVATE && + ctx == MethodData.Context.ABSTRACT)) { + for (final ClassData.Package pck : packages) { + cases.add((builder) -> { + final MethodData meth = new MethodData(acc, ctx); + final ClassData cls = new ClassData(pck, meth); + int override = -1; + switch(kind) { + case CLASS: + override = builder.addClass(cls); + break; + case INTERFACE: + override = builder.addInterface(cls); + break; + } + builder.hier.addInherit(override, builder.expected); + }); + } + } + } + } + } + + return new Template("ResultCombo", cases); + } + + /****************************** + * Resolution Templates * + ******************************/ + + private static MethodData getMethodData(final MethodData.Access acc, + final MethodData.Context ctx) { + if (!(acc == MethodData.Access.PUBLIC || + acc == MethodData.Access.PLACEHOLDER) && + ctx != MethodData.Context.STATIC) { + return null; + } else { + return new MethodData(MethodData.Access.PUBLIC, ctx); + } + } + + public static final Template MethodrefNotEqualsExpectedClass = + new Template("MethodrefNotEqualsExpectedClass", + /* Case 1: Inherit from super. + * + * C2[](res) + * C1[C2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final int C2 = builder.expected; + final int C1 = builder.addClass(emptyClass(ClassData.Package.SAME)); + builder.hier.addInherit(C1, C2); + builder.methodref = C1; + }, + /* Case 2: Inherit from super. + * + * C2[](res), I[](def) + * C1[C2,I]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final int C2 = builder.expected; + final int C1 = builder.addClass(emptyClass(ClassData.Package.SAME)); + final int I = builder.addInterface(withDef); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I); + builder.methodref = C1; + }, + /* Case 3: Inherit from super's super. + * + * C3[](res) + * C2[](), I[](def) + * C1[C2,I]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final int C3 = builder.expected; + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(ClassData.Package.SAME)); + final int I = builder.addInterface(withDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I); + builder.methodref = C1; + }); + + public static final Template IfaceMethodrefNotEqualsExpected = + new Template("IfaceMethodrefNotEqualsExpected", + /* Case 1: Inherit from super. + * + * I2[](res) + * I1[I2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I2 = builder.expected; + final int I1 = builder.addInterface(emptyClass(pck)); + builder.hier.addInherit(I1, I2); + builder.methodref = I1; + }, + /* Case 2: Inherit from super, skip private. + * + * I2[](res) + * I2[I3](priv) + * I1[I2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = new ClassData(pck, meth); + final int I3 = builder.expected; + final int I2 = builder.addInterface(withPrivDef); + final int I1 = builder.addInterface(emptyClass(pck)); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I2, I3); + builder.methodref = I1; + }, + /* Case 3: Inherit from super, skip static. + * + * I2[](res) + * I2[I3](stat) + * I1[I2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int I3 = builder.expected; + final int I2 = builder.addInterface(withStatDef); + final int I1 = builder.addInterface(emptyClass(pck)); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I2, I3); + builder.methodref = I1; + }, + /* Case 4: Maximally-specific. + * + * I3[](def) + * I2[I3](res) + * I1[I2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final int I3 = builder.addInterface(withDef); + final int I2 = builder.expected; + final int I1 = builder.addInterface(emptyClass(pck)); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I2, I3); + builder.methodref = I1; + }, + /* Case 5: Diamond, expected at top. + * + * I4[](res) + * I2[I4](), I3[I4]() + * I1[I2,I3]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I4 = builder.expected; + final int I3 = builder.addInterface(emptyClass(pck)); + final int I2 = builder.addInterface(emptyClass(pck)); + final int I1 = builder.addInterface(emptyClass(pck)); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I4); + builder.hier.addInherit(I3, I4); + builder.methodref = I1; + }, + /* Case 6: Diamond, skip private. + * + * I4[](res) + * I2[I4](priv), I3[I4]() + * I1[I2,I3]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = new ClassData(pck, meth); + final int I4 = builder.expected; + final int I3 = builder.addInterface(emptyClass(pck)); + final int I2 = builder.addInterface(withPrivDef); + final int I1 = builder.addInterface(emptyClass(pck)); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I4); + builder.hier.addInherit(I3, I4); + builder.methodref = I1; + }, + /* Case 7: Diamond, skip static. + * + * I4[](res) + * I2[I4](stat), I3[I4]() + * I1[I2,I3]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int I4 = builder.expected; + final int I3 = builder.addInterface(emptyClass(pck)); + final int I2 = builder.addInterface(withStatDef); + final int I1 = builder.addInterface(emptyClass(pck)); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I4); + builder.hier.addInherit(I3, I4); + builder.methodref = I1; + }, + /* Case 8: Diamond, maximally-specific. + * + * I4[](def) + * I2[I4](res), I3[I4]() + * I1[I2,I3]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final int I4 = builder.addInterface(withDef); + final int I3 = builder.addInterface(emptyClass(pck)); + final int I2 = builder.expected; + final int I1 = builder.addInterface(emptyClass(pck)); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I4); + builder.hier.addInherit(I3, I4); + builder.methodref = I1; + }, + /* Case 9: Diamond, maximally-specific, skipping private. + * + * I4[](def) + * I2[I4](res), I3[I4](priv) + * I1[I2,I3]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = new ClassData(pck, meth); + final int I4 = builder.addInterface(withDef); + final int I3 = builder.addInterface(withPrivDef); + final int I2 = builder.expected; + final int I1 = builder.addInterface(emptyClass(pck)); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I4); + builder.hier.addInherit(I3, I4); + builder.methodref = I1; + }, + /* Case 10: Diamond, maximally-specific, skipping static. + * + * I4[](def) + * I2[I4](res), I3[I4](stat) + * I1[I2,I3]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int I4 = builder.addInterface(withDef); + final int I3 = builder.addInterface(withStatDef); + final int I2 = builder.expected; + final int I1 = builder.addInterface(emptyClass(pck)); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I4); + builder.hier.addInherit(I3, I4); + builder.methodref = I1; + }); + + public static final Template MethodrefNotEqualsExpectedIface = + new Template("MethodrefNotEqualsExpectedIface", + /* Case 1: Inherit from superinterface. + * + * I[](res) + * C[I]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I = builder.expected; + final int C = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C, I); + builder.methodref = C; + }, + /* Case 2: Diamond, expected at top. + * + * I3[](res) + * I1[I3](), I2[I3]() + * C[I1,I2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I3 = builder.expected; + final int I2 = builder.addInterface(emptyClass(pck)); + final int I1 = builder.addInterface(emptyClass(pck)); + final int C = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.methodref = C; + }, + /* Case 3: Diamond, skipping private. + * + * I3[](def) + * I1[I3](priv), I2[I3]() + * C[I1,I2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = new ClassData(pck, meth); + final int I3 = builder.expected; + final int I2 = builder.addInterface(emptyClass(pck)); + final int I1 = builder.addInterface(withPrivDef); + final int C = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.methodref = C; + }, + /* Case 4: Diamond, skipping static. + * + * I3[](def) + * I1[I3](stat), I2[I3]() + * C[I1,I2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int I3 = builder.expected; + final int I2 = builder.addInterface(emptyClass(pck)); + final int I1 = builder.addInterface(withStatDef); + final int C = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.methodref = C; + }, + /* Case 5: Diamond, maximally-specific. + * + * I3[](def) + * I1[I3](res), I2[I3]() + * C[I1,I2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final int I3 = builder.addInterface(withDef); + final int I2 = builder.addInterface(emptyClass(pck)); + final int I1 = builder.expected; + final int C = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.methodref = C; + }, + /* Case 6: Diamond, maximally-specific, skipping private. + * + * I3[](def) + * I1[I3](res), I2[I3](priv) + * C[I1,I2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = new ClassData(pck, meth); + final int I3 = builder.addInterface(withDef); + final int I2 = builder.addInterface(withPrivDef); + final int I1 = builder.expected; + final int C = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.methodref = C; + }, + /* Case 7: Diamond, maximally-specific, skipping static. + * + * I3[](def) + * I1[I3](res), I2[I3](stat) + * C[I1,I2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int I3 = builder.addInterface(withDef); + final int I2 = builder.addInterface(withStatDef); + final int I1 = builder.expected; + final int C = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.methodref = C; + }, + /* Case 8: Diamond, with superclass, expected at top. + * + * I2[](res) + * C2[I2](), I1[I2]() + * C1[I1,C2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I2 = builder.expected; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addInterface(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C2, I2); + builder.methodref = C1; + }, + /* Case 9: Diamond with superclass, maximally-specific. + * + * I2[](def) + * C2[I2](), I1[I2](res), + * C1[I1,C2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final int I2 = builder.addInterface(withDef); + final int C2 = builder.addClass(emptyClass(pck)); + final int I1 = builder.expected; + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C2, I2); + builder.methodref = C1; + }, + /* Case 10: Inherit through superclass. + * + * I[](res) + * C2[I]() + * C1[C2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I = builder.expected; + final int C2 = builder.addInterface(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I); + builder.methodref = C1; + }, + /* Case 11: Diamond, inherit through superclass, + * expected at top. + * + * I3[](res) + * I1[I3](), I2[I3]() + * C2[I1,I2]() + * C1[C2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I3 = builder.expected; + final int I2 = builder.addInterface(emptyClass(pck)); + final int I1 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.hier.addInherit(C1, C2); + builder.methodref = C1; + }, + /* Case 12: Diamond through superclass, skip private. + * + * I3[](res) + * I1[I3](priv), I2[I3]() + * C2[I1,I2]() + * C1[C2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = new ClassData(pck, meth); + final int I3 = builder.expected; + final int I2 = builder.addInterface(emptyClass(pck)); + final int I1 = builder.addInterface(withPrivDef); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.hier.addInherit(C1, C2); + builder.methodref = C1; + }, + /* Case 13: Diamond through superclass, skip static. + * + * I3[](def) + * I1[I3](stat), I2[I3]() + * C2[I1,I2]() + * C1[C2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int I3 = builder.expected; + final int I2 = builder.addInterface(emptyClass(pck)); + final int I1 = builder.addInterface(withStatDef); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.hier.addInherit(C1, C2); + builder.methodref = C1; + }, + /* Case 14: Diamond through superclass, maximally-specific. + * + * I3[](def) + * I1[I3](res), I2[I3]() + * C2[I1,I2]() + * C1[C2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final int I3 = builder.addInterface(withDef); + final int I2 = builder.addInterface(emptyClass(pck)); + final int I1 = builder.expected; + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.hier.addInherit(C1, C2); + builder.methodref = C1; + }, + /* Case 15: Diamond through superclass, + * maximally-specific, skip private. + * + * I3[](def) + * I1[I3](res), I2[I3](priv) + * C2[I1,I2]() + * C1[C2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = new ClassData(pck, meth); + final int I3 = builder.addInterface(withDef); + final int I2 = builder.addInterface(withPrivDef); + final int I1 = builder.expected; + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.hier.addInherit(C1, C2); + builder.methodref = C1; + }, + /* Case 16: Diamond through superclass, + * maximally-specific, skip static. + * + * I3[](pub) + * I1[I3](res), I2[I3](stat) + * C2[I1,I2]() + * C1[C2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int I3 = builder.addInterface(withDef); + final int I2 = builder.addInterface(withStatDef); + final int I1 = builder.expected; + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.hier.addInherit(C1, C2); + builder.methodref = C1; + }, + /* Case 17: Diamond, with superclass, inherit through + * superclass, expected at top. + * + * I2[](res) + * C3[I2](), I1[I2]() + * C2[I1,C3]() + * C1[C2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I2 = builder.expected; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C3 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C3, I2); + builder.hier.addInherit(C1, C2); + builder.methodref = C1; + }, + /* Case 18: Diamond, with superclass, inherit through + * superclass, maximally-specific. + * + * I2[](def) + * C3[I2](), I1[I2](res), + * C2[I1,C3]() + * C1[I1,C2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final int I2 = builder.addInterface(withDef); + final int C3 = builder.addClass(emptyClass(pck)); + final int I1 = builder.expected; + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C3, I2); + builder.hier.addInherit(C1, C2); + builder.methodref = C1; + }); + + public static final Template IfaceMethodrefAmbiguous = + new Template("IfaceMethodrefAmbiguous", + /* Ambiguous. + * + * I2[](def), I3[](def) + * I1[I2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData expected = + builder.classdata.get(builder.expected); + final int I3 = builder.addInterface(expected); + final int I2 = builder.expected; + final int I1 = builder.addInterface(emptyClass(pck)); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I1, I3); + builder.methodref = I1; + }); + + public static final Template MethodrefAmbiguous = + new Template("MethodrefAmbiguous", + /* Ambiguous. + * + * I1[](def), I2[](def) + * C[I2]() = mref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData expected = + builder.classdata.get(builder.expected); + final int I1 = builder.addInterface(expected); + final int I2 = builder.expected; + final int C = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C, I2); + builder.hier.addInherit(C, I1); + builder.methodref = C; + }); + + /****************************** + * Callsite Templates * + ******************************/ + + public static final Template AllCallsiteCases = + new Template("AllCallsiteCases", + Template::callsiteIsMethodref, + Template::callsiteSubclassMethodref, + Template::callsiteUnrelatedMethodref); + + public static final Template InvokespecialCallsiteCases = + new Template("InvokespecialCallsiteCases", + Template::callsiteIsMethodref, + Template::callsiteSubclassMethodref); + + public static final Template CallsiteEqualsMethodref = + new Template("CallsiteEqualsMethodref", + Template::callsiteIsMethodref); + + public static final Template CallsiteSubclassMethodref = + new Template("CallsiteSubclassMethodref", + Template::callsiteSubclassMethodref); + + public static final Template CallsiteUnrelatedToMethodref = + new Template("CallsiteUnrelatedToMethodref", + Template::callsiteUnrelatedMethodref); + + public static final Template CallsiteNotEqualsMethodref = + new Template("CallsiteNotEqualsMethodref", + Template::callsiteSubclassMethodref, + Template::callsiteUnrelatedMethodref); + + /********************************* + * AbstractMethodError Templates * + *********************************/ + + public static final Template ReabstractExpectedIface = + new Template("ReabstractExpectedIface", + (builder) -> {}, + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData expected = + builder.classdata.get(builder.expected); + final ClassData.Package pck = expected.packageId; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = + getMethodData(acc, MethodData.Context.STATIC); + final ClassData withDef = new ClassData(pck, mdata); + final int C2 = builder.addInterface(withDef); + final int C1 = builder.expected; + builder.hier.addInherit(C1, C2); + }, + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData expected = + builder.classdata.get(builder.expected); + final ClassData.Package pck = expected.packageId; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = + getMethodData(acc, MethodData.Context.INSTANCE); + final ClassData withDef = new ClassData(pck, mdata); + final int C2 = builder.addInterface(withDef); + final int C1 = builder.expected; + builder.hier.addInherit(C1, C2); + }); + + public static final Template ReabstractExpectedClass = + new Template("ReabstractExpectedClass", + ReabstractExpectedIface, + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData expected = + builder.classdata.get(builder.expected); + final ClassData.Package pck = expected.packageId; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = + getMethodData(acc, MethodData.Context.STATIC); + final ClassData withDef = new ClassData(pck, mdata); + final int C2 = builder.addClass(withDef); + final int C1 = builder.expected; + builder.hier.addInherit(C1, C2); + }, + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData expected = + builder.classdata.get(builder.expected); + final ClassData.Package pck = expected.packageId; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = + getMethodData(acc, MethodData.Context.INSTANCE); + final ClassData withDef = new ClassData(pck, mdata); + final int C2 = builder.addClass(withDef); + final int C1 = builder.expected; + builder.hier.addInherit(C1, C2); + }); + + public static final Template ReabstractMethodrefResolvedClass = + new Template("ReabstractMethodrefResolvedClass", + /* Case 1: Objectref overrides. + * + * C2[](*) = mref + * C1[C2](res) = oref = expected + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int C2 = builder.methodref; + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C1; + }, + /* Case 2: Objectref's super overrides. + * + * C3[*](*) = mref + * C2[C3](res) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 3: Objectref's super overrides, skip private. + * + * C3[*](*) = mref + * C2[C3](res) = expected + * C1[C2](priv) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(withPrivDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 4: Objectref's super overrides, skip static. + * + * C3[*](*) = mref + * C2[C3](res) = expected + * C1[C2](stat) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(withStatDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }); + + public static final Template ReabstractMethodrefResolvedIface = + new Template("ReabstractMethodrefResolvedIface", + /* Case 1: Objectref overrides. + * + * C2[](*) = mref + * C1[C2](res) = oref = expected + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int C2 = builder.methodref; + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C1; + }, + /* Case 2: Objectref's super overrides. + * + * C3[](*) = mref + * C2[C3](res) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 3: Objectref's super overrides, skip private. + * + * C3[*](*) = mref + * C2[C3](res) = expected + * C1[C2](priv) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(withPrivDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 4: Objectref's super overrides, skip static. + * + * C3[*](*) = mref + * C2[C3](res) = expected + * C1[C2](stat) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(withStatDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 5: Overlapping with new interface overriding. + * + * I2[*](def) = old expected + * C2[*](*) = mref, I1[I2](res) = expected + * C1[C2,I2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int C2 = builder.methodref; + final int I2 = builder.expected; + final int I1 = builder.addInterface(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(I1, I2); + builder.objectref = C1; + builder.expected = I1; + }, + /* Case 6: Overlapping with new interface, skip private. + * + * I2[*](def) = old expected + * C2[*](*) = mref, I1[I2](res) = expected + * C1[C2,I2](priv) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = new ClassData(pck, meth); + final int C2 = builder.methodref; + final int I2 = builder.expected; + final int I1 = builder.addInterface(withDef); + final int C1 = builder.addClass(withPrivDef); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(I1, I2); + builder.objectref = C1; + builder.expected = I1; + }, + /* Case 7: Overlapping with new interface, skip static. + * + * I2[*](def) = old expected + * C2[*](*) = mref, I1[I2](res) = expected + * C1[C2,I2](stat) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int C2 = builder.methodref; + final int I2 = builder.expected; + final int I1 = builder.addInterface(withDef); + final int C1 = builder.addClass(withStatDef); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(I1, I2); + builder.objectref = C1; + builder.expected = I1; + }, + /* Case 8: Overlap with objectref's super with new + * interface overriding, inherit through class. + * + * I2[*](def) = old expected + * C3[](*) = mref, I1[I2](res) = expected + * C2[C3,I1]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int C3 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int I2 = builder.expected; + final int I1 = builder.addInterface(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(I1, I2); + builder.objectref = C1; + builder.expected = I1; + }, + /* Case 9: Overlap with objectref's super with new + * interface double diamond, overriding. + * + * I3[*](def) = old expected + * C3[](*) = mref, I2[I3](def) + * C2[C3,I2](), I1[I2](res) = expected + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int C3 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int I3 = builder.expected; + final int I2 = builder.addInterface(withDef); + final int I1 = builder.addInterface(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I2, I3); + builder.objectref = C1; + builder.expected = I1; + }, + /* Case 10: Overlap with objectref's super with new + * interface double diamond, skip private. + * + * I3[*](def) = old expected + * C3[](*) = mref, I2[I3](res) = expected + * C2[C3,I2](), I1[I2](priv) + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int I3 = builder.expected; + final int I2 = builder.addInterface(withDef); + final int I1 = builder.addInterface(withPrivDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I2, I3); + builder.objectref = C1; + builder.expected = I2; + }, + /* Case 11: Overlap with objectref's super with new + * interface double diamond, skip static. + * + * I3[*](def) = old expected + * C3[](*) = mref, I2[I3](res) = expected + * C2[C3,I2](), I1[I2](stat) + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int I3 = builder.expected; + final int I2 = builder.addInterface(withDef); + final int I1 = builder.addInterface(withStatDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I2, I3); + builder.objectref = C1; + builder.expected = I2; + }, + /* Case 12: Objectref's super overrides, skip interface below. + * + * C3[](*) = mref + * C2[C3](res) = expected, I[](def) + * C1[C2,I]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + final int I = builder.addInterface(withDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 13: Objectref's super overrides, skip interface above. + * + * C3[](*) = mref, I[](def) + * C2[C3,I](res) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + final int I = builder.addInterface(withDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I); + builder.objectref = C1; + builder.expected = C2; + }); + + public static final Template ReabstractIfaceMethodrefResolved = + new Template("ReabstractIfaceMethodrefResolved", + /* Case 1: Objectref overrides. + * + * I[](*) = mref + * C[I](res) = oref = expected + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int I = builder.methodref; + final int C = builder.addClass(withDef); + builder.hier.addInherit(C, I); + builder.objectref = C; + builder.expected = C; + }, + /* Case 2: Diamond, methodref at top, overriding. + * + * I3[](*) = mref + * I1[I3](), I2[I3](res) = expected + * C[I1,I2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int I3 = builder.methodref; + final int I2 = builder.addInterface(withDef); + final int I1 = builder.addInterface(emptyClass(pck)); + final int C = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.objectref = C; + builder.expected = I2; + }, + /* Case 3: Diamond, methodref at top, skip static. + * + * I3[](*) = mref + * I1[I3](), I2[I3](res) = expected + * C[I1,I2](stat) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int I3 = builder.methodref; + final int I2 = builder.addInterface(withDef); + final int I1 = builder.addInterface(emptyClass(pck)); + final int C = builder.addClass(withStatDef); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.objectref = C; + builder.expected = I2; + }, + /* Case 4: Diamond, with superclass, methodref at top, + * class overriding. + * + * I2[](*) = mref + * C2[I2](res) = expected, I1[I2]() + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int I2 = builder.methodref; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 5: Diamond, with superclass, methodref at top, + * class overriding, skip static. + * + * I2[](*) = mref + * C2[I2](res) = expected, I1[I2]() + * C1[I1,C2](stat) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int I2 = builder.methodref; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(withStatDef); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 6: Diamond, with superclass, expected at top, + * interface overriding + * + * I2[](*) = mref + * C2[I2](), I1[I2](res) = expected + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int I2 = builder.methodref; + final int I1 = builder.addInterface(withDef); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + builder.expected = I1; + }, + /* Case 7: Diamond, with superclass, expected at top, + * interface skip static + * + * I2[](*) = mref + * C2[I2](), I1[I2](res) = expected + * C1[I1,C2](stat) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int I2 = builder.methodref; + final int I1 = builder.addInterface(withDef); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(withStatDef); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + builder.expected = I1; + }, + /* Case 8: Y, with superclass, overlaping, expected + * at top, class overrides + * + * C2[I2](res) = expected, I1[](*) = mref + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int I1 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 9: Diamond, with superclass, overlaping, expected + * at top, class overrides + * + * I2[](def) = old expected + * C2[I2](res) = expected, I1[](*) = mref + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int I2 = builder.expected; + final int I1 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 10: Diamond, with superclass, overlaping, expected + * at top, class overrides, skipping static + * + * I2[](def) = old expected + * C2[I2](res) = expected, I1[](*) = mref + * C1[I1,C2](stat) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int I2 = builder.expected; + final int I1 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(withStatDef); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 11: Superclass overrides. + * + * I[](*) = mref + * C2[I](res) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int I = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I); + builder.objectref = C1; + }, + /* Case 12: Superclass overrides, skipping static. + * + * I[](*) = mref + * C2[I](res) = expected + * C1[C2](stat) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int I = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(withStatDef); + builder.hier.addInherit(C1, I); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I); + builder.objectref = C1; + }, + /* Case 13: Double diamond, with superclass, inherit through + * superclass, expected at top. + * + * I3[](def) = old expected + * C3[I3](), I2[*](*) = mref + * C2[I2,C3](), I1[I2](res) = expected + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final int I3 = builder.expected; + final int I2 = builder.methodref; + final int I1 = builder.addInterface(withDef); + final int C3 = builder.addClass(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C3, I3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C1, I1); + builder.objectref = C1; + builder.expected = I1; + }, + /* Case 14: Double diamond, with superclass, inherit through + * superclass, expected at top. + * + * I3[](def) = mref + * C3[I3](), I2[*](*) = expected + * C2[I2,C3](), I1[I2](priv) + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = new ClassData(pck, meth); + final int I3 = builder.methodref; + final int I2 = builder.addInterface(withDef); + final int I1 = builder.addInterface(withPrivDef); + final int C3 = builder.addClass(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C3, I3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C1, I1); + builder.objectref = C1; + builder.expected = I2; + }, + /* Case 15: Double diamond, with superclass, inherit through + * superclass, expected at top. + * + * I3[](def) = mref + * C3[I3](), I2[*](*) = expected + * C2[I2,C3](), I1[I2](stat) + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final ClassData withDef = + new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT)); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = new ClassData(pck, meth); + final int I3 = builder.methodref; + final int I2 = builder.addInterface(withDef); + final int I1 = builder.addInterface(withStatDef); + final int C3 = builder.addClass(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C3, I3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C1, I1); + builder.objectref = C1; + builder.expected = I2; + }); + + /****************************** + * Abstract Overrides * + ******************************/ + + public static final Template OverrideAbstractExpectedIface = + Template.ResolutionOverride(EnumSet.of(Template.Kind.INTERFACE), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.allOf(MethodData.Context.class), + EnumSet.of(ClassData.Package.SAME)); + + public static final Template OverrideAbstractExpectedClass = + Template.ResolutionOverride(EnumSet.allOf(Template.Kind.class), + EnumSet.of(MethodData.Access.PUBLIC), + EnumSet.allOf(MethodData.Context.class), + EnumSet.of(ClassData.Package.SAME)); + + public static final Template SelectionOverrideAbstract = + new Template("SelectionOverrideAbstract", + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData expected = + builder.classdata.get(builder.expected); + final MethodData olddef = + expected.methoddata; + if (MethodData.Context.ABSTRACT == olddef.context) { + final ClassData.Package pck = expected.packageId; + final MethodData.Access acc = olddef.access; + final MethodData mdata = + getMethodData(MethodData.Access.PUBLIC, + MethodData.Context.INSTANCE); + final ClassData withDef = new ClassData(pck, mdata); + final int C2 = builder.objectref; + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C1; + } + }); + + + /****************************** + * Ignored Abstract Templates * + ******************************/ + + public static final Template IgnoredAbstract = + new Template("IgnoredAbstract", + (builder) -> {}, + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData methodref = + builder.classdata.get(builder.methodref); + final ClassData.Package pck = methodref.packageId; + final MethodData mdata = + getMethodData(MethodData.Access.PUBLIC, + MethodData.Context.ABSTRACT); + final ClassData withDef = new ClassData(pck, mdata); + final int C2 = builder.addInterface(withDef); + final int C1 = builder.methodref; + builder.hier.addInherit(C1, C2); + }); + + /****************************** + * Selection Templates * + ******************************/ + + + + public static final Template TrivialObjectref = + new Template("TrivialObjectref", + Collections.singleton((builder) -> { + builder.objectref = builder.methodref; + })); + + public static final Template TrivialObjectrefNotEqualMethodref = + new Template("TrivialObjectrefNotEqualMethodref", + Collections.singleton( + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData.Package pck = oldexpected.packageId; + final int C2 = builder.methodref; + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + })); + + public static final Template MethodrefSelectionResolvedIsClassNoOverride = + new Template("MethodrefSelectionResolvedIsClassNoOverride", + /* Trivial. + * + * C[](*) = mref = oref + */ + (builder) -> { + builder.objectref = builder.methodref; + }, + /* Case 1: Inherit from super. + * + * C2[](*) = mref + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final int C2 = builder.methodref; + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 2: Objectref has private def. + * + * C2[](*) = mref + * C1[C2](priv) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withDef = new ClassData(pck, meth); + final int C2 = builder.methodref; + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 3: Objectref has static def. + * + * C2[](*) = mref + * C1[C2](stat) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withDef = new ClassData(pck, meth); + final int C2 = builder.methodref; + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 4: Skip inherit from interface. + * + * C2[](*) = mref, I[](def) + * C1[C2,I]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData.Package pck = oldexpected.packageId; + final MethodData.Context ctx = + builder.classdata.get(builder.expected).methoddata.context; + final MethodData.Access acc = + builder.classdata.get(builder.expected).methoddata.access; + final MethodData mdata = getMethodData(acc, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final int C2 = builder.methodref; + final int C1 = builder.addClass(emptyClass(pck)); + final int I = builder.addInterface(withDef); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I); + builder.objectref = C1; + }, + /* Case 5: Objectref's super has a private def. + * + * C3[*](*) = mref + * C2[C3](res) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 6: Objectref's super has a static def. + * + * C3[*](*) = mref + * C2[C3](res) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withDef = + new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }); + + public static final Template MethodrefSelectionResolvedIsClassOverride = + new Template("MethodrefSelectionResolvedIsClassOverride", + /* Case 7: Objectref overrides. + * + * C2[](*) = mref + * C1[C2](res) = oref = expected + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int C2 = builder.methodref; + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C1; + }, + /* Case 8: Objectref's super overrides. + * + * C3[*](*) = mref + * C2[C3](res) + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 9: Objectref's super overrides, + * objectref has a private def. + * + * C3[*](*) = mref + * C2[C3](res) + * C1[C2](priv) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(withPrivDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 10: Objectref's super overrides, + * objectref has a static def. + * + * C3[*](*) = mref + * C2[C3](res) + * C1[C2](stat) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withPrivDef = + new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(withPrivDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }); + + public static final Template MethodrefSelectionResolvedIsClass = + new Template("MethodrefSelectionResolvedIsClass", + MethodrefSelectionResolvedIsClassNoOverride, + MethodrefSelectionResolvedIsClassOverride); + + public static final Template MethodrefSelectionPackageSkip = + new Template("MethodrefSelectionPackageSkip", + MethodrefSelectionResolvedIsClass, + /* Case 11: Objectref has public def in other package. + * + * C2[](*) = mref + * Other.C1[C2](pub) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(ClassData.Package.OTHER, meth); + final int C2 = builder.methodref; + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 12: Objectref has package private def in other package. + * + * C2[](*) = mref + * Other.C1[C2](pack) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PACKAGE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(ClassData.Package.OTHER, meth); + final int C2 = builder.methodref; + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 13: Objectref has protected def in other package. + * + * C2[](*) = mref + * Other.C1[C2](prot) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PROTECTED, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(ClassData.Package.OTHER, meth); + final int C2 = builder.methodref; + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 14: Objectref's super has a public def in other package. + * + * C3[*](*) = mref + * Other.C2[C3](pub) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(ClassData.Package.OTHER, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 15: Objectref's super has a package + * private def in other package. + * + * C3[*](*) = mref + * Other.C2[C3](pack) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PACKAGE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(ClassData.Package.OTHER, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 16: Objectref's super has a protected def + * in other package. + * + * C3[*](*) = mref + * Other.C2[C3](pack) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PROTECTED, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(ClassData.Package.OTHER, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 17: Transitive override. + * + * C3[*](*) = mref + * C2[C3](pub) + * Other.C1[C2](pack) = oref, expected + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.INSTANCE); + final MethodData packmeth = + new MethodData(MethodData.Access.PACKAGE, + MethodData.Context.INSTANCE); + final ClassData withPubDef = new ClassData(pck, meth); + final ClassData withPackDef = + new ClassData(ClassData.Package.OTHER, packmeth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withPubDef); + final int C1 = builder.addClass(withPackDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C1; + }, + /* Case 18: Objectref's has a public def in other + * package, skip private. + * + * C3[*](*) = mref + * Other.C2[C3](priv) + * C1[C2](pub) = oref, expected + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(ClassData.Package.OTHER, meth); + final MethodData privmeth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, privmeth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withPrivDef); + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 19: Objectref's has a package private def in other + * package, skip private. + * + * C3[*](*) = mref + * Other.C2[C3](priv) + * C1[C2](pack) = oref, expected + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PACKAGE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(ClassData.Package.OTHER, meth); + final MethodData privmeth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, privmeth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withPrivDef); + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 20: Objectref's has a protected def in other + * package, skip private. + * + * C3[*](*) = mref + * Other.C2[C3](priv) + * C1[C2](pro) = oref, expected + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PROTECTED, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(ClassData.Package.OTHER, meth); + final MethodData privmeth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, privmeth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withPrivDef); + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 21: Objectref's super has a public def in other + * package, skip private. + * + * C3[*](*) = mref + * Other.C2[C3](pub) = expected + * C1[C2](priv) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(ClassData.Package.OTHER, meth); + final MethodData privmeth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, privmeth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(withPrivDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 22: Objectref's superhas a package private + * def in other package, skip private. + * + * C3[*](*) = mref + * Other.C2[C3](pack) = expected + * C1[C2](priv) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PACKAGE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(ClassData.Package.OTHER, meth); + final MethodData privmeth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, privmeth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(withPrivDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 23: Objectref's super has a protected def + * in other package, skip private. + * + * C3[*](*) = mref + * Other.C2[C3](pro) = expected + * C1[C2](priv) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PROTECTED, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(ClassData.Package.OTHER, meth); + final MethodData privmeth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, privmeth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withPrivDef); + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 24: Transitive override, skip private in between. + * + * C4[*](*) = mref + * C3[C4](pub) + * C2[C3](priv) + * Other.C1[C2](pack) = oref, expected + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.INSTANCE); + final MethodData packmeth = + new MethodData(MethodData.Access.PACKAGE, + MethodData.Context.INSTANCE); + final ClassData withPubDef = new ClassData(pck, meth); + final ClassData withPackDef = + new ClassData(ClassData.Package.OTHER, packmeth); + final MethodData privmeth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, privmeth); + final int C4 = builder.methodref; + final int C3 = builder.addClass(withPubDef); + final int C2 = builder.addClass(withPrivDef); + final int C1 = builder.addClass(withPackDef); + builder.hier.addInherit(C3, C4); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C1; + }, + /* Case 25: Transitive override, skip private in between. + * + * C4[*](*) = mref + * C3[C4](pub) + * Other.C2[C3](pack) = expected + * C1[C2](pack) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.INSTANCE); + final MethodData packmeth = + new MethodData(MethodData.Access.PACKAGE, + MethodData.Context.INSTANCE); + final ClassData withPubDef = new ClassData(pck, meth); + final ClassData withPackDef = + new ClassData(ClassData.Package.OTHER, packmeth); + final MethodData privmeth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, privmeth); + final int C4 = builder.methodref; + final int C3 = builder.addClass(withPubDef); + final int C2 = builder.addClass(withPackDef); + final int C1 = builder.addClass(withPrivDef); + builder.hier.addInherit(C3, C4); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C2; + builder.expected = C2; + }); + + public static final Template MethodrefSelectionResolvedIsIfaceNoOverride = + new Template("MethodrefSelectionResolvedIsIfaceNoOverride", + /* Trivial objectref. + * + * C[](*) = mref = oref + */ + (builder) -> { + builder.objectref = builder.methodref; + }, + /* Case 1: Inherit from super. + * + * C2[](*) = mref + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final int C2 = builder.methodref; + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 2: Objectref has private def. + * + * C2[](*) = mref + * C1[C2](priv) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withDef = new ClassData(pck, meth); + final int C2 = builder.methodref; + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 3: Objectref has static def. + * + * C2[](*) = mref + * C1[C2](stat) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withDef = new ClassData(pck, meth); + final int C2 = builder.methodref; + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 4: Overlapping. + * + * I[*](res) = expected + * C2[*](*) = mref + * C1[C2,I]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final int C2 = builder.methodref; + final int I = builder.expected; + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I); + builder.objectref = C1; + }, + /* Case 5: Overlapping with new interface. + * + * I2[*](res) = expected + * C2[*](*) = mref, I1[I2]() + * C1[C2,I2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final int C2 = builder.methodref; + final int I2 = builder.expected; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(I1, I2); + builder.objectref = C1; + }, + /* Case 6: Overlapping with new interface with private def. + * + * I2[*](res) = expected + * C2[*](*) = mref, I1[I2](priv) + * C1[C2,I2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, meth); + final int C2 = builder.methodref; + final int I2 = builder.expected; + final int I1 = builder.addInterface(withPrivDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(I1, I2); + builder.objectref = C1; + }, + /* Case 7: Overlapping with new interface with static def. + * + * I2[*](res) = expected + * C2[*](*) = mref, I1[I2](stat) + * C1[C2,I2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = + new ClassData(pck, meth); + final int C2 = builder.methodref; + final int I2 = builder.expected; + final int I1 = builder.addInterface(withStatDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(I1, I2); + builder.objectref = C1; + }, + /* Case 8: Objectref's super has a private def. + * + * C3[*](*) = mref + * C2[C3](priv) + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 9: Objectref's super has a static def. + * + * C3[*](*) = mref + * C2[C3](stat) + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withDef = + new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 10: Overlap with objectref's super. + * + * I[*](res) = expected + * C3[](*) = mref + * C2[C3,I]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final int C3 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int I = builder.expected; + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I); + builder.objectref = C1; + }, + /* Case 11: Overlap with objectref's super with new interface. + * + * I2[*](res) = expected + * C3[](*) = mref, I1[I2]() + * C2[C3,I1]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final int C3 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int I2 = builder.expected; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(I1, I2); + builder.objectref = C1; + }, + /* Case 12: Overlap with objectref's super with new + * interface with private def. + * + * I2[*](res) = expected + * C3[](*) = mref, I1[I2](priv) + * C2[C3,I1]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int I2 = builder.expected; + final int I1 = builder.addInterface(withPrivDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(I1, I2); + builder.objectref = C1; + }, + /* Case 13: Overlap with objectref's super with new + * interface with static def. + * + * I2[*](res) = expected + * C3[](*) = mref, I1[I2](stat) + * C2[C3,I1]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = + new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int I2 = builder.expected; + final int I1 = builder.addInterface(withStatDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(I1, I2); + builder.objectref = C1; + }, + /* Case 14: Overlap with objectref's super with new + * interface double diamond. + * + * I3[*](res) = expected + * C3[](*) = mref, I2[I3]() + * C2[C3,I2](), I1[I2]() + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final int C3 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int I3 = builder.expected; + final int I2 = builder.addInterface(emptyClass(pck)); + final int I1 = builder.addInterface(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I2); + builder.objectref = C1; + }, + /* Case 15: Overlapping with new interface with private def. + * + * C2[*](*) = mref, I1[](priv) + * C1[C2,I2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, meth); + final int C2 = builder.methodref; + final int I1 = builder.addInterface(withPrivDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.objectref = C1; + }, + /* Case 16: Overlapping with new interface with static def. + * + * C2[*](*) = mref, I1[](stat) + * C1[C2,I2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = + new ClassData(pck, meth); + final int C2 = builder.methodref; + final int I1 = builder.addInterface(withStatDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.objectref = C1; + }); + + public static final Template MethodrefSelectionResolvedIsIface = + new Template("MethodrefSelectionResolvedIsIface", + MethodrefSelectionResolvedIsIfaceNoOverride, + /* Case 17: Objectref overrides. + * + * C2[](*) = mref + * C1[C2](res) = oref = expected + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int C2 = builder.methodref; + final int C1 = builder.addClass(withDef); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C1; + }, + /* Case 18: Overlapping with new interface overriding. + * + * I2[*](def) = old expected + * C2[*](*) = mref, I1[I2](res) = expected + * C1[C2,I2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int C2 = builder.methodref; + final int I2 = builder.expected; + final int I1 = builder.addInterface(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(I1, I2); + builder.objectref = C1; + builder.expected = I1; + }, + /* Case 19: Objectref's super overrides. + * + * C3[](*) = mref + * C2[C3](res) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 20: Overlap with objectref's super with + * new interface overriding. + * + * I2[*](def) = old expected + * C3[](*) = mref, I1[I2](res) = expected + * C2[C3,I1]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int C3 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int I2 = builder.expected; + final int I1 = builder.addInterface(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(I1, I2); + builder.objectref = C1; + builder.expected = I1; + }, + /* Case 21: Overlap with objectref's super with new + * interface double diamond, overriding. + * + * I3[*](def) = old expected + * C3[](*) = mref, I2[I3](def) + * C2[C3,I2](), I1[I2](res) = expected + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int C3 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int I3 = builder.expected; + final int I2 = builder.addInterface(withDef); + final int I1 = builder.addInterface(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I2, I3); + builder.objectref = C1; + builder.expected = I1; + }, + /* Case 22: Objectref's super overrides, skip private. + * + * C3[](*) = mref + * C2[C3](res) = expected + * C1[C2](priv) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, meth); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(withPrivDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 23: Objectref's super overrides, skip static. + * + * C3[](*) = mref + * C2[C3](res) = expected + * C1[C2](stat) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = + new ClassData(pck, meth); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(withStatDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 24: Overlap with objectref's super with new + * interface double diamond, overriding, skip private. + * + * I3[*](def) = old expected + * C3[](*) = mref, I2[I3](res) = expected + * C2[C3,I2](), I1[I2](priv) + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int I3 = builder.expected; + final int I2 = builder.addInterface(withDef); + final int I1 = builder.addInterface(withPrivDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I2, I3); + builder.objectref = C1; + builder.expected = I2; + }, + /* Case 25: Overlap with objectref's super with new + * interface double diamond, overriding, skip static. + * + * I3[*](def) = old expected + * C3[](*) = mref, I2[I3](res) = expected + * C2[C3,I2](), I1[I2](stat) + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = + new ClassData(pck, meth); + final int C3 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int I3 = builder.expected; + final int I2 = builder.addInterface(withDef); + final int I1 = builder.addInterface(withStatDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I2, I3); + builder.objectref = C1; + builder.expected = I2; + }, + /* Case 26: Skip interface method after class overrides. + * + * C3[](*) = mref + * C2[C3](res) = expected, I[](def) + * C1[C2, I]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + final int I = builder.addInterface(withDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 27: Skip interface method after class overrides. + * + * C3[](*) = mref, I[](def) + * C2[C3,I](res) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + final int I = builder.addInterface(withDef); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 28: Overlap with objectref's super with new + * interface double diamond, overriding. + * + * I3[*](def) = old expected + * C3[](*) = mref, I2[I3](def) + * C2[C3,I2](res) = expected, I1[I2](def) = expected + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int C3 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int I3 = builder.expected; + final int I2 = builder.addInterface(withDef); + final int I1 = builder.addInterface(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(I2, I3); + builder.objectref = C1; + builder.expected = C2; + }); + + public static final Template IfaceMethodrefSelectionNoOverride = + new Template("IfaceMethodrefSelectionNoOverride", + /* Case 1: Inherit from super. + * + * I[](*) = mref + * C[I]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final int I = builder.methodref; + final int C = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C, I); + builder.objectref = C; + }, + /* Case 2: Objectref has static def + * + * I[](*) = mref + * C[I](stat) = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = + new ClassData(pck, meth); + final int I = builder.methodref; + final int C = builder.addClass(withStatDef); + builder.hier.addInherit(C, I); + builder.objectref = C; + }, + /* Case 3: Diamond, methodref at top. + * + * I3[](*) = mref + * I1[I3](), I2[I3]() + * C[I1,I2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I3 = builder.methodref; + final int I2 = builder.addInterface(emptyClass(pck)); + final int I1 = builder.addInterface(emptyClass(pck)); + final int C = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.objectref = C; + }, + /* Case 4: Diamond, methodref at top, skip private def + * + * I3[](*) = mref + * I1[I3](), I2[I3](priv) + * C[I1,I2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, meth); + final int I3 = builder.methodref; + final int I2 = builder.addInterface(withPrivDef); + final int I1 = builder.addInterface(emptyClass(pck)); + final int C = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.objectref = C; + }, + /* Case 5: Diamond, methodref at top, skip static def + * + * I3[](*) = mref + * I1[I3](), I2[I3](stat) + * C[I1,I2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = + new ClassData(pck, meth); + final int I3 = builder.methodref; + final int I2 = builder.addInterface(withStatDef); + final int I1 = builder.addInterface(emptyClass(pck)); + final int C = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.objectref = C; + }, + /* Case 6: Diamond, overlap with resolution. + * + * I3[](res) = expected + * I1[I3](), I2[](*) = mref + * C[I1,I2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I3 = builder.expected; + final int I2 = builder.methodref; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.hier.addInherit(I1, I3); + builder.objectref = C; + }, + /* Case 7: Diamond, with superclass, expected at top. + * + * I2[](*) = mref + * C2[I2](), I1[I2]() + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I2 = builder.methodref; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + }, + /* Case 8: Diamond, with superclass, expected at top, + * class has static def. + * + * I2[](*) = mref + * C2[I2](stat), I1[I2]() + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = + new ClassData(pck, meth); + final int I2 = builder.methodref; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addClass(withStatDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + }, + /* Case 9: Diamond, with superclass, expected at top, + * interface has private def + * + * I2[](*) = mref + * C2[I2](), I1[I2](priv) + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, meth); + final int I2 = builder.methodref; + final int I1 = builder.addInterface(withPrivDef); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + }, + /* Case 10: Diamond, with superclass, expected at top, + * interface has static def + * + * I2[](*) = mref + * C2[I2](), I1[I2](stat) + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withPrivDef = + new ClassData(pck, meth); + final int I2 = builder.methodref; + final int I1 = builder.addInterface(withPrivDef); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + }, + /* Case 11: Y, with superclass, expected + * at top. + * + * C2[](), I1[](*) = mref + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I1 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 12: Y, with superclass, expected + * at top, class has static def + * + * C2[](stat), I1[](*) = mref + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = + new ClassData(pck, meth); + final int I1 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 13: Diamond, with superclass, overlapping, expected + * at top. + * + * I2[](res) = expected + * C2[I2](), I1[](*) = mref + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I2 = builder.expected; + final int I1 = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + }, + /* Case 14: Diamond, with superclass, overlapping, expected + * at top, class has static def + * + * I2[](def) = expected + * C2[I2](stat), I1[](*) = mref + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = + new ClassData(pck, meth); + final int I2 = builder.expected; + final int I1 = builder.methodref; + final int C2 = builder.addClass(withStatDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + }, + /* Case 15: Inherit through superclass. + * + * I[](*) = mref + * C2[I]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I = builder.methodref; + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I); + builder.objectref = C1; + }, + /* Case 16: Superclass has static def. + * + * I[](*) = mref + * C2[I](stat) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = + new ClassData(pck, meth); + final int I = builder.methodref; + final int C2 = builder.addClass(withStatDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I); + builder.objectref = C1; + }, + /* Case 17: Diamond, inherit through superclass, + * methodref at top. + * + * I3[](*) = mref + * I1[I3](), I2[I3]() + * C2[I1,I2]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I3 = builder.methodref; + final int I2 = builder.addInterface(emptyClass(pck)); + final int I1 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 18: Diamond, with superclass, inherit through + * superclass, methodref at top. + * + * I2[](*) = mref + * C3[I2](), I1[I2]() + * C2[I1,C3]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I2 = builder.methodref; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C3 = builder.addClass(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C3, I2); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 19: Diamond, inherit through superclass, + * expected at top, skip private. + * + * I3[](*) = mref + * I1[I3](), I2[I3](priv) + * C2[I1,I2]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, meth); + final int I3 = builder.methodref; + final int I2 = builder.addInterface(withPrivDef); + final int I1 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 20: Diamond, inherit through superclass, + * expected at top, skip static. + * + * I3[](*) = mref + * I1[I3](), I2[I3](stat) + * C2[I1,I2]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = + new ClassData(pck, meth); + final int I3 = builder.methodref; + final int I2 = builder.addInterface(withStatDef); + final int I1 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 21: Diamond, inherit through superclass, + * overlapping, expected at top. + * + * I3[](res) = expected + * I1[I3](), I2[*](*) = mref + * C2[I1,I2]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I3 = builder.expected; + final int I2 = builder.methodref; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 22: Y, with superclass, inherit through + * superclass, expected at top. + * + * C3[](), I1[*](*) = mref + * C2[I1,C3]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I1 = builder.methodref; + final int C3 = builder.addClass(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 23: Diamond, with superclass, inherit through + * superclass, overlapping, expected at top. + * + * I2[](res) = expected + * C3[I2](), I1[*](*) = mref + * C2[I1,C3]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I2 = builder.expected; + final int I1 = builder.methodref; + final int C3 = builder.addClass(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C3, I2); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }, + /* Case 24: Double diamond, with superclass, inherit through + * superclass, overlapping expected at top. + * + * I3[](res) = expected + * C3[I3](), I2[*](*) = mref + * C2[I2,C3](), I1[I2]() + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final int I3 = builder.expected; + final int I2 = builder.methodref; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C3 = builder.addClass(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C3, I3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C1, I1); + builder.objectref = C1; + }, + /* Case 25: Double diamond, with superclass, inherit through + * superclass, skip private. + * + * I3[](def) = old expected + * C3[I3](), I2[*](*) = mref + * C2[I2,C3](), I1[I2](priv) + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, meth); + final int I3 = builder.expected; + final int I2 = builder.methodref; + final int I1 = builder.addInterface(withPrivDef); + final int C3 = builder.addClass(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C3, I3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C1, I1); + builder.objectref = C1; + }, + /* Case 26: Double diamond, with superclass, inherit through + * superclass, skip static. + * + * I3[](def) = old expected + * C3[I3](), I2[*](*) = mref + * C2[I2,C3](), I1[I2](stat) + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = + new ClassData(pck, meth); + final int I3 = builder.expected; + final int I2 = builder.methodref; + final int I1 = builder.addInterface(withStatDef); + final int C3 = builder.addClass(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C3, I3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C1, I1); + builder.objectref = C1; + }); + + public static final Template IfaceMethodrefSelection = + new Template("IfaceMethodrefSelection", + IfaceMethodrefSelectionNoOverride, + /* Case 27: Objectref overrides. + * + * I[](*) = mref + * C[I](res) = oref = expected + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int I = builder.methodref; + final int C = builder.addClass(withDef); + builder.hier.addInherit(C, I); + builder.objectref = C; + builder.expected = C; + }, + /* Case 28: Diamond, methodref at top, overriding. + * + * I3[](*) = mref + * I1[I3](), I2[I3](res) = expected + * C[I1,I2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int I3 = builder.methodref; + final int I2 = builder.addInterface(withDef); + final int I1 = builder.addInterface(emptyClass(pck)); + final int C = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.objectref = C; + builder.expected = I2; + }, + /* Case 29: Diamond, with superclass, expected at top, + * class overriding. + * + * I2[](*) = mref + * C2[I2](res) = expected, I1[I2]() + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int I2 = builder.methodref; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 30: Diamond, with superclass, expected at top, + * interface overriding + * + * I2[](*) = mref + * C2[I2](), I1[I2](res) = expected + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int I2 = builder.methodref; + final int I1 = builder.addInterface(withDef); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + builder.expected = I1; + }, + /* Case 31: Y, with superclass, overlaping, expected + * at top, class overrides + * + * C2[](res) = expected, I1[](*) = mref + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int I1 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 32: Diamond, with superclass, overlaping, expected + * at top, class overrides + * + * I2[](def) = old expected + * C2[I2](res) = expected, I1[](*) = mref + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int I2 = builder.expected; + final int I1 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 33: Superclass overrides. + * + * I[](*) = mref + * C2[I](res) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int I = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I); + builder.expected = C2; + builder.objectref = C1; + }, + /* Case 34: Diamond, inherit through superclass, + * expected at top, override. + * + * I3[](*) = mref + * I1[I3](), I2[I3](res) = expected + * C2[I1,I2]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int I3 = builder.methodref; + final int I2 = builder.addInterface(withDef); + final int I1 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(I1, I3); + builder.hier.addInherit(I2, I3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = I2; + }, + /* Case 35: Y, with superclass, inherit through + * superclass, overlapping, expected at top. + * + * C3[](res) = expected, I1[*](*) = mref + * C2[I1,C3]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int I1 = builder.methodref; + final int C3 = builder.addClass(withDef); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C3; + }, + /* Case 36: Diamond, with superclass, inherit through + * superclass, overlapping, expected at top. + * + * I2[](*) = oldexpected + * C3[I2](res) = expected, I1[*](*) = mref + * C2[I1,C3]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int I2 = builder.expected; + final int I1 = builder.methodref; + final int C3 = builder.addClass(withDef); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I1); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C3, I2); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C3; + }, + /* Case 37: Double diamond, with superclass, inherit through + * superclass, overriding. + * + * I3[](def) = old expected + * C3[I3](), I2[*](*) = mref + * C2[I2,C3](), I1[I2](res) = expected + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final int I3 = builder.expected; + final int I2 = builder.methodref; + final int I1 = builder.addInterface(withDef); + final int C3 = builder.addClass(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C3, I3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C1, I1); + builder.objectref = C1; + builder.expected = I1; + }, + /* Case 38: Double diamond, with superclass, inherit through + * superclass, skip private. + * + * I3[](def) = old expected + * C3[I3](), I2[*](*) = mref + * C2[I2,C3](), I1[I2](priv) + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withPrivDef = + new ClassData(pck, meth); + final int I3 = builder.expected; + final int I2 = builder.methodref; + final int I1 = builder.addInterface(withPrivDef); + final int C3 = builder.addClass(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C3, I3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C1, I1); + builder.objectref = C1; + }, + /* Case 39: Double diamond, with superclass, inherit through + * superclass, skip static. + * + * I3[](def) = old expected + * C3[I3](), I2[*](*) = mref + * C2[I2,C3](), I1[I2](stat) + * C1[C2,I1]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = + new ClassData(pck, meth); + final int I3 = builder.expected; + final int I2 = builder.methodref; + final int I1 = builder.addInterface(withStatDef); + final int C3 = builder.addClass(emptyClass(pck)); + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, I2); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C3, I3); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C1, I1); + builder.objectref = C1; + }, + /* Case 40: Superclass overrides. + * + * I[](*) = mref + * C3[I](res) = expected + * C2[C3](stat) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData withDef = + new ClassData(pck, oldexpected.methoddata); + final MethodData meth = + new MethodData(MethodData.Access.PUBLIC, + MethodData.Context.STATIC); + final ClassData withStatDef = + new ClassData(pck, meth); + final int I = builder.methodref; + final int C3 = builder.addClass(withDef); + final int C2 = builder.addClass(withStatDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C2, I); + builder.expected = C3; + builder.objectref = C1; + }); + + public static final Template IfaceMethodrefSelectionOverrideNonPublic = + new Template("IfaceMethodrefSelection", + /* Case 1: Objectref overrides. + * + * I[](*) = mref + * C[I](priv) = oref = expected + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int I = builder.methodref; + final int C = builder.addClass(withDef); + builder.hier.addInherit(C, I); + builder.objectref = C; + builder.expected = C; + }, + /* Case 2: Objectref overrides. + * + * I[](*) = mref + * C[I](prot) = oref = expected + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PROTECTED, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int I = builder.methodref; + final int C = builder.addClass(withDef); + builder.hier.addInherit(C, I); + builder.objectref = C; + builder.expected = C; + }, + /* Case 3: Objectref overrides package private. + * + * I[](*) = mref + * C[I](pack) = oref = expected + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.methodref).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PACKAGE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int I = builder.methodref; + final int C = builder.addClass(withDef); + builder.hier.addInherit(C, I); + builder.objectref = C; + builder.expected = C; + }, + /* Case 4: Diamond, with superclass, expected at top, + * class overriding with private. + * + * I2[](*) = mref + * C2[I2](priv) = expected, I1[I2]() + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int I2 = builder.methodref; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 5: Diamond, with superclass, expected at top, + * class overriding with package private. + * + * I2[](*) = mref + * C2[I2](pack) = expected, I1[I2]() + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PACKAGE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int I2 = builder.methodref; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 6: Diamond, with superclass, expected at top, + * class overriding with protected. + * + * I2[](*) = mref + * C2[I2](prot) = expected, I1[I2]() + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PROTECTED, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int I2 = builder.methodref; + final int I1 = builder.addInterface(emptyClass(pck)); + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(I1, I2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 7: Y, with superclass, overlaping, expected + * at top, class overrides + * + * C2[](priv) = expected, I1[](*) = mref + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int I1 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 8: Y, with superclass, overlaping, expected + * at top, class overrides + * + * C2[](prot) = expected, I1[](*) = mref + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PROTECTED, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int I1 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 9: Y, with superclass, overlaping, expected + * at top, class overrides + * + * C2[](pack) = expected, I1[](*) = mref + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PACKAGE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int I1 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 10: Diamond, with superclass, overlaping, expected + * at top, class overrides + * + * I2[](def) = old expected + * C2[I2](priv) = expected, I1[](*) = mref + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int I2 = builder.expected; + final int I1 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 11: Diamond, with superclass, overlaping, expected + * at top, class overrides + * + * I2[](def) = old expected + * C2[I2](pack) = expected, I1[](*) = mref + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PACKAGE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int I2 = builder.expected; + final int I1 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 12: Diamond, with superclass, overlaping, expected + * at top, class overrides + * + * I2[](def) = old expected + * C2[I2](prot) = expected, I1[](*) = mref + * C1[I1,C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PROTECTED, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int I2 = builder.expected; + final int I1 = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I1); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I2); + builder.objectref = C1; + builder.expected = C2; + }, + /* Case 13: Superclass overrides. + * + * I[](*) = mref + * C2[I](priv) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PRIVATE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int I = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I); + builder.expected = C2; + builder.objectref = C1; + }, + /* Case 14: Superclass overrides. + * + * I[](*) = mref + * C2[I](prot) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PROTECTED, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int I = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I); + builder.expected = C2; + builder.objectref = C1; + }, + /* Case 15: Superclass overrides. + * + * I[](*) = mref + * C2[I](pack) = expected + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.expected).packageId; + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final MethodData meth = + new MethodData(MethodData.Access.PACKAGE, + MethodData.Context.INSTANCE); + final ClassData withDef = + new ClassData(pck, meth); + final int I = builder.methodref; + final int C2 = builder.addClass(withDef); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, I); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C2, I); + builder.expected = C2; + builder.objectref = C1; + }); + + /*********************** + * Ambiguous selection * + ***********************/ + + public static final Template MethodrefAmbiguousResolvedIsIface = + new Template("MethodrefAmbiguousResolvedIsIface", + /* Inherit from interface. + * + * C2[](*) = mref, I[](any) + * C1[C2,I]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData.Package pck = oldexpected.packageId; + final MethodData.Context ctx = oldexpected.methoddata.context; + final MethodData mdata = + new MethodData(MethodData.Access.PUBLIC, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final int C2 = builder.methodref; + final int C1 = builder.addClass(emptyClass(pck)); + final int I = builder.addInterface(withDef); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I); + builder.objectref = C1; + }); + + public static final Template IfaceMethodrefAmbiguousResolvedIsIface = + new Template("IfaceMethodrefAmbiguousResolvedIsIface", + /* Inherit from interface. + * + * I1[](*) = mref, I2[](any) + * C1[I1,I2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData.Package pck = oldexpected.packageId; + final MethodData.Context ctx = oldexpected.methoddata.context; + final MethodData mdata = + new MethodData(MethodData.Access.PUBLIC, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final int I1 = builder.methodref; + final int C = builder.addClass(emptyClass(pck)); + final int I2 = builder.addInterface(withDef); + builder.hier.addInherit(C, I1); + builder.hier.addInherit(C, I2); + builder.objectref = C; + }); + + public static final Template InvokespecialAmbiguousResolvedIsIface = + new Template("InvokespecialAmbiguousResolvedIsIface", + /* Inherit from interface. + * + * C2[](*) = csite, I[](any) + * C1[C2,I]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData oldexpected = + builder.classdata.get(builder.expected); + final ClassData.Package pck = oldexpected.packageId; + final MethodData.Context ctx = oldexpected.methoddata.context; + final MethodData mdata = + new MethodData(MethodData.Access.PUBLIC, ctx); + final ClassData withDef = new ClassData(pck, mdata); + final int C2 = builder.callsite; + final int C1 = builder.addClass(emptyClass(pck)); + final int I = builder.addInterface(withDef); + builder.hier.addInherit(C1, C2); + builder.hier.addInherit(C1, I); + builder.objectref = C1; + }); + + /****************************** + * invokespecial Templates * + ******************************/ + + // Create this by taking MethodrefSelection and replacing + // methodref with callsite. + public static final Template ObjectrefAssignableToCallsite = + new Template("ObjectrefAssignableToCallsite", + /* Case 1: Objectref equals callsite + * + * C[](*) = csite = oref + */ + (builder) -> { + builder.objectref = builder.callsite; + }, + /* Case 2: Inherit from super. + * + * C2[](*) = csite + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.callsite).packageId; + final int C2 = builder.callsite; + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }); + + public static final Template ObjectrefExactSubclassOfCallsite = + new Template("ObjectrefSubclassOfCallsite", + /* Inherit from super. + * + * C2[](*) = csite + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.callsite).packageId; + final int C2 = builder.callsite; + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }); + + public static final Template ObjectrefEqualsOrExactSubclassOfCallsite = + new Template("ObjectrefEqualsOrExactSubclassOfCallsite", + (final SelectionResolutionTestCase.Builder builder) -> { + builder.objectref = builder.callsite; + }, + /* Inherit from super. + * + * C2[](*) = csite + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.callsite).packageId; + final int C2 = builder.callsite; + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }); + + public static final Template ObjectrefEqualsCallsite = + new Template("TrivialObjectref", + Collections.singleton((builder) -> { + builder.objectref = builder.callsite; + })); + + public static final Template ObjectrefSubclassOfSubclassOfCallsite = + new Template("ObjectrefSubclassOfCallsite", + /* Inherit from super. + * + * C3[](*) = csite + * C2[C3]() + * C1[C2]() = oref + */ + (final SelectionResolutionTestCase.Builder builder) -> { + final ClassData.Package pck = + builder.classdata.get(builder.callsite).packageId; + final int C3 = builder.callsite; + final int C2 = builder.addClass(emptyClass(pck)); + final int C1 = builder.addClass(emptyClass(pck)); + builder.hier.addInherit(C2, C3); + builder.hier.addInherit(C1, C2); + builder.objectref = C1; + }); + + private static class Placeholder extends ClassData { + private final String placeholder; + + + private Placeholder(final String placeholder, + final MethodData methoddata) { + super(ClassData.Package.PLACEHOLDER, methoddata); + this.placeholder = placeholder; + } + + private Placeholder(final String placeholder) { + this(placeholder, null); + } + + public String toString() { + return " = \n\n"; + } + + public static final Placeholder objectref = new Placeholder("objectref"); + public static final Placeholder methodref = new Placeholder("methodref"); + public static final Placeholder callsite = new Placeholder("callsite"); + public static final Placeholder expected = + new Placeholder("expected", + new MethodData(MethodData.Access.PLACEHOLDER, + MethodData.Context.PLACEHOLDER)); + } + + public static void main(String... args) { + + System.err.println("*** Resolution Templates ***\n"); + final SelectionResolutionTestCase.Builder withExpectedIface = + new SelectionResolutionTestCase.Builder(); + withExpectedIface.expected = + withExpectedIface.addInterface(Placeholder.expected); + final SelectionResolutionTestCase.Builder withExpectedClass = + new SelectionResolutionTestCase.Builder(); + withExpectedClass.expected = + withExpectedClass.addClass(Placeholder.expected); + + MethodrefNotEqualsExpectedClass.printCases(withExpectedClass); + MethodrefNotEqualsExpectedIface.printCases(withExpectedIface); + IfaceMethodrefNotEqualsExpected.printCases(withExpectedIface); + MethodrefAmbiguous.printCases(withExpectedIface); + IfaceMethodrefAmbiguous.printCases(withExpectedIface); + ReabstractExpectedIface.printCases(withExpectedIface); + ReabstractExpectedClass.printCases(withExpectedClass); + + final SelectionResolutionTestCase.Builder methodrefExpectedIface = + withExpectedIface.copy(); + methodrefExpectedIface.methodref = + methodrefExpectedIface.addClass(Placeholder.methodref); + final SelectionResolutionTestCase.Builder methodrefExpectedClass = + withExpectedClass.copy(); + methodrefExpectedClass.methodref = + methodrefExpectedClass.addClass(Placeholder.methodref); + final SelectionResolutionTestCase.Builder ifaceMethodref = + withExpectedIface.copy(); + ifaceMethodref.methodref = + ifaceMethodref.addInterface(Placeholder.methodref); + + IgnoredAbstract.printCases(methodrefExpectedIface); + MethodrefSelectionResolvedIsClass.printCases(methodrefExpectedClass); + MethodrefSelectionResolvedIsIface.printCases(methodrefExpectedIface); + IfaceMethodrefSelection.printCases(ifaceMethodref); + IfaceMethodrefSelectionOverrideNonPublic.printCases(ifaceMethodref); + + } + +} --- /dev/null 2015-04-06 08:40:03.942185037 -0400 +++ new/test/runtime/SelectionResolution/TestBuilder.java 2015-04-17 16:08:00.320471842 -0400 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013, 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. + * + */ + +import static jdk.internal.org.objectweb.asm.Opcodes.*; + +class TestBuilder extends Builder { + private final ClassConstruct testClass; + private final Method mainMethod; + + public TestBuilder(int classId, SelectionResolutionTestCase testcase) { + super(testcase); + + // Make a public class Test that contains all our test methods + testClass = new Clazz("Test", null, -1, ACC_PUBLIC); + + // Add a main method + mainMethod = testClass.addMethod("main", "([Ljava/lang/String;)V", ACC_PUBLIC + ACC_STATIC); + + } + + public ClassConstruct getMainTestClass() { + mainMethod.done(); + return testClass; + } + + public void addTest(ClassConstruct clazz, ClassBuilder.ExecutionMode execMode) { + Method m = clazz.addMethod("test", "()Ljava/lang/Integer;", ACC_PUBLIC + ACC_STATIC, execMode); + m.defaultInvoke(getInvokeInstruction(testcase.invoke), + getName(testcase.methodref), + getName(testcase.objectref)); + + mainMethod.makeStaticCall(clazz.getName(), "test", "()Ljava/lang/Integer;").done(); + } + + private static int getInvokeInstruction(SelectionResolutionTestCase.InvokeInstruction instr) { + switch (instr) { + case INVOKESTATIC: + return INVOKESTATIC; + case INVOKESPECIAL: + return INVOKESPECIAL; + case INVOKEINTERFACE: + return INVOKEINTERFACE; + case INVOKEVIRTUAL: + return INVOKEVIRTUAL; + default: + throw new AssertionError(instr.name()); + } + } +}