/* * Copyright (c) 2009, 2019, 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. * */ package invokevirtual; import static jdk.internal.org.objectweb.asm.Opcodes.ACC_ABSTRACT; import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC; import shared.AbstractGenerator; import shared.AccessType; import java.util.HashMap; import java.util.Map; public class Generator extends AbstractGenerator { public Generator(String[] args) { super(args); } public static void main (String[] args) throws Exception { new Generator(args).run(); } protected Checker getChecker(Class paramClass, Class targetClass) { return new Checker(paramClass, targetClass); } private void run() throws Exception { // Specify package names String pkg1 = "a."; String pkg2 = "b."; String pkg3 = "c."; String[] packages = new String[] { "", pkg1, pkg2, pkg3 }; boolean isPassed = true; // Hierarchy // The following triples will be used during further // hierarchy construction and will specify packages for A, B and C String[][] packageSets = new String[][] { { "", "", "" } , { "", pkg1, pkg1 } , { "", pkg1, pkg2 } , { pkg1, pkg1, pkg1 } , { pkg1, pkg1, pkg2 } , { pkg1, pkg2, pkg1 } , { pkg1, pkg2, pkg2 } }; String [] header = new String[] { String.format("%30s %45s %20s", "Method access modifiers", "Call site location", "Status") , String.format("%4s %-12s %-12s %-12s %7s %7s %7s %7s %7s %7s" , " # " , "A.m()" , "B.m()" , "C.m()" , " A " , "pkgA " , " B " , " pkgB" , " C " , "pkgC " ) , "-------------------------------------------------------------------------------------------------" }; for (String str : header) { System.out.println(str); } for (String[] pkgSet : packageSets) { String packageA = pkgSet[0]; String packageB = pkgSet[1]; String packageC = pkgSet[2]; String classNameA = packageA + "A"; String classNameB = packageB + "B"; String classNameC = packageC + "C"; String staticCallerParam = classNameA; // For all possible access modifier combinations for (AccessType accessA : AccessType.values()) { for (AccessType accessB : AccessType.values()) { for (AccessType accessC : AccessType.values()) { if (accessA == AccessType.UNDEF) { continue; } for (int I = 0; I < 4; I++) { boolean isAbstractA = ((I & 1) != 0); boolean isAbstractB = ((I & 2) != 0); Map classes = new HashMap(); // Generate class A classes.put( classNameA , new ClassGenerator( classNameA , "java.lang.Object" , ACC_PUBLIC | (isAbstractA ? ACC_ABSTRACT : 0)) .addTargetMethod( accessA , (isAbstractA ? ACC_ABSTRACT : 0)) .addCaller(staticCallerParam) .getClassFile() ); // Generate class B classes.put( classNameB , new ClassGenerator( classNameB , classNameA , ACC_PUBLIC | (isAbstractB ? ACC_ABSTRACT : 0)) .addTargetMethod( accessB , (isAbstractB ? ACC_ABSTRACT : 0)) .addCaller(staticCallerParam) .getClassFile() ); // Generate class C classes.put( classNameC , new ClassGenerator(classNameC, classNameB) .addTargetMethod(accessC) .addCaller(staticCallerParam) .getClassFile() ); // Generate package callers for (String pkg : packages) { classes.put( pkg+"Caller" , new ClassGenerator(pkg+"Caller") .addCaller(staticCallerParam) .getClassFile() ); } String[] callSites = new String[] { classNameA , packageA+"Caller" , classNameB , packageB+"Caller" , classNameC , packageC+"Caller" }; String caseDescription = String.format("%-12s %-12s %-12s| " , (isAbstractA ? "! " : " ") + classNameA + " " + accessA , (isAbstractB ? "! " : " ") + classNameB + " " + accessB , classNameC + " " + accessC ); boolean result = exec(classes, caseDescription, staticCallerParam, classNameC, callSites); isPassed = isPassed && result; } } } } } // Print footer for (int i = header.length-1; i >= 0; i--) { System.out.println(header[i]); } if (executeTests) { System.out.printf("\nEXECUTION STATUS: %s\n", (isPassed? "PASSED" : "FAILED")); } } }