src/jdk.jdi/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java
changeset 47216 71c04702a3d5
parent 45714 1820d351198d
child 54907 6bcda7ed24ef
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jdi/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java	Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.jdi;
+
+import java.lang.ref.SoftReference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.sun.jdi.ClassType;
+import com.sun.jdi.InterfaceType;
+import com.sun.jdi.Method;
+import com.sun.jdi.ReferenceType;
+import com.sun.jdi.VirtualMachine;
+
+final public class InterfaceTypeImpl extends InvokableTypeImpl
+                                     implements InterfaceType {
+
+    private static class IResult implements InvocationResult {
+        final private JDWP.InterfaceType.InvokeMethod rslt;
+
+        public IResult(JDWP.InterfaceType.InvokeMethod rslt) {
+            this.rslt = rslt;
+        }
+
+        @Override
+        public ObjectReferenceImpl getException() {
+            return rslt.exception;
+        }
+
+        @Override
+        public ValueImpl getResult() {
+            return rslt.returnValue;
+        }
+
+    }
+
+    private SoftReference<List<InterfaceType>> superinterfacesRef = null;
+
+    protected InterfaceTypeImpl(VirtualMachine aVm,long aRef) {
+        super(aVm, aRef);
+    }
+
+    public List<InterfaceType> superinterfaces() {
+        List<InterfaceType> superinterfaces = (superinterfacesRef == null) ? null :
+                                     superinterfacesRef.get();
+        if (superinterfaces == null) {
+            superinterfaces = getInterfaces();
+            superinterfaces = Collections.unmodifiableList(superinterfaces);
+            superinterfacesRef = new SoftReference<List<InterfaceType>>(superinterfaces);
+        }
+        return superinterfaces;
+    }
+
+    public List<InterfaceType> subinterfaces() {
+        List<InterfaceType> subs = new ArrayList<InterfaceType>();
+        for (ReferenceType refType : vm.allClasses()) {
+            if (refType instanceof InterfaceType) {
+                InterfaceType interfaze = (InterfaceType)refType;
+                if (interfaze.isPrepared() && interfaze.superinterfaces().contains(this)) {
+                    subs.add(interfaze);
+                }
+            }
+        }
+        return subs;
+    }
+
+    public List<ClassType> implementors() {
+        List<ClassType> implementors = new ArrayList<ClassType>();
+        for (ReferenceType refType : vm.allClasses()) {
+            if (refType instanceof ClassType) {
+                ClassType clazz = (ClassType)refType;
+                if (clazz.isPrepared() && clazz.interfaces().contains(this)) {
+                    implementors.add(clazz);
+                }
+            }
+        }
+        return implementors;
+    }
+
+    public boolean isInitialized() {
+        return isPrepared();
+    }
+
+    public String toString() {
+       return "interface " + name() + " (" + loaderString() + ")";
+    }
+
+    @Override
+    InvocationResult waitForReply(PacketStream stream) throws JDWPException {
+        return new IResult(JDWP.InterfaceType.InvokeMethod.waitForReply(vm, stream));
+    }
+
+    @Override
+    CommandSender getInvokeMethodSender(final ThreadReferenceImpl thread,
+                                        final MethodImpl method,
+                                        final ValueImpl[] args,
+                                        final int options) {
+        return () ->
+            JDWP.InterfaceType.InvokeMethod.enqueueCommand(vm,
+                                                           InterfaceTypeImpl.this,
+                                                           thread,
+                                                           method.ref(),
+                                                           args,
+                                                           options);
+    }
+
+    @Override
+    ClassType superclass() {
+        return null;
+    }
+
+    @Override
+    boolean isAssignableTo(ReferenceType type) {
+        if (type.name().equals("java.lang.Object")) {
+            // interfaces are always assignable to j.l.Object
+            return true;
+        }
+        return super.isAssignableTo(type);
+    }
+
+    @Override
+    List<InterfaceType> interfaces() {
+        return superinterfaces();
+    }
+
+    @Override
+    boolean canInvoke(Method method) {
+        // method must be directly in this interface
+        return this.equals(method.declaringType());
+    }
+}