lvalue.java

来自「jpda例子文件」· Java 代码 · 共 1,049 行 · 第 1/3 页

JAVA
1,049
字号
            interfaces = ((ClassType)fromType).interfaces();        } else {            // fromType must be an InterfaceType            interfaces = ((InterfaceType)fromType).superinterfaces();        }        Iterator iter = interfaces.iterator();        while (iter.hasNext()) {            InterfaceType interfaze = (InterfaceType)iter.next();            if (isAssignableTo(interfaze, toType)) {                return true;            }        }        return false;    }    static Method resolveOverload(List overloads, List arguments)                                        throws ParseException {        // If there is only one method to call, we'll just choose        // that without looking at the args.  If they aren't right        // the invoke will return a better error message than we        // could generate here.        if (overloads.size() == 1) {            return (Method)overloads.get(0);        }        // Resolving overloads is beyond the scope of this exercise.        // So, we will look for a method that matches exactly the        // types of the arguments.  If we can't find one, then        // if there is exactly one method whose param types are assignable        // from the arg types, we will use that.  Otherwise,        // it is an error.  We won't guess which of multiple possible        // methods to call. And, since casts aren't implemented,        // the user can't use them to pick a particular overload to call.        // IE, the user is out of luck in this case.        Iterator iter = overloads.iterator();        Method retVal = null;        int assignableCount = 0;        while (iter.hasNext()) {            Method mm = (Method)iter.next();            List argTypes;            try {                argTypes = mm.argumentTypes();            } catch (ClassNotLoadedException ee) {                // This probably won't happen for the                // method that we are really supposed to                // call.                continue;            }            int compare = argumentsMatch(argTypes, arguments);            if (compare == SAME) {                return mm;            }            if (compare == DIFFERENT) {                continue;            }            // Else, it is assignable.  Remember it.            retVal = mm;            assignableCount++;        }        // At this point, we didn't find an exact match,        // but we found one for which the args are assignable.        //         if (retVal != null) {            if (assignableCount == 1) {                return retVal;            }            throw new ParseException("Arguments match multiple methods");        }        throw new ParseException("Arguments match no method");    }    private static class LValueLocal extends LValue {        final StackFrame frame;        final LocalVariable var;        LValueLocal(StackFrame frame, LocalVariable var) {            this.frame = frame;            this.var = var;        }                Value getValue() {            if (jdiValue == null) {                jdiValue = frame.getValue(var);            }            return jdiValue;        }        void setValue0(Value val) throws InvalidTypeException,                                          ClassNotLoadedException {            frame.setValue(var, val);            jdiValue = val;        }        void invokeWith(List arguments) throws ParseException {            throw new ParseException(var.name() + " is not a method");        }    }    private static class LValueInstanceMember extends LValue {        final ObjectReference obj;        final ThreadReference thread;        final Field matchingField;        final List overloads;        Method matchingMethod = null;        List methodArguments = null;        LValueInstanceMember(Value value,                             String memberName,                             ThreadReference thread) throws ParseException {            if (!(value instanceof ObjectReference)) {                throw new ParseException(                       "Cannot access field of primitive type: " + value);            }            this.obj = (ObjectReference)value;            this.thread = thread;            ReferenceType refType = obj.referenceType();            /*             * Can't tell yet whether this LValue will be accessed as a             * field or method, so we keep track of all the possibilities             */            matchingField = LValue.fieldByName(refType, memberName,                                                LValue.INSTANCE);            overloads = LValue.methodsByName(refType, memberName,                                              LValue.INSTANCE);            if ((matchingField == null) && overloads.size() == 0) {                throw new ParseException("No instance field or method with the name "                               + memberName + " in " + refType.name());            }        }                Value getValue() throws InvocationException, InvalidTypeException,                                ClassNotLoadedException, IncompatibleThreadStateException,                                ParseException {            if (jdiValue != null) {                return jdiValue;            }            if (matchingMethod == null) {                if (matchingField == null) {                    throw new ParseException("No such field in " + obj.referenceType().name());                }                return jdiValue = obj.getValue(matchingField);            } else {                return jdiValue = obj.invokeMethod(thread, matchingMethod, methodArguments, 0);            }        }        void setValue0(Value val) throws ParseException,                                          InvalidTypeException,                                        ClassNotLoadedException {            if (matchingMethod != null) {                throw new ParseException("Cannot assign to a method invocation");            }            obj.setValue(matchingField, val);            jdiValue = val;        }        void invokeWith(List arguments) throws ParseException {            if (matchingMethod != null) {                throw new ParseException("Invalid consecutive invocations");            }            methodArguments = arguments;            matchingMethod = LValue.resolveOverload(overloads, arguments);        }    }    private static class LValueStaticMember extends LValue {        final ReferenceType refType;        final ThreadReference thread;        final Field matchingField;        final List overloads;        Method matchingMethod = null;        List methodArguments = null;        LValueStaticMember(ReferenceType refType,                           String memberName,                          ThreadReference thread) throws ParseException {            this.refType = refType;            this.thread = thread;            /*             * Can't tell yet whether this LValue will be accessed as a             * field or method, so we keep track of all the possibilities             */            matchingField = LValue.fieldByName(refType, memberName,                                                LValue.STATIC);            overloads = LValue.methodsByName(refType, memberName,                                              LValue.STATIC);            if ((matchingField == null) && overloads.size() == 0) {                throw new ParseException("No static field or method with the name "                               + memberName + " in " + refType.name());            }        }                Value getValue() throws InvocationException, InvalidTypeException,                                ClassNotLoadedException, IncompatibleThreadStateException,                                ParseException {            if (jdiValue != null) {                return jdiValue;            }            if (matchingMethod == null) {                return jdiValue = refType.getValue(matchingField);            } else if (refType instanceof ClassType) {                ClassType clazz = (ClassType)refType;                return jdiValue = clazz.invokeMethod(thread, matchingMethod, methodArguments, 0);            } else {                throw new InvalidTypeException("Cannot invoke static method on " +                                         refType.name());            }        }        void setValue0(Value val)                            throws ParseException, InvalidTypeException,                                  ClassNotLoadedException {            if (matchingMethod != null) {                throw new ParseException("Cannot assign to a method invocation");            }            if (!(refType instanceof ClassType)) {                throw new ParseException(                       "Cannot set interface field: " + refType);            }            ((ClassType)refType).setValue(matchingField, val);            jdiValue = val;        }        void invokeWith(List arguments) throws ParseException {            if (matchingMethod != null) {                throw new ParseException("Invalid consecutive invocations");            }            methodArguments = arguments;            matchingMethod = LValue.resolveOverload(overloads, arguments);        }    }    private static class LValueArrayLength extends LValue {        /*         * Since one can code "int myLen = myArray.length;",         * one might expect that these JDI calls would get a Value         * object for the length of an array in the debugee:         *    Field xxx = ArrayType.fieldByName("length")         *    Value lenVal= ArrayReference.getValue(xxx)         *         * However, this doesn't work because the array length isn't         * really stored as a field, and can't be accessed as such         * via JDI.  Instead, the arrayRef.length() method has to be         * used.         */        final ArrayReference arrayRef;        LValueArrayLength (ArrayReference value) {            this.arrayRef = value;        }        Value getValue() {            if (jdiValue == null) {                jdiValue = arrayRef.virtualMachine().mirrorOf(arrayRef.length());            }            return jdiValue;        }        void setValue0(Value value) throws ParseException  {            throw new ParseException("Cannot set constant: " + value);        }        void invokeWith(List arguments) throws ParseException {            throw new ParseException("Array element is not a method");        }    }    private static class LValueArrayElement extends LValue {        final ArrayReference array;        final int index;        LValueArrayElement(Value value, int index) throws ParseException {            if (!(value instanceof ArrayReference)) {                throw new ParseException(                       "Must be array type: " + value);            }            this.array = (ArrayReference)value;            this.index = index;        }                Value getValue() {            if (jdiValue == null) {                jdiValue = array.getValue(index);            }            return jdiValue;        }        void setValue0(Value val) throws InvalidTypeException,                                          ClassNotLoadedException  {            array.setValue(index, val);            jdiValue = val;        }        void invokeWith(List arguments) throws ParseException {            throw new ParseException("Array element is not a method");        }    }    private static class LValueConstant extends LValue {        final Value value;        LValueConstant(Value value) {            this.value = value;        }                Value getValue() {            if (jdiValue == null) {                jdiValue = value;            }            return jdiValue;        }        void setValue0(Value val) throws ParseException {            throw new ParseException("Cannot set constant: " + value);        }        void invokeWith(List arguments) throws ParseException {            throw new ParseException("Constant is not a method");        }    }    static LValue make(VirtualMachine vm, boolean val) {        return new LValueConstant(vm.mirrorOf(val));    }    static LValue make(VirtualMachine vm, byte val) {        return new LValueConstant(vm.mirrorOf(val));    }    static LValue make(VirtualMachine vm, char val) {        return new LValueConstant(vm.mirrorOf(val));    }    static LValue make(VirtualMachine vm, short val) {        return new LValueConstant(vm.mirrorOf(val));    }    static LValue make(VirtualMachine vm, int val) {        return new LValueConstant(vm.mirrorOf(val));    }    static LValue make(VirtualMachine vm, long val) {        return new LValueConstant(vm.mirrorOf(val));    }    static LValue make(VirtualMachine vm, float val) {        return new LValueConstant(vm.mirrorOf(val));    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?