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 org.openjdk.tests.shapegen.ClassCase.Kind; 29 30 import java.util.ArrayList; 31 import java.util.List; 32 import java.util.Set; 33 34 import static org.openjdk.tests.shapegen.ClassCase.Kind.*; 35 36 /** 37 * Type Template Node 38 * 39 * @author Robert Field 40 */ 41 public class TTNode { 42 43 final List<TTNode> supertypes; 44 final boolean canBeClass; 45 46 private int currentKindIndex; 47 private Kind[] kinds; 48 49 public TTNode(List<TTNode> subtypes, boolean canBeClass) { 50 this.supertypes = subtypes; 51 this.canBeClass = canBeClass; 52 } 53 54 public void start(boolean includeClasses) { 55 kinds = 56 supertypes.isEmpty()? 57 (new Kind[]{IDEFAULT, IPRESENT}) 58 : ((includeClasses && canBeClass)? 59 new Kind[]{CNONE, IVAC, IDEFAULT, IPRESENT} 60 : new Kind[]{IVAC, IDEFAULT, IPRESENT}); 61 currentKindIndex = 0; 62 63 for (TTNode sub : supertypes) { 64 sub.start(includeClasses); 65 } 66 } 67 68 public boolean next() { 69 ++currentKindIndex; 70 if (currentKindIndex >= kinds.length) { 71 currentKindIndex = 0; 72 return false; 73 } else { 74 return true; 75 } 76 } 77 78 public void collectAllSubtypes(Set<TTNode> subs) { 79 subs.add(this); 80 for (TTNode n : supertypes) { 81 n.collectAllSubtypes(subs); 82 } 83 } 84 85 private Kind getKind() { 86 return kinds[currentKindIndex]; 87 } 88 89 boolean isInterface() { 90 return getKind().isInterface; 91 } 92 93 boolean isClass() { 94 return !isInterface(); 95 } 96 97 boolean hasDefault() { 98 return getKind() == IDEFAULT; 99 } 100 101 public boolean isValid() { 102 for (TTNode n : supertypes) { 103 if (!n.isValid() || (isInterface() && n.isClass())) { 104 return false; 105 } 106 } 107 return true; 108 } 109 110 public ClassCase genCase() { 111 ClassCase subclass; 112 List<TTNode> ttintfs; 113 if (isClass() && !supertypes.isEmpty() && supertypes.get(0).isClass()) { 114 subclass = supertypes.get(0).genCase(); 115 ttintfs = supertypes.subList(1, supertypes.size()); 116 } else { 117 subclass = null; 118 ttintfs = supertypes; 119 } 120 List<ClassCase> intfs = new ArrayList<>(); 121 for (TTNode node : ttintfs) { 122 intfs.add(node.genCase()); 123 } 124 return new ClassCase(getKind(), subclass, intfs); 125 } 126 }