blob: a8dd7c1d7f4be97289f88137992f9de0048bf8ef [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1998-1999 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package com.sun.tools.jdi;
27
28import com.sun.jdi.*;
29
30import java.util.List;
31import java.util.ArrayList;
32import java.util.Map;
33import java.util.Iterator;
34import java.util.Collections;
35import java.lang.ref.SoftReference;
36
37public class InterfaceTypeImpl extends ReferenceTypeImpl
38 implements InterfaceType {
39
40 private SoftReference<List<InterfaceType>> superinterfacesRef = null;
41
42 protected InterfaceTypeImpl(VirtualMachine aVm,long aRef) {
43 super(aVm, aRef);
44 }
45
46 public List<InterfaceType> superinterfaces() {
47 List<InterfaceType> superinterfaces = (superinterfacesRef == null) ? null :
48 superinterfacesRef.get();
49 if (superinterfaces == null) {
50 superinterfaces = getInterfaces();
51 superinterfaces = Collections.unmodifiableList(superinterfaces);
52 superinterfacesRef = new SoftReference<List<InterfaceType>>(superinterfaces);
53 }
54 return superinterfaces;
55 }
56
57 public List<InterfaceType> subinterfaces() {
58 List<InterfaceType> subs = new ArrayList<InterfaceType>();
59 for (ReferenceType refType : vm.allClasses()) {
60 if (refType instanceof InterfaceType) {
61 InterfaceType interfaze = (InterfaceType)refType;
62 if (interfaze.isPrepared() && interfaze.superinterfaces().contains(this)) {
63 subs.add(interfaze);
64 }
65 }
66 }
67 return subs;
68 }
69
70 public List<ClassType> implementors() {
71 List<ClassType> implementors = new ArrayList<ClassType>();
72 for (ReferenceType refType : vm.allClasses()) {
73 if (refType instanceof ClassType) {
74 ClassType clazz = (ClassType)refType;
75 if (clazz.isPrepared() && clazz.interfaces().contains(this)) {
76 implementors.add(clazz);
77 }
78 }
79 }
80 return implementors;
81 }
82
83 void addVisibleMethods(Map<String, Method> methodMap) {
84 /*
85 * Add methods from
86 * parent types first, so that the methods in this class will
87 * overwrite them in the hash table
88 */
89
90 for (InterfaceType interfaze : superinterfaces()) {
91 ((InterfaceTypeImpl)interfaze).addVisibleMethods(methodMap);
92 }
93
94 addToMethodMap(methodMap, methods());
95 }
96
97 public List<Method> allMethods() {
98 ArrayList<Method> list = new ArrayList<Method>(methods());
99
100 /*
101 * It's more efficient if don't do this
102 * recursively.
103 */
104 for (InterfaceType interfaze : allSuperinterfaces()) {
105 list.addAll(interfaze.methods());
106 }
107
108 return list;
109 }
110
111 List<InterfaceType> allSuperinterfaces() {
112 ArrayList<InterfaceType> list = new ArrayList<InterfaceType>();
113 addSuperinterfaces(list);
114 return list;
115 }
116
117 void addSuperinterfaces(List<InterfaceType> list) {
118 /*
119 * This code is a little strange because it
120 * builds the list with a more suitable order than the
121 * depth-first approach a normal recursive solution would
122 * take. Instead, all direct superinterfaces precede all
123 * indirect ones.
124 */
125
126 /*
127 * Get a list of direct superinterfaces that's not already in the
128 * list being built.
129 */
130 List<InterfaceType> immediate = new ArrayList<InterfaceType>(superinterfaces());
131 Iterator iter = immediate.iterator();
132 while (iter.hasNext()) {
133 InterfaceType interfaze = (InterfaceType)iter.next();
134 if (list.contains(interfaze)) {
135 iter.remove();
136 }
137 }
138
139 /*
140 * Add all new direct superinterfaces
141 */
142 list.addAll(immediate);
143
144 /*
145 * Recurse for all new direct superinterfaces.
146 */
147 iter = immediate.iterator();
148 while (iter.hasNext()) {
149 InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
150 interfaze.addSuperinterfaces(list);
151 }
152 }
153
154 boolean isAssignableTo(ReferenceType type) {
155
156 // Exact match?
157 if (this.equals(type)) {
158 return true;
159 } else {
160 // Try superinterfaces.
161 for (InterfaceType interfaze : superinterfaces()) {
162 if (((InterfaceTypeImpl)interfaze).isAssignableTo(type)) {
163 return true;
164 }
165 }
166
167 return false;
168 }
169 }
170
171 List<InterfaceType> inheritedTypes() {
172 return superinterfaces();
173 }
174
175 public boolean isInitialized() {
176 return isPrepared();
177 }
178
179 public String toString() {
180 return "interface " + name() + " (" + loaderString() + ")";
181 }
182}