1 /*
   2  * Copyright (c) 2005, 2015, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package jdk.test.lib.jittester.types;
  25 
  26 import java.util.Collection;
  27 import java.util.HashSet;
  28 import java.util.TreeSet;
  29 import jdk.test.lib.jittester.ProductionParams;
  30 import jdk.test.lib.jittester.Symbol;
  31 import jdk.test.lib.jittester.SymbolTable;
  32 import jdk.test.lib.jittester.Type;
  33 import jdk.test.lib.jittester.TypeList;
  34 
  35 public class TypeKlass extends Type {
  36 
  37     private TypeKlass parent;
  38     private HashSet<String> parentsList;
  39     private HashSet<String> childrenList;
  40     private final HashSet<Symbol> symbolsSet;
  41     public static final int NONE = 0x00;
  42     public static final int FINAL = 0x01;
  43     public static final int INTERFACE = 0x02;
  44     public static final int ABSTRACT = 0x04;
  45     private int flags = NONE;
  46 
  47     public TypeKlass(String name) {
  48         this(name, 0);
  49     }
  50 
  51     public TypeKlass(String name, int flags) {
  52         super(name);
  53         this.flags = flags;
  54         symbolsSet = new HashSet<>();
  55     }
  56 
  57     public boolean addSymbol(Symbol s) {
  58         return symbolsSet.add(s);
  59     }
  60 
  61     public boolean addAllSymbols(Collection<? extends Symbol> symbols) {
  62         return symbolsSet.addAll(symbols);
  63     }
  64 
  65     public boolean containsSymbol(Symbol s) {
  66         return symbolsSet.contains(s);
  67     }
  68 
  69     public boolean removeSymbol(Symbol s) {
  70         return symbolsSet.remove(s);
  71     }
  72 
  73     public boolean removeAllSymbols(Collection<? extends Symbol> symbols) {
  74         return symbolsSet.removeAll(symbols);
  75     }
  76 
  77     @Override
  78     protected void exportSymbols() {
  79         symbolsSet.stream().forEach(symbol -> {
  80             SymbolTable.add(symbol);
  81         });
  82     }
  83 
  84     public void setParent(TypeKlass p) {
  85         parent = p;
  86     }
  87 
  88     public void addParent(String p) {
  89         if (parentsList == null) {
  90             parentsList = new HashSet<>();
  91         }
  92         parentsList.add(p);
  93     }
  94 
  95     public void addChild(String c) {
  96         if (childrenList == null) {
  97             childrenList = new HashSet<>();
  98         }
  99         childrenList.add(c);
 100     }
 101 
 102     protected void removeParent(String p) {
 103         if (parentsList != null) {
 104             parentsList.remove(p);
 105         }
 106     }
 107 
 108     protected void removeChild(String c) {
 109         if (childrenList != null) {
 110             childrenList.remove(c);
 111         }
 112     }
 113 
 114     public HashSet<String> getParentsNames() {
 115         return parentsList;
 116     }
 117 
 118     public HashSet<String> getChildrenNames() {
 119         return childrenList;
 120     }
 121 
 122     @Override
 123     public boolean canCompareTo(Type t) {
 124         return false;
 125     }
 126 
 127     @Override
 128     public boolean canEquateTo(Type t) {
 129         return true;
 130     }
 131 
 132     public TreeSet<TypeKlass> getAllParents() {
 133         TreeSet<TypeKlass> result = new TreeSet<>();
 134         if (parentsList != null) {
 135             for (String parentName : parentsList) {
 136                 Type _parentKlass = TypeList.find(new TypeKlass(parentName));
 137                 if (_parentKlass != null) {
 138                     try {
 139                         TypeKlass parentKlass = (TypeKlass) _parentKlass;
 140                         result.add(parentKlass);
 141                         result.addAll(parentKlass.getAllParents());
 142                     } catch (Exception e) {
 143                     }
 144                 }
 145             }
 146         }
 147         return result;
 148     }
 149 
 150     public TreeSet<TypeKlass> getAllChildren() {
 151         TreeSet<TypeKlass> r = new TreeSet<>();
 152         if (childrenList != null) {
 153             for (String childName : childrenList) {
 154                 Type _childKlass = TypeList.find(new TypeKlass(childName));
 155                 if (_childKlass != null) {
 156                     try {
 157                         TypeKlass childKlass = (TypeKlass) _childKlass;
 158                         r.add(childKlass);
 159                         r.addAll(childKlass.getAllChildren());
 160                     } catch (Exception e) {
 161                     }
 162                 }
 163             }
 164         }
 165         return r;
 166     }
 167 
 168     @Override
 169     public boolean canImplicitlyCastTo(Type t) {
 170         // We can implicitly cast to anything up the hierarchy and to self
 171         if (t instanceof TypeKlass) {
 172             return equals(t) || getAllParents().contains(t);
 173         }
 174         return false;
 175     }
 176 
 177     // If canExplicitlyCastTo() returns true in this case it doesn't mean that
 178     // it would really be successful. Since explicit casts are inherintly dynamic
 179     // we cannot guarantee that no exception will occur.
 180     @Override
 181     public boolean canExplicitlyCastTo(Type t) {
 182         if (t instanceof TypeKlass && !ProductionParams.disableDowncasts.value()) {
 183             return equals(t) || getAllChildren().contains(t);
 184         }
 185 
 186         return false;
 187     }
 188 
 189     public boolean isFinal() {
 190         return (flags & FINAL) > 0;
 191     }
 192 
 193     public void setFinal() {
 194         flags |= FINAL;
 195     }
 196 
 197     public boolean isAbstract() {
 198         return (flags & ABSTRACT) > 0;
 199     }
 200 
 201     public void setAbstract() {
 202         flags |= ABSTRACT;
 203     }
 204 
 205     public boolean isInterface() {
 206         return (flags & INTERFACE) > 0;
 207     }
 208 }