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.
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 org.openjdk.tests.shapegen;
25 
26 import java.util.HashSet;
27 import java.util.Set;
28 
29 import static org.openjdk.tests.shapegen.ClassCase.Kind.*;
30 
31 /**
32  *
33  * @author Robert Field
34  */
35 public class RuleGroup {
36 
37     final String name;
38     private final Rule[] rules;
39 
RuleGroup(String name, Rule[] rules)40     public RuleGroup(String name, Rule[] rules) {
41         this.name = name;
42         this.rules = rules;
43     }
44 
exec(ClassCase cc)45     public boolean exec(ClassCase cc) {
46         boolean found = false;
47         for (Rule rule : rules) {
48             if (rule.guard(cc)) {
49                 if (found) {
50                     throw new RuntimeException("Bad rules -- multiple matches " + toString() + " for " + cc);
51                 } else {
52                     rule.eval(cc);
53                     found = true;
54                 }
55             }
56         }
57         return found;
58     }
59 
60     @Override
toString()61     public String toString() {
62         return name;
63     }
64 
65     public static RuleGroup PROVENENCE = new RuleGroup("Provenence", new Rule[] {
66       new Rule("P-CDeclare") {
67           boolean guard(ClassCase cc) {
68               return cc.isa(CCONCRETE, CABSTRACT);
69           }
70 
71           void eval(ClassCase cc) {
72               cc.set_mprov(cc);
73               cc.set_HasClassMethod(true);
74           }
75       },
76 
77       new Rule("P-IDeclare") {
78           boolean guard(ClassCase cc) {
79               return cc.isa(IDEFAULT, IPRESENT);
80           }
81 
82           void eval(ClassCase cc) {
83               cc.set_mprov(cc);
84           }
85       },
86 
87       new Rule("P-IntfInh") {
88           boolean guard(ClassCase cc) {
89               return cc.isa(IVAC, CNONE) && !(cc.hasSuperclass() && cc.getSuperclass().get_HasClassMethod());
90           }
91 
92           void eval(ClassCase cc) {
93               Set<ClassCase> _S = new HashSet<>();
94               for (ClassCase t : cc.getSupertypes()) {
95                   _S.addAll(t.get_mprov());
96               }
97               Set<ClassCase> tops = new HashSet<>();
98               for (ClassCase _W : _S) {
99                   for (ClassCase _V : _S) {
100                       if (_V.equals(_W) || !(_V.isSubtypeOf(_W))) {
101                           tops.add(_W);
102                       }
103                   }
104               }
105               cc.set_mprov(tops);
106           }
107       },
108 
109       new Rule("P-ClassInh") {
110           boolean guard(ClassCase cc) {
111               return cc.isa(CNONE) && (cc.hasSuperclass() && cc.getSuperclass().get_HasClassMethod());
112           }
113 
114           void eval(ClassCase cc) {
115               cc.set_mprov(cc.getSuperclass());
116               cc.set_HasClassMethod(true);
117           }
118       },
119 
120     });
121 
122     public static RuleGroup MARKER = new RuleGroup("Marker", new Rule[] {
123       new Rule("M-Default") {
124           boolean guard(ClassCase cc) {
125               return cc.isa(IDEFAULT);
126           }
127 
128           void eval(ClassCase cc) {
129               cc.set_HasDefault(true);
130           }
131       },
132 
133       new Rule("M-Conc") {
134           boolean guard(ClassCase cc) {
135             return cc.isa(CCONCRETE);
136           }
137 
138           void eval(ClassCase cc) {
139               cc.set_IsConcrete(true);
140           }
141       },
142 
143     });
144 
145     public static RuleGroup RESOLUTION = new RuleGroup("Resolution", new Rule[] {
146       new Rule("R-Resolve") {
147           boolean guard(ClassCase cc) {
148               if (!(cc.isClass() && cc.get_mprov().size() == 1)) {
149                   return false;
150               }
151               ClassCase _V = cc.get_mprov().iterator().next();
152               return _V.get_IsConcrete() || _V.get_HasDefault();
153           }
154 
155           void eval(ClassCase cc) {
156               ClassCase _V = cc.get_mprov().iterator().next();
157               cc.set_mres(_V);
158           }
159       },
160 
161     });
162 
163     public static RuleGroup DEFENDER = new RuleGroup("Defender", new Rule[] {
164       new Rule("D-Defend") {
165           boolean guard(ClassCase cc) {
166               ClassCase mresSuper = cc.hasSuperclass() ? cc.getSuperclass().get_mres() : null;
167               boolean eq = cc.get_mres() == null ? mresSuper == null : cc.get_mres().equals(mresSuper);
168               return cc.isa(CNONE) && !eq;
169           }
170 
171           void eval(ClassCase cc) {
172               cc.set_mdefend(cc.get_mres());
173           }
174       },
175 
176     });
177 
178     public static RuleGroup CHECKING = new RuleGroup("Checking", new Rule[] {
179       new Rule("C-Check") {
180           boolean guard(ClassCase cc) {
181               for (ClassCase t : cc.getSupertypes()) {
182                   if (! t.get_OK()) {
183                       return false;
184                   }
185               }
186               int defenderCount = 0;
187               int provCount = 0;
188               for (ClassCase prov : cc.get_mprov()) {
189                   if (prov.get_HasDefault()) {
190                       defenderCount++;
191                   }
192                   provCount++;
193               }
194               return provCount <= 1 || defenderCount == 0;
195           }
196 
197           void eval(ClassCase cc) {
198               cc.set_OK(true);
199           }
200       },
201 
202     });
203 
204 }
205