Sun, 04 Nov 2012 10:59:42 +0000
7192246: Add type-checking support for default methods
Summary: Add type-checking support for default methods as per Featherweight-Defender document
Reviewed-by: jjg, dlsmith
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 */
26 package shapegen;
28 import shapegen.ClassCase.Kind;
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.Set;
34 import static shapegen.ClassCase.Kind.*;
36 /**
37 * Type Template Node
38 *
39 * @author Robert Field
40 */
41 public class TTNode {
43 final List<TTNode> supertypes;
44 final boolean canBeClass;
46 private int currentKindIndex;
47 private Kind[] kinds;
49 public TTNode(List<TTNode> subtypes, boolean canBeClass) {
50 this.supertypes = subtypes;
51 this.canBeClass = canBeClass;
52 }
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;
63 for (TTNode sub : supertypes) {
64 sub.start(includeClasses);
65 }
66 }
68 public boolean next() {
69 ++currentKindIndex;
70 if (currentKindIndex >= kinds.length) {
71 currentKindIndex = 0;
72 return false;
73 } else {
74 return true;
75 }
76 }
78 public void collectAllSubtypes(Set<TTNode> subs) {
79 subs.add(this);
80 for (TTNode n : supertypes) {
81 n.collectAllSubtypes(subs);
82 }
83 }
85 private Kind getKind() {
86 return kinds[currentKindIndex];
87 }
89 boolean isInterface() {
90 return getKind().isInterface;
91 }
93 boolean isClass() {
94 return !isInterface();
95 }
97 boolean hasDefault() {
98 return getKind() == IDEFAULT;
99 }
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 }
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 }