1 /* 2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package org.openjdk.tests.shapegen; 27 28 import java.util.ArrayList; 29 import java.util.List; 30 import java.util.HashMap; 31 import java.util.HashSet; 32 import java.util.Map; 33 import java.util.Set; 34 35 import static org.openjdk.tests.shapegen.ClassCase.Kind.*; 36 37 /** 38 * 39 * @author Robert Field 40 */ 41 public class Hierarchy { 42 43 public final ClassCase root; 44 public final Set<ClassCase> all; 45 Hierarchy(ClassCase root)46 public Hierarchy(ClassCase root) { 47 this.root = root; 48 root.init(new HashMap<String,Integer>()); 49 Set<ClassCase> allClasses = new HashSet<>(); 50 root.collectClasses(allClasses); 51 this.all = allClasses; 52 } 53 anyDefaults()54 public boolean anyDefaults() { 55 for (ClassCase cc : all) { 56 if (cc.kind == IDEFAULT) { 57 return true; 58 } 59 } 60 return false; 61 } 62 get_OK()63 public boolean get_OK() { 64 return root.get_OK(); 65 } 66 testName()67 public String testName() { 68 return root + "Test"; 69 } 70 genInterfaceList(StringBuilder buf, String prefix, List<ClassCase> interfaces)71 private static void genInterfaceList(StringBuilder buf, String prefix, List<ClassCase> interfaces) { 72 if (!interfaces.isEmpty()) { 73 buf.append(" "); 74 buf.append(prefix); 75 buf.append(" "); 76 buf.append(interfaces.get(0)); 77 for (int i = 1; i < interfaces.size(); ++i) { 78 buf.append(", " + interfaces.get(i)); 79 } 80 } 81 } 82 genClassDef(StringBuilder buf, ClassCase cc, String implClass, List<ClassCase> defaultRef)83 public static void genClassDef(StringBuilder buf, ClassCase cc, String implClass, List<ClassCase> defaultRef) { 84 if (cc.isInterface()) { 85 buf.append("interface "); 86 buf.append(cc.getName() + " "); 87 genInterfaceList(buf, "extends", cc.getInterfaces()); 88 buf.append(" {\n"); 89 90 switch (cc.kind) { 91 case IDEFAULT: 92 buf.append(" default String m() { return \"\"; }\n"); 93 defaultRef.add(cc); 94 break; 95 case IPRESENT: 96 buf.append(" String m();\n"); 97 break; 98 case IVAC: 99 break; 100 default: 101 throw new AssertionError("Unexpected kind"); 102 } 103 buf.append("}\n\n"); 104 } else { 105 buf.append((cc.isAbstract()? "abstract " : "")); 106 buf.append(" class " + cc.getName()); 107 if (cc.getSuperclass() != null) { 108 buf.append(" extends " + cc.getSuperclass()); 109 } 110 111 genInterfaceList(buf, "implements", cc.getInterfaces()); 112 buf.append(" {\n"); 113 114 switch (cc.kind) { 115 case CCONCRETE: 116 buf.append(" public String m() { return \"\"; }\n"); 117 break; 118 case CABSTRACT: 119 buf.append(" public abstract String m();\n"); 120 break; 121 case CNONE: 122 break; 123 default: 124 throw new AssertionError("Unexpected kind"); 125 } 126 buf.append("}\n\n"); 127 } 128 } 129 130 @Override equals(Object obj)131 public boolean equals(Object obj) { 132 return obj instanceof Hierarchy && root.getID().equals(((Hierarchy)obj).root.getID()); 133 } 134 135 @Override hashCode()136 public int hashCode() { 137 return root.getID().hashCode(); 138 } 139 140 @Override toString()141 public String toString() { 142 return root.getName(); 143 } 144 145 private static String classNames[] = { 146 "C", "D", "E", "F", "G", "H", "S", "T", "U", "V" 147 }; 148 149 private static String interfaceNames[] = { 150 "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R" 151 }; 152 153 private static int CLASS_INDEX = 0; 154 private static int INTERFACE_INDEX = 1; 155 private static int NUM_INDICIES = 2; 156 getDescription()157 public List<String> getDescription() { 158 Map<ClassCase,String> nameMap = new HashMap<>(); 159 assignNames(root, new int[NUM_INDICIES], nameMap); 160 161 ArrayList<String> res = new ArrayList<>(); 162 if (root.getSupertypes().size() == 0) { 163 res.add(nameMap.get(root) + root.kind.getPrefix() + "()"); 164 } else { 165 genCaseDescription(root, res, new HashSet<ClassCase>(), nameMap); 166 } 167 return res; 168 } 169 assignNames( ClassCase cc, int indices[], Map<ClassCase,String> names)170 private static void assignNames( 171 ClassCase cc, int indices[], Map<ClassCase,String> names) { 172 String name = names.get(cc); 173 if (name == null) { 174 if (cc.isInterface()) { 175 names.put(cc, interfaceNames[indices[INTERFACE_INDEX]++]); 176 } else { 177 names.put(cc, classNames[indices[CLASS_INDEX]++]); 178 } 179 for (int i = 0; i < cc.getSupertypes().size(); ++i) { 180 assignNames(cc.getSupertypes().get(i), indices, names); 181 } 182 } 183 } 184 genCaseDescription( ClassCase cc, List<String> res, Set<ClassCase> alreadyDone, Map<ClassCase,String> nameMap)185 private static void genCaseDescription( 186 ClassCase cc, List<String> res, Set<ClassCase> alreadyDone, 187 Map<ClassCase,String> nameMap) { 188 if (!alreadyDone.contains(cc)) { 189 if (cc.getSupertypes().size() > 0) { 190 StringBuilder sb = new StringBuilder(); 191 sb.append(nameMap.get(cc)); 192 sb.append(cc.kind.getPrefix()); 193 sb.append("("); 194 for (int i = 0; i < cc.getSupertypes().size(); ++i) { 195 ClassCase supertype = cc.getSupertypes().get(i); 196 if (i != 0) { 197 sb.append(","); 198 } 199 genCaseDescription(supertype, res, alreadyDone, nameMap); 200 sb.append(nameMap.get(supertype)); 201 sb.append(supertype.kind.getPrefix()); 202 } 203 sb.append(")"); 204 res.add(sb.toString()); 205 } 206 } 207 alreadyDone.add(cc); 208 } 209 } 210