lvalue.java
来自「jpda例子文件」· Java 代码 · 共 1,049 行 · 第 1/3 页
JAVA
1,049 行
/* * @(#)LValue.java 1.24 02/09/05 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. *//* * Copyright (c) 1997-1999 by Sun Microsystems, Inc. All Rights Reserved. * * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use, * modify and redistribute this software in source and binary code form, * provided that i) this copyright notice and license appear on all copies of * the software; and ii) Licensee does not utilize the software in a manner * which is disparaging to Sun. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * This software is not designed or intended for use in on-line control of * aircraft, air traffic, aircraft navigation or aircraft communications; or in * the design, construction, operation or maintenance of any nuclear * facility. Licensee represents and warrants that it will not use or * redistribute the Software for such purposes. */package com.sun.tools.example.debug.expr;import com.sun.jdi.*;import java.util.*;abstract class LValue { // The JDI Value object for this LValue. Once we have this Value, // we have to remember it since after we return the LValue object // to the ExpressionParser, it might decide that it needs // the 'toString' value for the LValue in which case it will // call getMassagedValue to get this toString value. At that // point, we don't want to call JDI a 2nd time to get the Value // for the LValue. This is especially wrong when the LValue // represents a member function. We would end up calling it // a 2nd time. // // Unfortunately, there are several levels of calls to // get/set values in this file. To minimize confusion, // jdiValue is set/tested at the lowest level - right // next to the actual calls to JDI methods to get/set the // value in the debuggee. protected Value jdiValue; abstract Value getValue() throws InvocationException, IncompatibleThreadStateException, InvalidTypeException, ClassNotLoadedException, ParseException; abstract void setValue0(Value value) throws ParseException, InvalidTypeException, ClassNotLoadedException; abstract void invokeWith(List arguments) throws ParseException; void setValue(Value value) throws ParseException { try { setValue0(value); } catch (InvalidTypeException exc) { throw new ParseException( "Attempt to set value of incorrect type" + exc); } catch (ClassNotLoadedException exc) { throw new ParseException( "Attempt to set value before " + exc.className() + " was loaded" + exc); } } void setValue(LValue lval) throws ParseException { setValue(lval.interiorGetValue()); } LValue memberLValue(ExpressionParser.GetFrame frameGetter, String fieldName) throws ParseException { try { return memberLValue(fieldName, frameGetter.get().thread()); } catch (IncompatibleThreadStateException exc) { throw new ParseException("Thread not suspended"); } } LValue memberLValue(String fieldName, ThreadReference thread) throws ParseException { Value val = interiorGetValue(); if ((val instanceof ArrayReference) && "length".equals(fieldName)){ return new LValueArrayLength((ArrayReference)val); } return new LValueInstanceMember(val, fieldName, thread); } // Return the Value for this LValue that would be used to concatenate // to a String. IE, if it is an Object, call toString in the debuggee. Value getMassagedValue(ExpressionParser.GetFrame frameGetter) throws ParseException { Value vv = interiorGetValue(); // If vv is an ObjectReference, then we have to // do the implicit call to toString(). if (vv instanceof ObjectReference && !(vv instanceof StringReference) && !(vv instanceof ArrayReference)) { StackFrame frame; try { frame = frameGetter.get(); } catch (IncompatibleThreadStateException exc) { throw new ParseException("Thread not suspended"); } ThreadReference thread = frame.thread(); LValue toStringMember = memberLValue("toString", thread); toStringMember.invokeWith(new ArrayList()); return toStringMember.interiorGetValue(); } return vv; } Value interiorGetValue() throws ParseException { Value value; try { value = getValue(); } catch (InvocationException e) { throw new ParseException("Unable to complete expression. Exception " + e.exception() + " thrown"); } catch (IncompatibleThreadStateException itse) { throw new ParseException("Unable to complete expression. Thread " + "not suspended for method invoke"); } catch (InvalidTypeException ite) { throw new ParseException("Unable to complete expression. Method " + "argument type mismatch"); } catch (ClassNotLoadedException tnle) { throw new ParseException("Unable to complete expression. Method " + "argument type " + tnle.className() + " not yet loaded"); } return value; } LValue arrayElementLValue(LValue lval) throws ParseException { Value indexValue = lval.interiorGetValue(); int index; if ( (indexValue instanceof IntegerValue) || (indexValue instanceof ShortValue) || (indexValue instanceof ByteValue) || (indexValue instanceof CharValue) ) { index = ((PrimitiveValue)indexValue).intValue(); } else { throw new ParseException("Array index must be a integer type"); } return new LValueArrayElement(interiorGetValue(), index); } public String toString() { try { return interiorGetValue().toString(); } catch (ParseException e) { return "<Parse Exception>"; } } static final int STATIC = 0; static final int INSTANCE = 1; static Field fieldByName(ReferenceType refType, String name, int kind) { /* * TO DO: Note that this currently fails to find superclass * or implemented interface fields. This is due to a temporary * limititation of RefType.fieldByName. Once that method is * fixed, superclass fields will be found. */ Field field = refType.fieldByName(name); if (field != null) { boolean isStatic = field.isStatic(); if (((kind == STATIC) && !isStatic) || ((kind == INSTANCE) && isStatic)) { field = null; } }/*** System.err.println("fieldByName: " + refType.name() + " " + name + " " + kind + " " + (field != null));***/ return field; } static List methodsByName(ReferenceType refType, String name, int kind) { List list = refType.methodsByName(name); Iterator iter = list.iterator(); while (iter.hasNext()) { Method method = (Method)iter.next(); boolean isStatic = method.isStatic(); if (((kind == STATIC) && !isStatic) || ((kind == INSTANCE) && isStatic)) { iter.remove(); } } return list; } static List primitiveTypeNames = new ArrayList(); static { primitiveTypeNames.add("boolean"); primitiveTypeNames.add("byte"); primitiveTypeNames.add("char"); primitiveTypeNames.add("short"); primitiveTypeNames.add("int"); primitiveTypeNames.add("long"); primitiveTypeNames.add("float"); primitiveTypeNames.add("double"); } static final int SAME = 0; static final int ASSIGNABLE = 1; static final int DIFFERENT = 2; /* * Return SAME, DIFFERENT or ASSIGNABLE. * SAME means each arg type is the same as type of the corr. arg. * ASSIGNABLE means that not all the pairs are the same, but * for those that aren't, at least the argType is assignable * from the type of the argument value. * DIFFERENT means that in at least one pair, the * argType is not assignable from the type of the argument value. * IE, one is an Apple and the other is an Orange. */ static int argumentsMatch(List argTypes, List arguments) { if (argTypes.size() != arguments.size()) { return DIFFERENT; } Iterator typeIter = argTypes.iterator(); Iterator valIter = arguments.iterator(); int result = SAME; // If any pair aren't the same, change the // result to ASSIGNABLE. If any pair aren't // assignable, return DIFFERENT while (typeIter.hasNext()) { Type argType = (Type)typeIter.next(); Value value = (Value)valIter.next(); if (value == null) { // Null values can be passed to any non-primitive argument if (primitiveTypeNames.contains(argType.name())) { return DIFFERENT; } // Else, we will assume that a null value // exactly matches an object type. } if (!value.type().equals(argType)) { if (isAssignableTo(value.type(), argType)) { result = ASSIGNABLE; } else { return DIFFERENT; } } } return result; } // These is...AssignableTo methods are based on similar code in the JDI // implementations of ClassType, ArrayType, and InterfaceType static boolean isComponentAssignable(Type fromType, Type toType) { if (fromType instanceof PrimitiveType) { // Assignment of primitive arrays requires identical // component types. return fromType.equals(toType); } if (toType instanceof PrimitiveType) { return false; } // Assignment of object arrays requires availability // of widening conversion of component types return isAssignableTo(fromType, toType); } static boolean isArrayAssignableTo(ArrayType fromType, Type toType) { if (toType instanceof ArrayType) { try { Type toComponentType = ((ArrayType)toType).componentType(); return isComponentAssignable(fromType.componentType(), toComponentType); } catch (ClassNotLoadedException e) { // One or both component types has not yet been // loaded => can't assign return false; } } if (toType instanceof InterfaceType) { // Only valid InterfaceType assignee is Cloneable return toType.name().equals("java.lang.Cloneable"); } // Only valid ClassType assignee is Object return toType.name().equals("java.lang.Object"); } static boolean isAssignableTo(Type fromType, Type toType) { if (fromType.equals(toType)) { return true; } // If one is boolean, so must be the other. if (fromType instanceof BooleanType) { if (toType instanceof BooleanType) { return true; } return false; } if (toType instanceof BooleanType) { return false; } // Other primitive types are intermixable only with each other. if (fromType instanceof PrimitiveType) { if (toType instanceof PrimitiveType) { return true; } return false; } if (toType instanceof PrimitiveType) { return false; } // neither one is primitive. if (fromType instanceof ArrayType) { return isArrayAssignableTo((ArrayType)fromType, toType); } List interfaces; if (fromType instanceof ClassType) { ClassType superclazz = ((ClassType)fromType).superclass(); if ((superclazz != null) && isAssignableTo(superclazz, toType)) { return true; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?