0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Micro//S ystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Micro//S ystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.modules.debugger.jpda.expr;
0043:
0044: import com.sun.jdi.AbsentInformationException;
0045: import com.sun.jdi.ArrayReference;
0046: import com.sun.jdi.ArrayType;
0047: import com.sun.jdi.BooleanType;
0048: import com.sun.jdi.BooleanValue;
0049: import com.sun.jdi.ByteType;
0050: import com.sun.jdi.ByteValue;
0051: import com.sun.jdi.CharType;
0052: import com.sun.jdi.CharValue;
0053: import com.sun.jdi.ClassNotLoadedException;
0054: import com.sun.jdi.ClassType;
0055: import com.sun.jdi.DoubleType;
0056: import com.sun.jdi.DoubleValue;
0057: import com.sun.jdi.Field;
0058: import com.sun.jdi.FloatType;
0059: import com.sun.jdi.FloatValue;
0060: import com.sun.jdi.IncompatibleThreadStateException;
0061: import com.sun.jdi.IntegerType;
0062: import com.sun.jdi.IntegerValue;
0063: import com.sun.jdi.InterfaceType;
0064: import com.sun.jdi.InvalidTypeException;
0065: import com.sun.jdi.InvocationException;
0066: import com.sun.jdi.LocalVariable;
0067: import com.sun.jdi.LongType;
0068: import com.sun.jdi.LongValue;
0069: import com.sun.jdi.Method;
0070: import com.sun.jdi.Mirror;
0071: import com.sun.jdi.NativeMethodException;
0072: import com.sun.jdi.ObjectCollectedException;
0073: import com.sun.jdi.ObjectReference;
0074: import com.sun.jdi.PrimitiveType;
0075: import com.sun.jdi.PrimitiveValue;
0076: import com.sun.jdi.ReferenceType;
0077: import com.sun.jdi.ShortType;
0078: import com.sun.jdi.ShortValue;
0079: import com.sun.jdi.StackFrame;
0080: import com.sun.jdi.StringReference;
0081: import com.sun.jdi.ThreadReference;
0082: import com.sun.jdi.Type;
0083: import com.sun.jdi.Value;
0084: import com.sun.jdi.VirtualMachine;
0085:
0086: import com.sun.source.tree.AnnotationTree;
0087: import com.sun.source.tree.ArrayAccessTree;
0088: import com.sun.source.tree.ArrayTypeTree;
0089: import com.sun.source.tree.AssertTree;
0090: import com.sun.source.tree.AssignmentTree;
0091: import com.sun.source.tree.BinaryTree;
0092: import com.sun.source.tree.BlockTree;
0093: import com.sun.source.tree.BreakTree;
0094: import com.sun.source.tree.CaseTree;
0095: import com.sun.source.tree.CatchTree;
0096: import com.sun.source.tree.ClassTree;
0097: import com.sun.source.tree.CompilationUnitTree;
0098: import com.sun.source.tree.CompoundAssignmentTree;
0099: import com.sun.source.tree.ConditionalExpressionTree;
0100: import com.sun.source.tree.ContinueTree;
0101: import com.sun.source.tree.DoWhileLoopTree;
0102: import com.sun.source.tree.EmptyStatementTree;
0103: import com.sun.source.tree.EnhancedForLoopTree;
0104: import com.sun.source.tree.ErroneousTree;
0105: import com.sun.source.tree.ExpressionStatementTree;
0106: import com.sun.source.tree.ExpressionTree;
0107: import com.sun.source.tree.ForLoopTree;
0108: import com.sun.source.tree.IdentifierTree;
0109: import com.sun.source.tree.IfTree;
0110: import com.sun.source.tree.ImportTree;
0111: import com.sun.source.tree.InstanceOfTree;
0112: import com.sun.source.tree.LabeledStatementTree;
0113: import com.sun.source.tree.LiteralTree;
0114: import com.sun.source.tree.MemberSelectTree;
0115: import com.sun.source.tree.MethodInvocationTree;
0116: import com.sun.source.tree.MethodTree;
0117: import com.sun.source.tree.ModifiersTree;
0118: import com.sun.source.tree.NewArrayTree;
0119: import com.sun.source.tree.NewClassTree;
0120: import com.sun.source.tree.ParameterizedTypeTree;
0121: import com.sun.source.tree.ParenthesizedTree;
0122: import com.sun.source.tree.PrimitiveTypeTree;
0123: import com.sun.source.tree.ReturnTree;
0124: import com.sun.source.tree.SwitchTree;
0125: import com.sun.source.tree.SynchronizedTree;
0126: import com.sun.source.tree.ThrowTree;
0127: import com.sun.source.tree.Tree;
0128: import com.sun.source.tree.TryTree;
0129: import com.sun.source.tree.TypeCastTree;
0130: import com.sun.source.tree.TypeParameterTree;
0131: import com.sun.source.tree.UnaryTree;
0132: import com.sun.source.tree.VariableTree;
0133: import com.sun.source.tree.WhileLoopTree;
0134: import com.sun.source.tree.WildcardTree;
0135: import com.sun.source.util.TreePath;
0136: import com.sun.source.util.TreePathScanner;
0137:
0138: import java.util.ArrayList;
0139: import java.util.Arrays;
0140: import java.util.Collections;
0141: import java.util.Iterator;
0142: import java.util.List;
0143: import java.util.logging.Level;
0144: import java.util.logging.Logger;
0145: import javax.lang.model.element.Element;
0146: import javax.lang.model.element.ElementKind;
0147: import javax.lang.model.element.ExecutableElement;
0148: import javax.lang.model.element.Modifier;
0149: import javax.lang.model.element.TypeElement;
0150: import javax.lang.model.element.VariableElement;
0151: import javax.lang.model.type.DeclaredType;
0152: import javax.lang.model.type.ErrorType;
0153: import javax.lang.model.type.ExecutableType;
0154: import javax.lang.model.type.TypeKind;
0155: import javax.lang.model.type.TypeMirror;
0156:
0157: import javax.lang.model.type.TypeVariable;
0158: import org.netbeans.api.debugger.jpda.InvalidExpressionException;
0159: import org.netbeans.api.java.source.ElementUtilities;
0160: import org.netbeans.modules.debugger.jpda.expr.EvaluationContext.VariableInfo;
0161: import org.netbeans.modules.debugger.jpda.models.CallStackFrameImpl;
0162: import org.openide.util.NbBundle;
0163:
0164: /**
0165: * Mirror is either Value or ReferenceType
0166: *
0167: * @author Martin Entlicher
0168: */
0169: public class EvaluatorVisitor extends
0170: TreePathScanner<Mirror, EvaluationContext> {
0171:
0172: private static final Logger loggerMethod = Logger
0173: .getLogger("org.netbeans.modules.debugger.jpda.invokeMethod"); // NOI18N
0174: private static final Logger loggerValue = Logger
0175: .getLogger("org.netbeans.modules.debugger.jpda.getValue"); // NOI8N
0176:
0177: private Type newArrayType;
0178:
0179: public EvaluatorVisitor() {
0180: }
0181:
0182: @Override
0183: public Mirror visitAnnotation(AnnotationTree arg0,
0184: EvaluationContext evaluationContext) {
0185: return null;
0186: }
0187:
0188: @Override
0189: public Mirror visitMethodInvocation(MethodInvocationTree arg0,
0190: EvaluationContext evaluationContext) {
0191: if (!evaluationContext.canInvokeMethods()) {
0192: Assert2.error(arg0, "calleeException",
0193: new UnsupportedOperationException(),
0194: evaluationContext);
0195: }
0196: if (loggerMethod.isLoggable(Level.FINE)) {
0197: loggerMethod.fine("STARTED : " + arg0 + " in thread "
0198: + evaluationContext.getFrame().thread());
0199: }
0200: Mirror object = null;
0201: String methodName;
0202: Boolean isStatic = null;
0203: ExpressionTree expression = arg0.getMethodSelect();
0204: Element elm;
0205: TreePath currentPath = getCurrentPath();
0206: if (expression.getKind() == Tree.Kind.MEMBER_SELECT) {
0207: MemberSelectTree mst = (MemberSelectTree) expression;
0208: object = mst.getExpression()
0209: .accept(this , evaluationContext);
0210: methodName = mst.getIdentifier().toString();
0211: if (currentPath != null) {
0212: TreePath memberSelectPath = TreePath.getPath(
0213: currentPath, mst);
0214: if (memberSelectPath == null)
0215: memberSelectPath = currentPath;
0216: elm = evaluationContext.getTrees().getElement(
0217: memberSelectPath);
0218: } else {
0219: elm = null;
0220: }
0221: } else {
0222: if (currentPath != null) {
0223: TreePath methodInvokePath = TreePath.getPath(
0224: currentPath, arg0);
0225: if (methodInvokePath == null)
0226: methodInvokePath = currentPath;
0227: elm = evaluationContext.getTrees().getElement(
0228: methodInvokePath);
0229: methodName = elm.getSimpleName().toString();
0230: } else {
0231: elm = null;
0232: methodName = expression.toString();
0233: }
0234: }
0235: List<? extends TypeMirror> paramTypes = null;
0236: String enclosingClass = null;
0237: if (elm != null) {
0238: TypeMirror typeMirror = elm.asType();
0239: TypeKind kind = typeMirror.getKind();
0240: if (kind == TypeKind.ERROR) { // In case of error type resolution we do not know parameter types
0241: elm = null;
0242: } else {
0243: if (kind != TypeKind.EXECUTABLE) {
0244: Assert2.error(arg0, "noSuchMethod", elm
0245: .getSimpleName().toString(), elm
0246: .getEnclosingElement().getSimpleName()
0247: .toString());
0248: }
0249: ExecutableElement methodElement = (ExecutableElement) elm;
0250: ExecutableType execTypeMirror = (ExecutableType) typeMirror;
0251: paramTypes = execTypeMirror.getParameterTypes();
0252: isStatic = methodElement.getModifiers().contains(
0253: Modifier.STATIC);
0254: Element enclosing = methodElement.getEnclosingElement();
0255: if (enclosing.getKind() == ElementKind.CLASS) {
0256: TypeElement enclosingClassElement = (TypeElement) enclosing;
0257: enclosingClass = ElementUtilities
0258: .getBinaryName(enclosingClassElement);
0259: }
0260: }
0261: }
0262:
0263: List<? extends ExpressionTree> args = arg0.getArguments();
0264: List<Value> argVals = new ArrayList<Value>(args.size());
0265: for (ExpressionTree arg : args) {
0266: Mirror argValue = arg.accept(this , evaluationContext);
0267: if (!(argValue instanceof Value)) {
0268: Assert2.error(arg, "Not a value");
0269: }
0270: argVals.add((Value) argValue);
0271: }
0272: List<Type> argTypes = null;
0273: if (elm == null) {
0274: argTypes = new ArrayList<Type>(argVals.size());
0275: for (Value value : argVals) {
0276: if (value == null) {
0277: argTypes.add(evaluationContext.getDebugger()
0278: .getVirtualMachine().classesByName(
0279: "java.lang.Object").get(0));
0280: } else {
0281: argTypes.add(value.type());
0282: }
0283: }
0284: }
0285: ObjectReference objectReference;
0286: ReferenceType type;
0287: if (isStatic == null) {
0288: if (object instanceof ClassType
0289: || object instanceof ArrayType) {
0290: type = (ReferenceType) object;
0291: objectReference = null;
0292: isStatic = Boolean.TRUE;
0293: } else if (object instanceof ObjectReference) {
0294: objectReference = (ObjectReference) object;
0295: type = (ReferenceType) objectReference.type();
0296: } else {
0297: objectReference = evaluationContext.getFrame()
0298: .this Object();
0299: type = (ReferenceType) evaluationContext.getFrame()
0300: .location().declaringType();
0301: }
0302: } else if (isStatic) {
0303: objectReference = null;
0304: if (object instanceof ClassType
0305: || object instanceof ArrayType) {
0306: type = (ReferenceType) object;
0307: } else if (object instanceof ObjectReference) {
0308: type = (ReferenceType) ((ObjectReference) object)
0309: .type();
0310: } else {
0311: type = evaluationContext.getFrame().location()
0312: .declaringType();
0313: if (enclosingClass != null) {
0314: ReferenceType dt = findEnclosingType(type,
0315: enclosingClass);
0316: if (dt != null)
0317: type = dt;
0318: }
0319: }
0320: } else {
0321: if (object != null) {
0322: objectReference = (ObjectReference) object;
0323: type = objectReference.referenceType();
0324: } else {
0325: objectReference = evaluationContext.getFrame()
0326: .this Object();
0327: type = evaluationContext.getFrame().location()
0328: .declaringType();
0329: if (enclosingClass != null) {
0330: ReferenceType dt = findEnclosingType(type,
0331: enclosingClass);
0332: if (dt != null)
0333: type = dt;
0334: }
0335: }
0336: if (objectReference == null) {
0337: Assert2.error(arg0, "methodCallOnNull", methodName);
0338: }
0339: }
0340: ClassType cType;
0341: if (type instanceof ArrayType) {
0342: Assert2.error(arg0, "methOnArray");
0343: return null;
0344: } else {
0345: cType = (ClassType) type;
0346: }
0347: Method method = getConcreteMethodAndReportProblems(arg0, type,
0348: methodName, null, paramTypes, argTypes);
0349: return invokeMethod(arg0, method, isStatic, cType,
0350: objectReference, argVals, evaluationContext);
0351: }
0352:
0353: /*private Method getConcreteMethod(ReferenceType type, String methodName, List<? extends ExpressionTree> typeArguments) {
0354: List<Method> methods = type.methodsByName(methodName);
0355: String signature = createSignature(typeArguments);
0356: for (Method method : methods) {
0357: if (egualMethodSignatures(method.signature(), signature)) {
0358: return method;
0359: }
0360: }
0361: return null;
0362: }*/
0363:
0364: private static Method getConcreteMethodAndReportProblems(Tree arg0,
0365: ReferenceType type, String methodName,
0366: String firstParamSignature,
0367: List<? extends TypeMirror> paramTypes,
0368: List<? extends Type> argTypes) {
0369: Method method;
0370: try {
0371: if (paramTypes != null) {
0372: method = getConcreteMethod(type, methodName,
0373: firstParamSignature, paramTypes);
0374: } else {
0375: method = getConcreteMethod2(type, methodName, argTypes);
0376: }
0377: } catch (UnsuitableArgumentsException uaex) {
0378: StringBuilder methodArgs = new StringBuilder("(");
0379: if (paramTypes != null) {
0380: for (TypeMirror paramType : paramTypes) {
0381: if (methodArgs.length() > 1)
0382: methodArgs.append(", ");
0383: methodArgs.append(paramType.toString());
0384: }
0385: } else {
0386: for (Type argType : argTypes) {
0387: if (methodArgs.length() > 1)
0388: methodArgs.append(", ");
0389: methodArgs.append(argType.name());
0390: }
0391: }
0392: methodArgs.append(")");
0393: if ("<init>".equals(methodName)) {
0394: Assert2.error(arg0, "noSuchConstructorWithArgs", type
0395: .name(), methodArgs.toString());
0396: }
0397: if (methodArgs.length() == 2) {
0398: Assert2.error(arg0, "noSuchMethod", methodName
0399: + methodArgs, type.name());
0400: } else {
0401: Assert2.error(arg0, "noSuchMethodWithArgs", methodName,
0402: type.name(), methodArgs.toString());
0403: }
0404: method = null;
0405: }
0406: if (method == null) {
0407: Assert2
0408: .error(arg0, "noSuchMethod", methodName, type
0409: .name());
0410: }
0411: return method;
0412: }
0413:
0414: private static Method getConcreteMethod(ReferenceType type,
0415: String methodName, List<? extends TypeMirror> typeArguments)
0416: throws UnsuitableArgumentsException {
0417: return getConcreteMethod(type, methodName, null, typeArguments);
0418: }
0419:
0420: private static Method getConcreteMethod(ReferenceType type,
0421: String methodName, String firstParamSignature,
0422: List<? extends TypeMirror> typeArguments)
0423: throws UnsuitableArgumentsException {
0424: List<Method> methods = type.methodsByName(methodName);
0425: String signature = createSignature(firstParamSignature,
0426: typeArguments);
0427: boolean constructor = "<init>".equals(methodName);
0428: for (Method method : methods) {
0429: if (!method.isAbstract()
0430: && (!constructor || type.equals(method
0431: .declaringType()))
0432: && egualMethodSignatures(method.signature(),
0433: signature)) {
0434: return method;
0435: }
0436: }
0437: if (methods.size() > 0)
0438: throw new UnsuitableArgumentsException();
0439: return null;
0440: }
0441:
0442: private static Method getConcreteMethod2(ReferenceType type,
0443: String methodName, List<? extends Type> typeArguments)
0444: throws UnsuitableArgumentsException {
0445: List<Method> methods = type.methodsByName(methodName);
0446: List<Method> possibleMethods = new ArrayList<Method>();
0447: boolean constructor = "<init>".equals(methodName);
0448: for (Method method : methods) {
0449: if (!method.isAbstract()
0450: && (!constructor || type.equals(method
0451: .declaringType()))) {
0452: try {
0453: if (equalTypes(method.argumentTypes(),
0454: typeArguments)) {
0455: return method;
0456: }
0457: if (acceptTypes(method.argumentTypes(),
0458: typeArguments)) {
0459: possibleMethods.add(method);
0460: }
0461: } catch (ClassNotLoadedException ex) {
0462: // Ignore
0463: } catch (ObjectCollectedException ocex) {
0464: // What can we do?
0465: }
0466: }
0467: }
0468: if (possibleMethods.size() == 0) {
0469: if (methods.size() > 0)
0470: throw new UnsuitableArgumentsException();
0471: return null;
0472: }
0473: return possibleMethods.get(0);
0474: }
0475:
0476: private static boolean equalTypes(List<? extends Type> methodTypes,
0477: List<? extends Type> argumentTypes) {
0478: if (methodTypes.size() != argumentTypes.size()) {
0479: return false;
0480: }
0481: int n = methodTypes.size();
0482: for (int i = 0; i < n; i++) {
0483: if (!methodTypes.get(i).equals(argumentTypes.get(i))
0484: && !unboxType(methodTypes.get(i)).equals(
0485: unboxType(argumentTypes.get(i)))) {
0486: return false;
0487: }
0488: }
0489: return true;
0490: }
0491:
0492: private static boolean acceptTypes(
0493: List<? extends Type> methodTypes,
0494: List<? extends Type> argumentTypes) {
0495: if (methodTypes.size() != argumentTypes.size()) {
0496: return false;
0497: }
0498: int n = methodTypes.size();
0499: for (int i = 0; i < n; i++) {
0500: Type methodType = unboxType(methodTypes.get(i));
0501: Type argType = unboxType(argumentTypes.get(i));
0502: if (!methodType.equals(argType)) {
0503: if (!extendsType(argType, methodType)) {
0504: return false;
0505: }
0506: }
0507: }
0508: return true;
0509: }
0510:
0511: private static boolean extendsType(Type argType, Type methodType) {
0512: if (methodType instanceof ReferenceType
0513: && argType instanceof ReferenceType) {
0514: return extendsType((ReferenceType) argType,
0515: (ReferenceType) methodType);
0516: } else if (methodType instanceof PrimitiveType
0517: && argType instanceof PrimitiveType) {
0518: return extendsType((PrimitiveType) argType,
0519: (PrimitiveType) methodType);
0520: }
0521: return false;
0522: }
0523:
0524: /** @return true if t1 extends t2 */
0525: private static boolean extendsType(ReferenceType t1,
0526: ReferenceType t2) {
0527: if (t2 instanceof InterfaceType) {
0528: List<InterfaceType> super Interfaces;
0529: if (t1 instanceof ClassType) {
0530: super Interfaces = ((ClassType) t1).allInterfaces();
0531: } else if (t1 instanceof InterfaceType) {
0532: super Interfaces = ((InterfaceType) t1)
0533: .super interfaces();
0534: } else {
0535: return false;
0536: }
0537: return super Interfaces.contains(t2);
0538: }
0539: if (t2 instanceof ClassType) {
0540: if (t1 instanceof ClassType) {
0541: ClassType super Class = ((ClassType) t1).super class();
0542: if (super Class != null) {
0543: if (super Class.equals(t2))
0544: return true;
0545: else
0546: return extendsType(super Class, t2);
0547: } else {
0548: return false;
0549: }
0550: } else {
0551: return false;
0552: }
0553: }
0554: if (t2 instanceof ArrayType) {
0555: if (t1 instanceof ArrayType) {
0556: try {
0557: Type ct1 = ((ArrayType) t1).componentType();
0558: Type ct2 = ((ArrayType) t2).componentType();
0559: return extendsType(ct1, ct2);
0560: } catch (ClassNotLoadedException cnlex) {
0561: return false;
0562: }
0563: } else {
0564: return false;
0565: }
0566: } else {
0567: throw new IllegalStateException("Unknown ReferenceType: "
0568: + t2);
0569: }
0570: }
0571:
0572: /** @return true if t2 is an extension of t1 */
0573: private static boolean extendsType(PrimitiveType t1,
0574: PrimitiveType t2) {
0575: // BooleanType, ByteType and CharType can be matched together only.
0576: if (t2 instanceof ShortType) {
0577: return t2 instanceof ByteType || t2 instanceof ShortType;
0578: }
0579: if (t2 instanceof IntegerType) {
0580: return t2 instanceof ByteType || t2 instanceof ShortType
0581: || t2 instanceof IntegerType;
0582: }
0583: if (t2 instanceof LongType) {
0584: return t2 instanceof ByteType || t2 instanceof ShortType
0585: || t2 instanceof IntegerType
0586: || t2 instanceof LongType;
0587: }
0588: if (t2 instanceof FloatType) {
0589: return !(t2 instanceof BooleanType
0590: || t2 instanceof CharType || t2 instanceof DoubleType);
0591: }
0592: if (t2 instanceof DoubleType) {
0593: return !(t2 instanceof BooleanType || t2 instanceof CharType);
0594: }
0595: return false;
0596: }
0597:
0598: private static Type unboxType(Type t) {
0599: if (t instanceof ClassType) {
0600: String name = ((ClassType) t).name();
0601: if (name.equals("java.lang.Boolean")) {
0602: t = t.virtualMachine().mirrorOf(true).type();
0603: } else if (name.equals("java.lang.Byte")) {
0604: t = t.virtualMachine().mirrorOf((byte) 10).type();
0605: } else if (name.equals("java.lang.Character")) {
0606: t = t.virtualMachine().mirrorOf('a').type();
0607: } else if (name.equals("java.lang.Integer")) {
0608: t = t.virtualMachine().mirrorOf(10).type();
0609: } else if (name.equals("java.lang.Long")) {
0610: t = t.virtualMachine().mirrorOf(10l).type();
0611: } else if (name.equals("java.lang.Short")) {
0612: t = t.virtualMachine().mirrorOf((short) 10).type();
0613: } else if (name.equals("java.lang.Float")) {
0614: t = t.virtualMachine().mirrorOf(10f).type();
0615: } else if (name.equals("java.lang.Double")) {
0616: t = t.virtualMachine().mirrorOf(10.0).type();
0617: }
0618: }
0619: return t;
0620: }
0621:
0622: private static boolean egualMethodSignatures(String s1, String s2) {
0623: int i = s1.lastIndexOf(")");
0624: if (i > 0)
0625: s1 = s1.substring(0, i);
0626: i = s2.lastIndexOf(")");
0627: if (i > 0)
0628: s2 = s2.substring(0, i);
0629: return s1.equals(s2);
0630: }
0631:
0632: private static String createSignature(String firstParamSignature,
0633: List<? extends TypeMirror> typeArguments) {
0634: StringBuilder signature = new StringBuilder("(");
0635: if (firstParamSignature != null) {
0636: signature.append(firstParamSignature);
0637: }
0638: for (TypeMirror param : typeArguments) {
0639: String paramType = getTypeName(param);//getSimpleName().toString();
0640: signature.append(getSignature(paramType));
0641: }
0642: signature.append(')');
0643: //String returnType = elm.getReturnType().toString();
0644: //signature.append(getSignature(returnType));
0645: return signature.toString();
0646: }
0647:
0648: private static String getTypeName(TypeMirror type) {
0649: if (type.getKind() == TypeKind.ARRAY) {
0650: return getTypeName(((javax.lang.model.type.ArrayType) type)
0651: .getComponentType())
0652: + "[]";
0653: }
0654: if (type.getKind() == TypeKind.TYPEVAR) {
0655: TypeVariable tv = (TypeVariable) type;
0656: return getTypeName(tv.getUpperBound());
0657: }
0658: if (type.getKind() == TypeKind.DECLARED) {
0659: return ((DeclaredType) type).asElement().toString();
0660: }
0661: return type.toString();
0662: }
0663:
0664: private static String getSignature(String javaType) {
0665: if (javaType.equals("boolean")) {
0666: return "Z";
0667: } else if (javaType.equals("byte")) {
0668: return "B";
0669: } else if (javaType.equals("char")) {
0670: return "C";
0671: } else if (javaType.equals("short")) {
0672: return "S";
0673: } else if (javaType.equals("int")) {
0674: return "I";
0675: } else if (javaType.equals("long")) {
0676: return "J";
0677: } else if (javaType.equals("float")) {
0678: return "F";
0679: } else if (javaType.equals("double")) {
0680: return "D";
0681: } else if (javaType.endsWith("[]")) {
0682: return "["
0683: + getSignature(javaType.substring(0, javaType
0684: .length() - 2));
0685: } else {
0686: return "L" + javaType.replace('.', '/') + ";";
0687: }
0688: }
0689:
0690: private static ReferenceType getClassType(Tree tree,
0691: TypeMirror type, EvaluationContext evaluationContext) {
0692: String className = ElementUtilities
0693: .getBinaryName((TypeElement) ((DeclaredType) type)
0694: .asElement());
0695: VirtualMachine vm = evaluationContext.getDebugger()
0696: .getVirtualMachine();
0697: List<ReferenceType> classes = vm.classesByName(className);
0698: if (classes.size() == 0) {
0699: Assert2.error(tree, "unknownType", className);
0700: }
0701: return classes.get(0);
0702: }
0703:
0704: private boolean instanceOf(Type left, Type right) {
0705: if (left == null)
0706: return false;
0707: if (left.equals(right))
0708: return true;
0709:
0710: if (right instanceof ArrayType) {
0711: if (!(left instanceof ArrayType)) {
0712: return false;
0713: } else {
0714: ArrayType leftArray = (ArrayType) left;
0715: ArrayType rightArray = (ArrayType) right;
0716: Type leftType;
0717: Type rightType;
0718: try {
0719: leftType = leftArray.componentType();
0720: rightType = rightArray.componentType();
0721: } catch (ClassNotLoadedException e) {
0722: // TODO: load missing classes
0723: return false;
0724: }
0725: return instanceOf(leftType, rightType);
0726: }
0727: }
0728:
0729: if (left instanceof ClassType) {
0730: ClassType classLeft = (ClassType) left;
0731: if (right instanceof InterfaceType) {
0732: List<InterfaceType> ifaces = classLeft.allInterfaces();
0733: for (Iterator<InterfaceType> i = ifaces.iterator(); i
0734: .hasNext();) {
0735: InterfaceType type = i.next();
0736: if (type.equals(right))
0737: return true;
0738: }
0739: return false;
0740: } else { // right instanceof ClassType
0741: for (;;) {
0742: classLeft = classLeft.super class();
0743: if (classLeft == null)
0744: return false;
0745: if (classLeft.equals(right))
0746: return true;
0747: }
0748: }
0749: }
0750:
0751: if (left instanceof InterfaceType) {
0752: InterfaceType intLeft = (InterfaceType) left;
0753: if (right instanceof InterfaceType) {
0754: List<InterfaceType> ifaces = intLeft.super interfaces();
0755: for (Iterator<InterfaceType> i = ifaces.iterator(); i
0756: .hasNext();) {
0757: InterfaceType type = i.next();
0758: if (type.equals(right))
0759: return true;
0760: }
0761: return false;
0762: }
0763: }
0764:
0765: return false;
0766: }
0767:
0768: @Override
0769: public Mirror visitAssert(AssertTree arg0,
0770: EvaluationContext evaluationContext) {
0771: Assert2.error(arg0, "unsupported");
0772: return null;
0773: }
0774:
0775: @Override
0776: public Mirror visitAssignment(AssignmentTree arg0,
0777: EvaluationContext evaluationContext) {
0778: Mirror var = arg0.getVariable().accept(this , evaluationContext);
0779: Mirror exp = arg0.getExpression().accept(this ,
0780: evaluationContext);
0781: VirtualMachine vm = evaluationContext.getDebugger()
0782: .getVirtualMachine();
0783: Value value = (Value) exp;
0784: setToMirror(arg0.getVariable(), value, evaluationContext);
0785: return value;
0786: }
0787:
0788: @Override
0789: public Mirror visitCompoundAssignment(CompoundAssignmentTree arg0,
0790: EvaluationContext evaluationContext) {
0791: Mirror var = arg0.getVariable().accept(this , evaluationContext);
0792: Mirror exp = arg0.getExpression().accept(this ,
0793: evaluationContext);
0794: VirtualMachine vm = evaluationContext.getDebugger()
0795: .getVirtualMachine();
0796: Tree.Kind kind = arg0.getKind();
0797: if (var instanceof BooleanValue) {
0798: boolean v = ((BooleanValue) var).value();
0799: boolean e = ((BooleanValue) exp).value();
0800: switch (kind) {
0801: case AND_ASSIGNMENT:
0802: v &= e;
0803: break;
0804: case OR_ASSIGNMENT:
0805: v |= e;
0806: break;
0807: case XOR_ASSIGNMENT:
0808: v ^= e;
0809: break;
0810: default:
0811: throw new IllegalStateException("Unknown assignment: "
0812: + kind + " of " + arg0);
0813: }
0814: Value value = vm.mirrorOf(v);
0815: setToMirror(arg0.getVariable(), value, evaluationContext);
0816: return value;
0817: }
0818: if (var instanceof DoubleValue) {
0819: double v = ((DoubleValue) var).value();
0820: double e = ((PrimitiveValue) exp).doubleValue();
0821: switch (kind) {
0822: case DIVIDE_ASSIGNMENT:
0823: v /= e;
0824: break;
0825: case MINUS_ASSIGNMENT:
0826: v -= e;
0827: break;
0828: case MULTIPLY_ASSIGNMENT:
0829: v *= e;
0830: break;
0831: case PLUS_ASSIGNMENT:
0832: v += e;
0833: break;
0834: default:
0835: throw new IllegalStateException("Unknown assignment: "
0836: + kind + " of " + arg0);
0837: }
0838: Value value = vm.mirrorOf(v);
0839: setToMirror(arg0.getVariable(), value, evaluationContext);
0840: return value;
0841: }
0842: if (var instanceof FloatValue) {
0843: float v = ((FloatValue) var).value();
0844: float e = ((PrimitiveValue) exp).floatValue();
0845: switch (kind) {
0846: case DIVIDE_ASSIGNMENT:
0847: v /= e;
0848: break;
0849: case MINUS_ASSIGNMENT:
0850: v -= e;
0851: break;
0852: case MULTIPLY_ASSIGNMENT:
0853: v *= e;
0854: break;
0855: case PLUS_ASSIGNMENT:
0856: v += e;
0857: break;
0858: default:
0859: throw new IllegalStateException("Unknown assignment: "
0860: + kind + " of " + arg0);
0861: }
0862: Value value = vm.mirrorOf(v);
0863: setToMirror(arg0.getVariable(), value, evaluationContext);
0864: return value;
0865: }
0866: if (var instanceof LongValue) {
0867: long v = ((LongValue) var).value();
0868: long e = ((PrimitiveValue) exp).longValue();
0869: switch (kind) {
0870: case AND_ASSIGNMENT:
0871: v &= e;
0872: break;
0873: case DIVIDE_ASSIGNMENT:
0874: v /= e;
0875: break;
0876: case LEFT_SHIFT_ASSIGNMENT:
0877: v <<= e;
0878: break;
0879: case MINUS_ASSIGNMENT:
0880: v -= e;
0881: break;
0882: case MULTIPLY_ASSIGNMENT:
0883: v *= e;
0884: break;
0885: case OR_ASSIGNMENT:
0886: v |= e;
0887: break;
0888: case PLUS_ASSIGNMENT:
0889: v += e;
0890: break;
0891: case REMAINDER_ASSIGNMENT:
0892: v %= e;
0893: break;
0894: case RIGHT_SHIFT_ASSIGNMENT:
0895: v >>= e;
0896: break;
0897: case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT:
0898: v >>>= e;
0899: break;
0900: case XOR_ASSIGNMENT:
0901: v ^= e;
0902: break;
0903: default:
0904: throw new IllegalStateException("Unknown assignment: "
0905: + kind + " of " + arg0);
0906: }
0907: Value value = vm.mirrorOf(v);
0908: setToMirror(arg0.getVariable(), value, evaluationContext);
0909: return value;
0910: }
0911: if (var instanceof IntegerValue) {
0912: int v = ((IntegerValue) var).value();
0913: int e = ((PrimitiveValue) exp).intValue();
0914: switch (kind) {
0915: case AND_ASSIGNMENT:
0916: v &= e;
0917: break;
0918: case DIVIDE_ASSIGNMENT:
0919: v /= e;
0920: break;
0921: case LEFT_SHIFT_ASSIGNMENT:
0922: v <<= e;
0923: break;
0924: case MINUS_ASSIGNMENT:
0925: v -= e;
0926: break;
0927: case MULTIPLY_ASSIGNMENT:
0928: v *= e;
0929: break;
0930: case OR_ASSIGNMENT:
0931: v |= e;
0932: break;
0933: case PLUS_ASSIGNMENT:
0934: v += e;
0935: break;
0936: case REMAINDER_ASSIGNMENT:
0937: v %= e;
0938: break;
0939: case RIGHT_SHIFT_ASSIGNMENT:
0940: v >>= e;
0941: break;
0942: case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT:
0943: v >>>= e;
0944: break;
0945: case XOR_ASSIGNMENT:
0946: v ^= e;
0947: break;
0948: default:
0949: throw new IllegalStateException("Unknown assignment: "
0950: + kind + " of " + arg0);
0951: }
0952: Value value = vm.mirrorOf(v);
0953: setToMirror(arg0.getVariable(), value, evaluationContext);
0954: return value;
0955: }
0956: if (var instanceof StringReference) {
0957: String v = ((StringReference) var).value();
0958: String e = ((StringReference) exp).value();
0959: switch (kind) {
0960: case PLUS_ASSIGNMENT:
0961: v += e;
0962: break;
0963: default:
0964: throw new IllegalStateException("Unknown assignment: "
0965: + kind + " of " + arg0);
0966: }
0967: Value value = vm.mirrorOf(v);
0968: setToMirror(arg0.getVariable(), value, evaluationContext);
0969: return value;
0970: }
0971: throw new IllegalStateException("Unknown assignment var type: "
0972: + var);
0973: }
0974:
0975: @Override
0976: public Mirror visitBinary(BinaryTree arg0,
0977: EvaluationContext evaluationContext) {
0978: Mirror left = arg0.getLeftOperand().accept(this ,
0979: evaluationContext);
0980: Mirror right = arg0.getRightOperand().accept(this ,
0981: evaluationContext);
0982: VirtualMachine vm = evaluationContext.getDebugger()
0983: .getVirtualMachine();
0984: Tree.Kind kind = arg0.getKind();
0985: if (left instanceof ObjectReference) {
0986: left = unboxIfCan(arg0, (ObjectReference) left,
0987: evaluationContext);
0988: }
0989: if (right instanceof ObjectReference) {
0990: right = unboxIfCan(arg0, (ObjectReference) right,
0991: evaluationContext);
0992: }
0993: if ((left instanceof BooleanValue)
0994: && (right instanceof BooleanValue)) {
0995: boolean op1 = ((BooleanValue) left).booleanValue();
0996: boolean op2 = ((BooleanValue) right).booleanValue();
0997: boolean res;
0998: switch (kind) {
0999: case AND:
1000: res = op1 & op2;
1001: break;
1002: case CONDITIONAL_AND:
1003: res = op1 && op2;
1004: break;
1005: case CONDITIONAL_OR:
1006: res = op1 || op2;
1007: break;
1008: case EQUAL_TO:
1009: res = op1 == op2;
1010: break;
1011: case NOT_EQUAL_TO:
1012: res = op1 != op2;
1013: break;
1014: case OR:
1015: res = op1 | op2;
1016: break;
1017: case XOR:
1018: res = op1 ^ op2;
1019: break;
1020: default:
1021: throw new IllegalArgumentException(
1022: "Unhandled binary tree: " + arg0);
1023: }
1024: return vm.mirrorOf(res);
1025: }
1026: boolean isLeftNumeric = left instanceof PrimitiveValue
1027: && !(left instanceof BooleanValue);
1028: boolean isRightNumeric = right instanceof PrimitiveValue
1029: && !(right instanceof BooleanValue);
1030: if (isLeftNumeric && isRightNumeric) {
1031: if ((left instanceof DoubleValue)
1032: || (right instanceof DoubleValue)) {
1033: double l = ((PrimitiveValue) left).doubleValue();
1034: double r = ((PrimitiveValue) right).doubleValue();
1035: double v = 0.;
1036: boolean b = false;
1037: boolean isBoolean = true;
1038: switch (kind) {
1039: case DIVIDE:
1040: v = l / r;
1041: isBoolean = false;
1042: break;
1043: case MINUS:
1044: v = l - r;
1045: isBoolean = false;
1046: break;
1047: case MULTIPLY:
1048: v = l * r;
1049: isBoolean = false;
1050: break;
1051: case PLUS:
1052: v = l + r;
1053: isBoolean = false;
1054: break;
1055: case EQUAL_TO:
1056: b = l == r;
1057: break;
1058: case GREATER_THAN:
1059: b = l > r;
1060: break;
1061: case GREATER_THAN_EQUAL:
1062: b = l >= r;
1063: break;
1064: case LESS_THAN:
1065: b = l < r;
1066: break;
1067: case LESS_THAN_EQUAL:
1068: b = l <= r;
1069: break;
1070: case NOT_EQUAL_TO:
1071: b = l != r;
1072: break;
1073: default:
1074: throw new IllegalStateException(
1075: "Unhandled binary tree: " + arg0);
1076: }
1077: if (isBoolean) {
1078: return vm.mirrorOf(b);
1079: } else {
1080: return vm.mirrorOf(v);
1081: }
1082: }
1083: if ((left instanceof FloatValue)
1084: || (right instanceof FloatValue)) {
1085: float l = ((PrimitiveValue) left).floatValue();
1086: float r = ((PrimitiveValue) right).floatValue();
1087: float v = 0.f;
1088: boolean b = false;
1089: boolean isBoolean = true;
1090: switch (kind) {
1091: case DIVIDE:
1092: v = l / r;
1093: isBoolean = false;
1094: break;
1095: case MINUS:
1096: v = l - r;
1097: isBoolean = false;
1098: break;
1099: case MULTIPLY:
1100: v = l * r;
1101: isBoolean = false;
1102: break;
1103: case PLUS:
1104: v = l + r;
1105: isBoolean = false;
1106: break;
1107: case EQUAL_TO:
1108: b = l == r;
1109: break;
1110: case GREATER_THAN:
1111: b = l > r;
1112: break;
1113: case GREATER_THAN_EQUAL:
1114: b = l >= r;
1115: break;
1116: case LESS_THAN:
1117: b = l < r;
1118: break;
1119: case LESS_THAN_EQUAL:
1120: b = l <= r;
1121: break;
1122: case NOT_EQUAL_TO:
1123: b = l != r;
1124: break;
1125: default:
1126: throw new IllegalStateException(
1127: "Unhandled binary tree: " + arg0);
1128: }
1129: if (isBoolean) {
1130: return vm.mirrorOf(b);
1131: } else {
1132: return vm.mirrorOf(v);
1133: }
1134: }
1135: if ((left instanceof LongValue)
1136: || (right instanceof LongValue)) {
1137: long l = ((PrimitiveValue) left).longValue();
1138: long r = ((PrimitiveValue) right).longValue();
1139: long v = 0l;
1140: boolean b = false;
1141: boolean isBoolean = false;
1142: switch (kind) {
1143: case DIVIDE:
1144: v = l / r;
1145: break;
1146: case MINUS:
1147: v = l - r;
1148: break;
1149: case MULTIPLY:
1150: v = l * r;
1151: break;
1152: case PLUS:
1153: v = l + r;
1154: break;
1155: case REMAINDER:
1156: v = l % r;
1157: break;
1158: case LEFT_SHIFT:
1159: v = l << r;
1160: break;
1161: case RIGHT_SHIFT:
1162: v = l >> r;
1163: break;
1164: case UNSIGNED_RIGHT_SHIFT:
1165: v = l >>> r;
1166: break;
1167: case AND:
1168: v = l & r;
1169: break;
1170: case OR:
1171: v = l | r;
1172: break;
1173: case XOR:
1174: v = l ^ r;
1175: break;
1176: case EQUAL_TO:
1177: b = l == r;
1178: isBoolean = true;
1179: break;
1180: case GREATER_THAN:
1181: b = l > r;
1182: isBoolean = true;
1183: break;
1184: case GREATER_THAN_EQUAL:
1185: b = l >= r;
1186: isBoolean = true;
1187: break;
1188: case LESS_THAN:
1189: b = l < r;
1190: isBoolean = true;
1191: break;
1192: case LESS_THAN_EQUAL:
1193: b = l <= r;
1194: isBoolean = true;
1195: break;
1196: case NOT_EQUAL_TO:
1197: b = l != r;
1198: isBoolean = true;
1199: break;
1200: default:
1201: throw new IllegalStateException(
1202: "Unhandled binary tree: " + arg0);
1203: }
1204: if (isBoolean) {
1205: return vm.mirrorOf(b);
1206: } else {
1207: return vm.mirrorOf(v);
1208: }
1209: }
1210: //if ((left instanceof IntegerValue) || (right instanceof IntegerValue)) {
1211: // int, short, char and byte - operations have int result
1212: int l = ((PrimitiveValue) left).intValue();
1213: int r = ((PrimitiveValue) right).intValue();
1214: int v = 0;
1215: boolean b = false;
1216: boolean isBoolean = false;
1217: switch (kind) {
1218: case DIVIDE:
1219: v = l / r;
1220: break;
1221: case MINUS:
1222: v = l - r;
1223: break;
1224: case MULTIPLY:
1225: v = l * r;
1226: break;
1227: case PLUS:
1228: v = l + r;
1229: break;
1230: case REMAINDER:
1231: v = l % r;
1232: break;
1233: case LEFT_SHIFT:
1234: v = l << r;
1235: break;
1236: case RIGHT_SHIFT:
1237: v = l >> r;
1238: break;
1239: case UNSIGNED_RIGHT_SHIFT:
1240: v = l >>> r;
1241: break;
1242: case AND:
1243: v = l & r;
1244: break;
1245: case OR:
1246: v = l | r;
1247: break;
1248: case XOR:
1249: v = l ^ r;
1250: break;
1251: case EQUAL_TO:
1252: b = l == r;
1253: isBoolean = true;
1254: break;
1255: case GREATER_THAN:
1256: b = l > r;
1257: isBoolean = true;
1258: break;
1259: case GREATER_THAN_EQUAL:
1260: b = l >= r;
1261: isBoolean = true;
1262: break;
1263: case LESS_THAN:
1264: b = l < r;
1265: isBoolean = true;
1266: break;
1267: case LESS_THAN_EQUAL:
1268: b = l <= r;
1269: isBoolean = true;
1270: break;
1271: case NOT_EQUAL_TO:
1272: b = l != r;
1273: isBoolean = true;
1274: break;
1275: default:
1276: throw new IllegalStateException(
1277: "Unhandled binary tree: " + arg0);
1278: }
1279: if (isBoolean) {
1280: return vm.mirrorOf(b);
1281: } else {
1282: return vm.mirrorOf(v);
1283: }
1284: //}
1285: }
1286: if (((left == null || left instanceof StringReference) && (right == null || right instanceof StringReference))
1287: && kind == Tree.Kind.PLUS) {
1288: String s1 = (left == null) ? null
1289: : ((StringReference) left).value();
1290: String s2 = (right == null) ? null
1291: : ((StringReference) right).value();
1292: switch (kind) {
1293: case PLUS:
1294: return vm.mirrorOf(s1 + s2);
1295: default:
1296: throw new IllegalStateException(
1297: "Unhandled binary tree: " + arg0);
1298: }
1299: }
1300: if ((left instanceof StringReference || right instanceof StringReference)
1301: && kind == Tree.Kind.PLUS) {
1302: String s1 = (left instanceof StringReference) ? ((StringReference) left)
1303: .value()
1304: : toString(arg0, left, evaluationContext);
1305: String s2 = (right instanceof StringReference) ? ((StringReference) right)
1306: .value()
1307: : toString(arg0, right, evaluationContext);
1308: return vm.mirrorOf(s1 + s2);
1309: }
1310: switch (kind) {
1311: case EQUAL_TO:
1312: return vm.mirrorOf(left == right
1313: || (left != null && left.equals(right)));
1314: case NOT_EQUAL_TO:
1315: return vm.mirrorOf(left == null && right != null
1316: || (left != null && !left.equals(right)));
1317: default:
1318: throw new IllegalStateException("Unhandled binary tree: "
1319: + arg0);
1320: }
1321: }
1322:
1323: @Override
1324: public Mirror visitBlock(BlockTree arg0,
1325: EvaluationContext evaluationContext) {
1326: Assert2.error(arg0, "unsupported");
1327: return null;
1328: }
1329:
1330: @Override
1331: public Mirror visitBreak(BreakTree arg0,
1332: EvaluationContext evaluationContext) {
1333: Assert2.error(arg0, "unsupported");
1334: return null;
1335: }
1336:
1337: @Override
1338: public Mirror visitCase(CaseTree arg0,
1339: EvaluationContext evaluationContext) {
1340: Assert2.error(arg0, "unsupported");
1341: return null;
1342: }
1343:
1344: @Override
1345: public Mirror visitCatch(CatchTree arg0,
1346: EvaluationContext evaluationContext) {
1347: Assert2.error(arg0, "unsupported");
1348: return null;
1349: }
1350:
1351: @Override
1352: public Mirror visitClass(ClassTree arg0,
1353: EvaluationContext evaluationContext) {
1354: Assert2.error(arg0, "unsupported");
1355: return null;
1356: }
1357:
1358: @Override
1359: public Mirror visitConditionalExpression(
1360: ConditionalExpressionTree arg0,
1361: EvaluationContext evaluationContext) {
1362: Mirror condition = arg0.getCondition().accept(this ,
1363: evaluationContext);
1364: if (!(condition instanceof BooleanValue)) {
1365: throw new IllegalStateException(
1366: "Condition must be boolean: " + arg0.getCondition());
1367: }
1368: boolean isTrue = ((BooleanValue) condition).value();
1369: if (isTrue) {
1370: return arg0.getTrueExpression().accept(this ,
1371: evaluationContext);
1372: } else {
1373: return arg0.getFalseExpression().accept(this ,
1374: evaluationContext);
1375: }
1376: }
1377:
1378: @Override
1379: public Mirror visitContinue(ContinueTree arg0,
1380: EvaluationContext evaluationContext) {
1381: Assert2.error(arg0, "unsupported");
1382: return null;
1383: }
1384:
1385: @Override
1386: public Mirror visitDoWhileLoop(DoWhileLoopTree arg0,
1387: EvaluationContext evaluationContext) {
1388: Assert2.error(arg0, "unsupported");
1389: return null;
1390: }
1391:
1392: @Override
1393: public Mirror visitErroneous(ErroneousTree arg0,
1394: EvaluationContext evaluationContext) {
1395: Assert2.error(arg0, "errorneous");
1396: return null;
1397: }
1398:
1399: @Override
1400: public Mirror visitExpressionStatement(
1401: ExpressionStatementTree arg0,
1402: EvaluationContext evaluationContext) {
1403: return arg0.getExpression().accept(this , evaluationContext);
1404: }
1405:
1406: @Override
1407: public Mirror visitEnhancedForLoop(EnhancedForLoopTree arg0,
1408: EvaluationContext evaluationContext) {
1409: Assert2.error(arg0, "unsupported");
1410: return null;
1411: }
1412:
1413: @Override
1414: public Mirror visitForLoop(ForLoopTree arg0,
1415: EvaluationContext evaluationContext) {
1416: Assert2.error(arg0, "unsupported");
1417: return null;
1418: }
1419:
1420: private Mirror getIdentifierByName(IdentifierTree arg0,
1421: EvaluationContext evaluationContext) {
1422: String name = arg0.getName().toString();
1423: VirtualMachine vm = evaluationContext.getDebugger()
1424: .getVirtualMachine();
1425: List<ReferenceType> classes = vm.classesByName(name);
1426: if (classes.size() > 0) {
1427: return classes.get(0);
1428: }
1429: // Class not found. If the source is not fully resolved, we may
1430: // get a field or local variable here:
1431: if (name.equals("this")) {
1432: return evaluationContext.getFrame().this Object();
1433: }
1434: if (name.equals("super")) {
1435: ReferenceType this Type = evaluationContext.getFrame()
1436: .location().declaringType();
1437: if (this Type instanceof ClassType) {
1438: ClassType super Class = ((ClassType) this Type)
1439: .super class();
1440: ObjectReference this Object = evaluationContext
1441: .getFrame().this Object();
1442: if (this Object == null) {
1443: return super Class;
1444: } else {
1445: return this Object;
1446: }
1447: }
1448: }
1449: Field field = evaluationContext.getFrame().location()
1450: .declaringType().fieldByName(name);
1451: if (field != null) {
1452: if (field.isStatic()) {
1453: evaluationContext.getVariables().put(arg0,
1454: new VariableInfo(field));
1455: return field.declaringType().getValue(field);
1456: }
1457: ObjectReference this Object = evaluationContext.getFrame()
1458: .this Object();
1459: if (this Object != null) {
1460: evaluationContext.getVariables().put(arg0,
1461: new VariableInfo(field, this Object));
1462: return this Object.getValue(field);
1463: }
1464: }
1465: try {
1466: LocalVariable lv = evaluationContext.getFrame()
1467: .visibleVariableByName(name);
1468: if (lv == null) {
1469: Assert2.error(arg0, "unknownVariable", name);
1470: }
1471: evaluationContext.getVariables().put(arg0,
1472: new VariableInfo(lv));
1473: return evaluationContext.getFrame().getValue(lv);
1474: } catch (AbsentInformationException aiex) {
1475: }
1476: Assert2.error(arg0, "unknownType", name);
1477: return null;
1478: }
1479:
1480: @Override
1481: public Mirror visitIdentifier(IdentifierTree arg0,
1482: EvaluationContext evaluationContext) {
1483: TreePath currentPath = getCurrentPath();
1484: Element elm = null;
1485: if (currentPath != null) {
1486: TreePath identifierPath = TreePath.getPath(currentPath,
1487: arg0);
1488: if (identifierPath == null)
1489: identifierPath = getCurrentPath();
1490: elm = evaluationContext.getTrees().getElement(
1491: identifierPath);
1492: if (elm instanceof TypeElement
1493: && ((TypeElement) elm).asType() instanceof ErrorType) {
1494: currentPath = null; // Elements not resolved correctly
1495: }
1496: }
1497: if (currentPath == null) {
1498: return getIdentifierByName(arg0, evaluationContext);
1499: }
1500: switch (elm.getKind()) {
1501: case CLASS:
1502: case ENUM:
1503: case INTERFACE:
1504: TypeElement te = (TypeElement) elm;
1505: String className = ElementUtilities.getBinaryName(te);
1506: VirtualMachine vm = evaluationContext.getDebugger()
1507: .getVirtualMachine();
1508: List<ReferenceType> classes = vm.classesByName(className);
1509: if (classes.size() > 0) {
1510: return classes.get(0);
1511: }
1512: Assert2.error(arg0, "unknownType", className);
1513: case ENUM_CONSTANT:
1514: VariableElement ve = (VariableElement) elm;
1515: String constantName = ve.getSimpleName().toString();
1516: ve.asType().toString();
1517: break;
1518: case FIELD:
1519: ve = (VariableElement) elm;
1520: String fieldName = ve.getSimpleName().toString();
1521: if (fieldName.equals("this")) {
1522: return evaluationContext.getFrame().this Object();
1523: }
1524: if (fieldName.equals("super")) {
1525: ReferenceType this Type = evaluationContext.getFrame()
1526: .location().declaringType();
1527: if (this Type instanceof ClassType) {
1528: ClassType super Class = ((ClassType) this Type)
1529: .super class();
1530: ObjectReference this Object = evaluationContext
1531: .getFrame().this Object();
1532: if (this Object == null) {
1533: return super Class;
1534: } else {
1535: return this Object;
1536: }
1537: }
1538: }
1539: Element enclosing = ve.getEnclosingElement();
1540: String enclosingClass = null;
1541: if (enclosing.getKind() == ElementKind.CLASS) {
1542: TypeElement enclosingClassElement = (TypeElement) enclosing;
1543: enclosingClass = ElementUtilities
1544: .getBinaryName(enclosingClassElement);
1545: }
1546: ReferenceType declaringType = evaluationContext.getFrame()
1547: .location().declaringType();
1548: if (enclosingClass != null) {
1549: ReferenceType dt = findEnclosingType(declaringType,
1550: enclosingClass);
1551: if (dt != null)
1552: declaringType = dt;
1553: }
1554: Field field = declaringType.fieldByName(fieldName);
1555: if (field == null) {
1556: Assert2.error(arg0, "unknownVariable", fieldName);
1557: }
1558: if (field.isStatic()) {
1559: evaluationContext.getVariables().put(arg0,
1560: new VariableInfo(field));
1561: return declaringType.getValue(field);
1562: }
1563: ObjectReference this Object = evaluationContext.getFrame()
1564: .this Object();
1565: if (this Object != null) {
1566: if (field.isPrivate()) {
1567: ObjectReference to = findEnclosedObject(this Object,
1568: declaringType);
1569: if (to != null)
1570: this Object = to;
1571: } else {
1572: if (!instanceOf(this Object.referenceType(),
1573: declaringType)) {
1574: ObjectReference to = findEnclosedObject(
1575: this Object, declaringType);
1576: if (to != null)
1577: this Object = to;
1578: }
1579: }
1580: evaluationContext.getVariables().put(arg0,
1581: new VariableInfo(field, this Object));
1582: return this Object.getValue(field);
1583: } else {
1584: Assert2.error(arg0,
1585: "accessInstanceVariableFromStaticContext",
1586: fieldName);
1587: throw new IllegalStateException(
1588: "No current instance available.");
1589: }
1590: case LOCAL_VARIABLE:
1591: case EXCEPTION_PARAMETER:
1592: ve = (VariableElement) elm;
1593: String varName = ve.getSimpleName().toString();
1594: try {
1595: LocalVariable lv = evaluationContext.getFrame()
1596: .visibleVariableByName(varName);
1597: if (lv == null) {
1598: Assert2.error(arg0, "unknownVariable", varName);
1599: }
1600: evaluationContext.getVariables().put(arg0,
1601: new VariableInfo(lv));
1602: return evaluationContext.getFrame().getValue(lv);
1603: } catch (AbsentInformationException aiex) {
1604: return (Value) Assert2.error(arg0, "unknownVariable",
1605: varName);
1606: }
1607: case PARAMETER:
1608: ve = (VariableElement) elm;
1609: String paramName = ve.getSimpleName().toString();
1610: StackFrame frame = evaluationContext.getFrame();
1611: try {
1612: LocalVariable lv = frame
1613: .visibleVariableByName(paramName);
1614: if (lv == null) {
1615: Assert2.error(arg0, "unknownVariable", paramName);
1616: }
1617: evaluationContext.getVariables().put(arg0,
1618: new VariableInfo(lv));
1619: return frame.getValue(lv);
1620: } catch (AbsentInformationException aiex) {
1621: try {
1622: org.netbeans.api.debugger.jpda.LocalVariable[] lvs;
1623: lvs = new CallStackFrameImpl(frame, 0,
1624: evaluationContext.getDebugger())
1625: .getMethodArguments();
1626: if (lvs != null) {
1627: for (org.netbeans.api.debugger.jpda.LocalVariable lv : lvs) {
1628: if (paramName.equals(lv.getName())) {
1629: return ((JDIVariable) lv).getJDIValue();
1630: }
1631: }
1632: }
1633: } catch (NativeMethodException nmex) {
1634: // ignore - no arguments available
1635: }
1636: return (Value) Assert2.error(arg0, "unknownVariable",
1637: paramName);
1638: }
1639: case PACKAGE:
1640: return (Value) Assert2.error(arg0, "notExpression");
1641: default:
1642: throw new UnsupportedOperationException(
1643: "Not supported element kind:" + elm.getKind()
1644: + " Tree = '" + arg0 + "'");
1645: }
1646: arg0.getName();
1647: throw new UnsupportedOperationException("Not supported yet."
1648: + " Tree = '" + arg0 + "'");
1649: }
1650:
1651: private ReferenceType findEnclosingType(ReferenceType type,
1652: String name) {
1653: if (type.name().equals(name)) {
1654: return type;
1655: }
1656: List<ReferenceType> classes = type.virtualMachine()
1657: .classesByName(name);
1658: if (classes.size() == 1) {
1659: return classes.get(0);
1660: }
1661: for (ReferenceType clazz : classes) {
1662: if (isNestedOf(clazz, type)) {
1663: return clazz;
1664: }
1665: }
1666: return null;
1667: }
1668:
1669: private boolean isNestedOf(ReferenceType nested, ReferenceType type) {
1670: if (nested.equals(type)) {
1671: return true;
1672: }
1673: for (ReferenceType n : nested.nestedTypes()) {
1674: if (isNestedOf(n, type)) {
1675: return true;
1676: }
1677: }
1678: return false;
1679: }
1680:
1681: private ObjectReference findEnclosedObject(ObjectReference object,
1682: ReferenceType type) {
1683: if (object.referenceType().equals(type)) {
1684: return object;
1685: }
1686: Field outerRef = object.referenceType().fieldByName("this$0");
1687: if (outerRef == null)
1688: return null;
1689: object = (ObjectReference) object.getValue(outerRef);
1690: return findEnclosedObject(object, type);
1691: }
1692:
1693: @Override
1694: public Mirror visitIf(IfTree arg0,
1695: EvaluationContext evaluationContext) {
1696: Assert2.error(arg0, "unsupported");
1697: return null;
1698: }
1699:
1700: @Override
1701: public Mirror visitImport(ImportTree arg0,
1702: EvaluationContext evaluationContext) {
1703: Assert2.error(arg0, "unsupported");
1704: return null;
1705: }
1706:
1707: @Override
1708: public Mirror visitArrayAccess(ArrayAccessTree arg0,
1709: EvaluationContext evaluationContext) {
1710: Mirror array = arg0.getExpression().accept(this ,
1711: evaluationContext);
1712: Mirror index = arg0.getIndex().accept(this , evaluationContext);
1713: return ((ArrayReference) array)
1714: .getValue(((PrimitiveValue) index).intValue());
1715: }
1716:
1717: @Override
1718: public Mirror visitLabeledStatement(LabeledStatementTree arg0,
1719: EvaluationContext evaluationContext) {
1720: Assert2.error(arg0, "unsupported");
1721: return null;
1722: }
1723:
1724: @Override
1725: public Mirror visitLiteral(LiteralTree arg0,
1726: EvaluationContext evaluationContext) {
1727: VirtualMachine vm = evaluationContext.getDebugger()
1728: .getVirtualMachine();
1729: Object value = arg0.getValue();
1730: if (value instanceof Boolean) {
1731: return vm.mirrorOf(((Boolean) value).booleanValue());
1732: }
1733: if (value instanceof Byte) {
1734: return vm.mirrorOf(((Byte) value).byteValue());
1735: }
1736: if (value instanceof Character) {
1737: return vm.mirrorOf(((Character) value).charValue());
1738: }
1739: if (value instanceof Double) {
1740: return vm.mirrorOf(((Double) value).doubleValue());
1741: }
1742: if (value instanceof Float) {
1743: return vm.mirrorOf(((Float) value).floatValue());
1744: }
1745: if (value instanceof Integer) {
1746: return vm.mirrorOf(((Integer) value).intValue());
1747: }
1748: if (value instanceof Long) {
1749: return vm.mirrorOf(((Long) value).longValue());
1750: }
1751: if (value instanceof Short) {
1752: return vm.mirrorOf(((Short) value).shortValue());
1753: }
1754: if (value instanceof String) {
1755: StringReference str = vm.mirrorOf((String) value);
1756: ClassType strClass = (ClassType) vm.classesByName(
1757: "java.lang.String").get(0);
1758: try {
1759: List<Value> args = Collections.emptyList();
1760: return invokeMethod(arg0, strClass.methodsByName(
1761: "intern").get(0), false, strClass, str, args,
1762: evaluationContext);
1763: } catch (Exception ex) {
1764: return str;
1765: }
1766: }
1767: if (value == null) {
1768: return null;
1769: }
1770: throw new UnsupportedOperationException("Unsupported value: "
1771: + value);
1772: }
1773:
1774: @Override
1775: public Mirror visitMethod(MethodTree arg0,
1776: EvaluationContext evaluationContext) {
1777: Assert2.error(arg0, "unsupported");
1778: return null;
1779: }
1780:
1781: @Override
1782: public Mirror visitModifiers(ModifiersTree arg0,
1783: EvaluationContext evaluationContext) {
1784: Assert2.error(arg0, "unsupported");
1785: return null;
1786: }
1787:
1788: @Override
1789: public Mirror visitNewArray(NewArrayTree arg0,
1790: EvaluationContext evaluationContext) {
1791: Type type;
1792: Tree typeTree = arg0.getType();
1793: if (typeTree == null) {
1794: if (newArrayType == null) {
1795: throw new IllegalStateException("No type info for "
1796: + arg0);
1797: }
1798: type = newArrayType;
1799: } else {
1800: type = (Type) arg0.getType()
1801: .accept(this , evaluationContext);
1802: }
1803: List<? extends ExpressionTree> dimensionTrees = arg0
1804: .getDimensions();
1805: int numDimensions = dimensionTrees.size();
1806: if (numDimensions > 0) {
1807: int[] dimensions = new int[numDimensions];
1808: ArrayType[] arrayTypes = new ArrayType[numDimensions];
1809: String arrayClassName = type.name() + "[]";
1810: for (int i = 0; i < numDimensions; i++, arrayClassName += "[]") {
1811: dimensions[i] = ((PrimitiveValue) dimensionTrees.get(
1812: numDimensions - 1 - i).accept(this ,
1813: evaluationContext)).intValue();
1814: List<ReferenceType> classes = type.virtualMachine()
1815: .classesByName(arrayClassName);
1816: if (classes.size() == 0) {
1817: Assert2.error(arg0, "unknownType", arrayClassName);
1818: }
1819: arrayTypes[i] = (ArrayType) classes.get(0);
1820: }
1821: return constructNewArray(arrayTypes, dimensions,
1822: numDimensions - 1);
1823: } else {
1824: List<? extends ExpressionTree> initializerTrees = arg0
1825: .getInitializers();
1826: return constructNewArray(arg0, type, initializerTrees,
1827: evaluationContext);
1828: }
1829: }
1830:
1831: private ArrayReference constructNewArray(ArrayType[] arrayTypes,
1832: int[] dimensions, int dimension) {
1833: ArrayReference array = arrayTypes[dimension]
1834: .newInstance(dimensions[dimension]);
1835: if (dimension > 0) {
1836: List<ArrayReference> elements = new ArrayList<ArrayReference>(
1837: dimensions[dimension]);
1838: for (int i = 0; i < dimensions[dimension]; i++) {
1839: ArrayReference subArray = constructNewArray(arrayTypes,
1840: dimensions, dimension - 1);
1841: elements.add(subArray);
1842: }
1843: try {
1844: array.setValues(elements);
1845: } catch (InvalidTypeException ex) {
1846: throw new IllegalStateException("ArrayType "
1847: + arrayTypes[dimension] + " can not have "
1848: + elements + " elements.");
1849: } catch (ClassNotLoadedException ex) {
1850: throw new IllegalStateException(
1851: new InvalidExpressionException(ex));
1852: }
1853: }
1854: return array;
1855: }
1856:
1857: private ArrayReference constructNewArray(NewArrayTree arg0,
1858: Type type, List<? extends ExpressionTree> initializerTrees,
1859: EvaluationContext evaluationContext) {
1860: int n = initializerTrees.size();
1861: List<Value> elements = new ArrayList<Value>(n);
1862: for (int i = 0; i < n; i++) {
1863: ExpressionTree exp = initializerTrees.get(i);
1864: newArrayType = getSubArrayType(arg0, type);
1865: // might call visitNewArray()
1866: Value element = (Value) exp.accept(this , evaluationContext);
1867: elements.add(element);
1868: }
1869: int depth = 1;
1870: ArrayReference array = getArrayType(arg0, type, depth)
1871: .newInstance(n);
1872: autoboxElements(arg0, type, elements, evaluationContext);
1873: try {
1874: array.setValues(elements);
1875: } catch (InvalidTypeException ex) {
1876: throw new IllegalStateException("ArrayType "
1877: + getArrayType(arg0, type, depth)
1878: + " can not have " + elements + " elements.");
1879: } catch (ClassNotLoadedException ex) {
1880: throw new IllegalStateException(
1881: new InvalidExpressionException(ex));
1882: }
1883: return array;
1884: }
1885:
1886: private static final String BRACKETS = "[][][][][][][][][][][][][][][][][][][][]"; // NOI8N
1887:
1888: private ArrayType getArrayType(NewArrayTree arg0, Type type,
1889: int depth) {
1890: String arrayClassName;
1891: if (depth < BRACKETS.length() / 2) {
1892: arrayClassName = type.name()
1893: + BRACKETS.substring(0, 2 * depth);
1894: } else {
1895: arrayClassName = type.name() + BRACKETS;
1896: for (int i = BRACKETS.length() / 2; i < depth; i++) {
1897: arrayClassName += "[]"; // NOI8N
1898: }
1899: }
1900: List<ReferenceType> classes = type.virtualMachine()
1901: .classesByName(arrayClassName);
1902: if (classes.size() == 0) {
1903: Assert2.error(arg0, "unknownType", arrayClassName);
1904: }
1905: return (ArrayType) classes.get(0);
1906: }
1907:
1908: private Type getSubArrayType(Tree arg0, Type type) {
1909: String name = type.name();
1910: if (name.endsWith("[]")) {
1911: name = name.substring(0, name.length() - 2);
1912: if (!name.endsWith("[]")) {
1913: Type pType = getPrimitiveType(name, type
1914: .virtualMachine());
1915: if (pType != null)
1916: return pType;
1917: }
1918: List<ReferenceType> classes = type.virtualMachine()
1919: .classesByName(name);
1920: if (classes.size() == 0) {
1921: Assert2.error(arg0, "unknownType", name);
1922: }
1923: type = classes.get(0);
1924: }
1925: return type;
1926: }
1927:
1928: private Type getPrimitiveType(String name, VirtualMachine vm) {
1929: if (name.equals(Boolean.TYPE.getName())) {
1930: return vm.mirrorOf(true).type();
1931: }
1932: if (name.equals((Byte.TYPE.getName()))) {
1933: return vm.mirrorOf((byte) 0).type();
1934: }
1935: if (name.equals((Character.TYPE.getName()))) {
1936: return vm.mirrorOf('a').type();
1937: }
1938: if (name.equals((Double.TYPE.getName()))) {
1939: return vm.mirrorOf(0.).type();
1940: }
1941: if (name.equals((Float.TYPE.getName()))) {
1942: return vm.mirrorOf(0f).type();
1943: }
1944: if (name.equals((Integer.TYPE.getName()))) {
1945: return vm.mirrorOf(0).type();
1946: }
1947: if (name.equals((Long.TYPE.getName()))) {
1948: return vm.mirrorOf(0l).type();
1949: }
1950: if (name.equals((Short.TYPE.getName()))) {
1951: return vm.mirrorOf((short) 0).type();
1952: }
1953: return null;
1954: }
1955:
1956: @Override
1957: public Mirror visitNewClass(NewClassTree arg0,
1958: EvaluationContext evaluationContext) {
1959: TreePath currentPath = getCurrentPath();
1960: TypeMirror cType;
1961: if (currentPath != null) {
1962: TreePath identifierPath = TreePath.getPath(currentPath,
1963: arg0);
1964: if (identifierPath == null)
1965: identifierPath = currentPath;
1966: Element elm = evaluationContext.getTrees().getElement(
1967: identifierPath);
1968: if (elm == null) {
1969: // Unresolved class
1970: Assert2
1971: .error(arg0, "unknownType", arg0
1972: .getIdentifier());
1973: }
1974: if (elm.asType().getKind() == TypeKind.ERROR) {
1975: cType = null;
1976: } else {
1977: if (elm.getKind() != ElementKind.CONSTRUCTOR) {
1978: throw new IllegalStateException("Element " + elm
1979: + " is of " + elm.getKind()
1980: + " kind. Tree = " + arg0);
1981: }
1982: ExecutableElement cElem = (ExecutableElement) elm;
1983: cType = cElem.asType();
1984: }
1985: } else {
1986: cType = null;
1987: }
1988: ExpressionTree classIdentifier = arg0.getIdentifier();
1989: Mirror clazz = classIdentifier.accept(this , evaluationContext);
1990: ClassType classType = (ClassType) clazz;
1991: //ReferenceType classType = getClassType(arg0, cType, evaluationContext);
1992: List<? extends ExpressionTree> args = arg0.getArguments();
1993: List<Value> argVals = new ArrayList<Value>(args.size());
1994: for (ExpressionTree arg : args) {
1995: Mirror argValue = arg.accept(this , evaluationContext);
1996: if (!(argValue instanceof Value)) {
1997: Assert2.error(arg, "Not a value");
1998: }
1999: argVals.add((Value) argValue);
2000: }
2001: List<? extends TypeMirror> paramTypes = null;
2002: String firstParamSignature = null;
2003: List<Type> argTypes = null;
2004: if (cType != null) {
2005: paramTypes = ((ExecutableType) cType).getParameterTypes();
2006: ObjectReference this Object = evaluationContext.getFrame()
2007: .this Object();
2008: if (this Object != null) {
2009: List<ReferenceType> nestedTypes = ((ReferenceType) this Object
2010: .type()).nestedTypes();
2011: for (ReferenceType nested : nestedTypes) {
2012: if (!nested.isStatic() && nested.equals(classType)) {
2013: argVals.add(0, this Object);
2014: firstParamSignature = this Object.type()
2015: .signature();
2016: }
2017: }
2018: }
2019: } else {
2020: argTypes = new ArrayList<Type>(argVals.size());
2021: for (Value value : argVals) {
2022: if (value == null) {
2023: argTypes.add(evaluationContext.getDebugger()
2024: .getVirtualMachine().classesByName(
2025: "java.lang.Object").get(0));
2026: } else {
2027: argTypes.add(value.type());
2028: }
2029: }
2030: ObjectReference this Object = evaluationContext.getFrame()
2031: .this Object();
2032: if (this Object != null) {
2033: List<ReferenceType> nestedTypes = ((ReferenceType) this Object
2034: .type()).nestedTypes();
2035: for (ReferenceType nested : nestedTypes) {
2036: if (!nested.isStatic() && nested.equals(classType)) {
2037: argVals.add(0, this Object);
2038: argTypes.add(0, this Object.type());
2039: }
2040: }
2041: }
2042: }
2043: try {
2044: if (loggerMethod.isLoggable(Level.FINE)) {
2045: loggerMethod.fine("STARTED : " + classType + "."
2046: + "<init>" + " (" + argVals + ") in thread "
2047: + evaluationContext.getFrame().thread());
2048: }
2049: evaluationContext.methodToBeInvoked();
2050: Method constructorMethod = getConcreteMethodAndReportProblems(
2051: arg0, classType, "<init>", firstParamSignature,
2052: paramTypes, argTypes);
2053: return classType.newInstance(evaluationContext.getFrame()
2054: .thread(), constructorMethod, argVals,
2055: ObjectReference.INVOKE_SINGLE_THREADED);
2056: } catch (InvalidTypeException itex) {
2057: throw new IllegalStateException(
2058: new InvalidExpressionException(itex));
2059: } catch (ClassNotLoadedException cnlex) {
2060: throw new IllegalStateException(
2061: new InvalidExpressionException(cnlex));
2062: } catch (IncompatibleThreadStateException itsex) {
2063: InvalidExpressionException ieex = new InvalidExpressionException(
2064: itsex);
2065: ieex.initCause(itsex);
2066: throw new IllegalStateException(ieex);
2067: } catch (InvocationException iex) {
2068: InvalidExpressionException ieex = new InvalidExpressionException(
2069: iex);
2070: ieex.initCause(iex);
2071: throw new IllegalStateException(ieex);
2072: } catch (UnsupportedOperationException uoex) {
2073: InvalidExpressionException ieex = new InvalidExpressionException(
2074: uoex);
2075: ieex.initCause(uoex);
2076: throw new IllegalStateException(ieex);
2077: } catch (ObjectCollectedException ocex) {
2078: throw new IllegalStateException(
2079: new InvalidExpressionException(NbBundle.getMessage(
2080: Evaluator.class, "CTL_EvalError_collected")));
2081: } finally {
2082: try {
2083: evaluationContext.methodInvokeDone();
2084: } catch (IncompatibleThreadStateException itsex) {
2085: InvalidExpressionException ieex = new InvalidExpressionException(
2086: itsex);
2087: ieex.initCause(itsex);
2088: throw new IllegalStateException(ieex);
2089: }
2090: if (loggerMethod.isLoggable(Level.FINE)) {
2091: loggerMethod.fine("FINISHED: " + classType + "."
2092: + "<init>" + " (" + argVals + ") in thread "
2093: + evaluationContext.getFrame().thread());
2094: }
2095: }
2096: }
2097:
2098: @Override
2099: public Mirror visitParenthesized(ParenthesizedTree arg0,
2100: EvaluationContext evaluationContext) {
2101: return arg0.getExpression().accept(this , evaluationContext);
2102: }
2103:
2104: @Override
2105: public Mirror visitReturn(ReturnTree arg0,
2106: EvaluationContext evaluationContext) {
2107: Assert2.error(arg0, "unsupported");
2108: return null;
2109: }
2110:
2111: @Override
2112: public Mirror visitMemberSelect(MemberSelectTree arg0,
2113: EvaluationContext evaluationContext) {
2114: TreePath currentPath = getCurrentPath();
2115: Element elm = null;
2116: if (currentPath != null) {
2117: // We have the path and resolved elements
2118: TreePath memberSelectPath = TreePath.getPath(currentPath,
2119: arg0);
2120: if (memberSelectPath == null)
2121: memberSelectPath = currentPath;
2122: elm = evaluationContext.getTrees().getElement(
2123: memberSelectPath);
2124: if (elm instanceof TypeElement
2125: && ((TypeElement) elm).asType() instanceof ErrorType) {
2126: currentPath = null; // Elements not resolved correctly
2127: }
2128: }
2129: if (currentPath == null) {
2130: Mirror expression = arg0.getExpression().accept(this ,
2131: evaluationContext);
2132: String name = arg0.getIdentifier().toString();
2133: // try field:
2134: if (expression instanceof ClassType) {
2135: ClassType clazz = (ClassType) expression;
2136: if (name.equals("this")) {
2137: ObjectReference this Object = evaluationContext
2138: .getFrame().this Object();
2139: while (this Object != null
2140: && !((ReferenceType) this Object.type())
2141: .equals(clazz)) {
2142: ReferenceType this Class = (ReferenceType) this Object
2143: .type();
2144: Field outerThisField = this Class
2145: .fieldByName("this$0");
2146: if (outerThisField != null) {
2147: this Object = (ObjectReference) this Object
2148: .getValue(outerThisField);
2149: } else {
2150: this Object = null;
2151: }
2152: }
2153: if (this Object == null) {
2154: Assert2.error(arg0, "unknownOuterClass", clazz
2155: .name());
2156: } else {
2157: return this Object;
2158: }
2159: }
2160: if (name.equals("class")) {
2161: return clazz.classObject();
2162: }
2163: Field f = clazz.fieldByName(name);
2164: if (f != null) {
2165: return clazz.getValue(f);
2166: }
2167: } else if (expression instanceof InterfaceType) {
2168: if (name.equals("class")) {
2169: return ((InterfaceType) expression).classObject();
2170: }
2171: } else if (expression instanceof ObjectReference) {
2172: if (expression instanceof ArrayReference
2173: && "length".equals(name)) {
2174: return expression.virtualMachine().mirrorOf(
2175: ((ArrayReference) expression).length());
2176: }
2177: ReferenceType type = ((ObjectReference) expression)
2178: .referenceType();
2179: Field f = type.fieldByName(name);
2180: if (f != null) {
2181: return ((ObjectReference) expression).getValue(f);
2182: }
2183: }
2184: if (expression == null) {
2185: Assert2.error(arg0, "fieldOnNull", name);
2186: }
2187: // try class
2188: VirtualMachine vm = evaluationContext.getDebugger()
2189: .getVirtualMachine();
2190: List<ReferenceType> classes = vm.classesByName(name);
2191: if (classes.size() == 0) {
2192: Assert2.error(arg0, "unknownType", name);
2193: }
2194: return classes.get(0);
2195: }
2196: // We have the path and resolved elements
2197: switch (elm.getKind()) {
2198: case ENUM_CONSTANT:
2199: VariableElement ve = (VariableElement) elm;
2200: String constantName = ve.getSimpleName().toString();
2201: ReferenceType enumType = getClassType(arg0, ve.asType(),
2202: evaluationContext);
2203: Method valueOfMethod = enumType.methodsByName("valueOf")
2204: .get(0);
2205: VirtualMachine vm = evaluationContext.getDebugger()
2206: .getVirtualMachine();
2207: StringReference constantNameRef = vm.mirrorOf(constantName);
2208: Value enumValue = invokeMethod(arg0, valueOfMethod, true,
2209: (ClassType) enumType, null, Collections
2210: .singletonList((Value) constantNameRef),
2211: evaluationContext);
2212: return enumValue;
2213: case FIELD:
2214: ve = (VariableElement) elm;
2215: String fieldName = ve.getSimpleName().toString();
2216: Mirror expression = arg0.getExpression().accept(this ,
2217: evaluationContext);
2218: if (expression instanceof ClassType) {
2219: ClassType clazz = (ClassType) expression;
2220: if (fieldName.equals("this")) {
2221: ObjectReference this Object = evaluationContext
2222: .getFrame().this Object();
2223: while (this Object != null
2224: && !((ReferenceType) this Object.type())
2225: .equals(clazz)) {
2226: ReferenceType this Class = (ReferenceType) this Object
2227: .type();
2228: Field outerThisField = this Class
2229: .fieldByName("this$0");
2230: if (outerThisField != null) {
2231: this Object = (ObjectReference) this Object
2232: .getValue(outerThisField);
2233: } else {
2234: this Object = null;
2235: }
2236: }
2237: if (this Object == null) {
2238: Assert2.error(arg0, "unknownOuterClass", clazz
2239: .name());
2240: } else {
2241: return this Object;
2242: }
2243: }
2244: if (fieldName.equals("class")) {
2245: return clazz.classObject();
2246: }
2247: Field f = clazz.fieldByName(fieldName);
2248: if (f != null) {
2249: return clazz.getValue(f);
2250: } else {
2251: Assert2.error(arg0, "unknownField", fieldName);
2252: return null;
2253: }
2254: }
2255: if (expression instanceof InterfaceType) {
2256: InterfaceType intrfc = (InterfaceType) expression;
2257: if (fieldName.equals("class")) {
2258: return intrfc.classObject();
2259: }
2260: Field f = intrfc.fieldByName(fieldName);
2261: if (f != null) {
2262: return intrfc.getValue(f);
2263: } else {
2264: Assert2.error(arg0, "unknownField", fieldName);
2265: return null;
2266: }
2267: }
2268: if (expression instanceof ObjectReference) {
2269: if (expression instanceof ArrayReference
2270: && "length".equals(fieldName)) {
2271: return expression.virtualMachine().mirrorOf(
2272: ((ArrayReference) expression).length());
2273: }
2274: ReferenceType type = ((ObjectReference) expression)
2275: .referenceType();
2276: Field f = type.fieldByName(fieldName);
2277: if (f != null) {
2278: return ((ObjectReference) expression).getValue(f);
2279: } else {
2280: Assert2.error(arg0, "unknownField", fieldName);
2281: return null;
2282: }
2283: }
2284: if (expression == null) {
2285: Assert2.error(arg0, "fieldOnNull", fieldName);
2286: }
2287: throw new IllegalArgumentException(
2288: "Wrong expression value: " + expression);
2289: case CLASS:
2290: case INTERFACE:
2291: TypeElement te = (TypeElement) elm;
2292: String className = ElementUtilities.getBinaryName(te);
2293: vm = evaluationContext.getDebugger().getVirtualMachine();
2294: List<ReferenceType> classes = vm.classesByName(className);
2295: if (classes.size() == 0) {
2296: Assert2.error(arg0, "unknownType", className);
2297: }
2298: return classes.get(0);
2299: case PACKAGE:
2300: return (Value) Assert2.error(arg0, "notExpression");
2301: default:
2302: throw new UnsupportedOperationException(
2303: "Not supported yet." + " Tree = '" + arg0
2304: + "', element kind = " + elm.getKind());
2305: }
2306: }
2307:
2308: @Override
2309: public Mirror visitEmptyStatement(EmptyStatementTree arg0,
2310: EvaluationContext evaluationContext) {
2311: Assert2.error(arg0, "unsupported");
2312: return null;
2313: }
2314:
2315: @Override
2316: public Mirror visitSwitch(SwitchTree arg0,
2317: EvaluationContext evaluationContext) {
2318: Assert2.error(arg0, "unsupported");
2319: return null;
2320: }
2321:
2322: @Override
2323: public Mirror visitSynchronized(SynchronizedTree arg0,
2324: EvaluationContext evaluationContext) {
2325: Assert2.error(arg0, "unsupported");
2326: return null;
2327: }
2328:
2329: @Override
2330: public Mirror visitThrow(ThrowTree arg0,
2331: EvaluationContext evaluationContext) {
2332: Assert2.error(arg0, "unsupported");
2333: return null;
2334: }
2335:
2336: @Override
2337: public Mirror visitCompilationUnit(CompilationUnitTree arg0,
2338: EvaluationContext evaluationContext) {
2339: Assert2.error(arg0, "unsupported");
2340: return null;
2341: }
2342:
2343: @Override
2344: public Mirror visitTry(TryTree arg0,
2345: EvaluationContext evaluationContext) {
2346: Assert2.error(arg0, "unsupported");
2347: return null;
2348: }
2349:
2350: @Override
2351: public Mirror visitParameterizedType(ParameterizedTypeTree arg0,
2352: EvaluationContext evaluationContext) {
2353: return arg0.getType().accept(this , evaluationContext);
2354: }
2355:
2356: @Override
2357: public Mirror visitArrayType(ArrayTypeTree arg0,
2358: EvaluationContext evaluationContext) {
2359: Type type = (Type) arg0.getType().accept(this ,
2360: evaluationContext);
2361: if (type == null)
2362: return null;
2363: String arrayClassName = type.name() + "[]";
2364: List<ReferenceType> aTypes = type.virtualMachine()
2365: .classesByName(arrayClassName);
2366: if (aTypes.size() > 0) {
2367: return aTypes.get(0);
2368: } else {
2369: Assert2.error(arg0, "unknownType", arrayClassName);
2370: return null;
2371: }
2372: }
2373:
2374: @Override
2375: public Mirror visitTypeCast(TypeCastTree arg0,
2376: EvaluationContext evaluationContext) {
2377: ExpressionTree expTree = arg0.getExpression();
2378: Mirror expression = expTree.accept(this , evaluationContext);
2379: if (expression == null)
2380: return null;
2381: Tree typeTree = arg0.getType();
2382: Mirror type = typeTree.accept(this , evaluationContext);
2383: if (expression instanceof PrimitiveValue) {
2384: PrimitiveValue primValue = (PrimitiveValue) expression;
2385: if (primValue instanceof BooleanValue) {
2386: Assert2.assertAssignable(type, BooleanType.class, arg0,
2387: "castToBooleanRequired", primValue, type);
2388: return primValue;
2389: }
2390: Assert2.assertNotAssignable(type, BooleanType.class, arg0,
2391: "castFromBooleanRequired", primValue, type);
2392: VirtualMachine vm = evaluationContext.getDebugger()
2393: .getVirtualMachine();
2394: if (type instanceof ByteType) {
2395: return vm.mirrorOf(primValue.byteValue());
2396: } else if (type instanceof CharType) {
2397: return vm.mirrorOf(primValue.charValue());
2398: } else if (type instanceof DoubleType) {
2399: return vm.mirrorOf(primValue.doubleValue());
2400: } else if (type instanceof FloatType) {
2401: return vm.mirrorOf(primValue.floatValue());
2402: } else if (type instanceof IntegerType) {
2403: return vm.mirrorOf(primValue.intValue());
2404: } else if (type instanceof LongType) {
2405: return vm.mirrorOf(primValue.longValue());
2406: } else {
2407: return vm.mirrorOf(primValue.shortValue());
2408: }
2409: }
2410: if (!instanceOf(((ObjectReference) expression).type(),
2411: (Type) type)) {
2412: Assert2.error(arg0, "castError",
2413: ((ObjectReference) expression).type(), type);
2414: }
2415: return expression;
2416: }
2417:
2418: @Override
2419: public Mirror visitPrimitiveType(PrimitiveTypeTree arg0,
2420: EvaluationContext evaluationContext) {
2421: TypeKind type = arg0.getPrimitiveTypeKind();
2422: VirtualMachine vm = evaluationContext.getDebugger()
2423: .getVirtualMachine();
2424: switch (type) {
2425: case BOOLEAN:
2426: return vm.mirrorOf(true).type();
2427: case BYTE:
2428: return vm.mirrorOf((byte) 0).type();
2429: case CHAR:
2430: return vm.mirrorOf('a').type();
2431: case DOUBLE:
2432: return vm.mirrorOf(0.).type();
2433: case FLOAT:
2434: return vm.mirrorOf(0f).type();
2435: case INT:
2436: return vm.mirrorOf(0).type();
2437: case LONG:
2438: return vm.mirrorOf(0l).type();
2439: case SHORT:
2440: return vm.mirrorOf((short) 0).type();
2441: default:
2442: throw new IllegalStateException("Tree = " + arg0);
2443: }
2444: }
2445:
2446: @Override
2447: public Mirror visitTypeParameter(TypeParameterTree arg0,
2448: EvaluationContext evaluationContext) {
2449: Assert2.error(arg0, "unsupported");
2450: return null;
2451: }
2452:
2453: @Override
2454: public Mirror visitInstanceOf(InstanceOfTree arg0,
2455: EvaluationContext evaluationContext) {
2456: Mirror expression = arg0.getExpression().accept(this ,
2457: evaluationContext);
2458: VirtualMachine vm = evaluationContext.getDebugger()
2459: .getVirtualMachine();
2460: if (expression == null)
2461: return vm.mirrorOf(false);
2462: Assert2.assertAssignable(expression, ObjectReference.class,
2463: arg0, "instanceOfLeftOperandNotAReference", expression);
2464:
2465: ReferenceType expressionType = ((ObjectReference) expression)
2466: .referenceType();
2467: Type type = (Type) arg0.getType().accept(this ,
2468: evaluationContext);
2469:
2470: return vm.mirrorOf(instanceOf(expressionType, type));
2471: }
2472:
2473: @Override
2474: public Mirror visitUnary(UnaryTree arg0,
2475: EvaluationContext evaluationContext) {
2476: Mirror expression = arg0.getExpression().accept(this ,
2477: evaluationContext);
2478: VirtualMachine vm = evaluationContext.getDebugger()
2479: .getVirtualMachine();
2480: Tree.Kind kind = arg0.getKind();
2481: if (expression instanceof BooleanValue) {
2482: boolean v = ((BooleanValue) expression).value();
2483: switch (kind) {
2484: case LOGICAL_COMPLEMENT:
2485: v = !v;
2486: break;
2487: default:
2488: throw new IllegalStateException("Tree = " + arg0);
2489: }
2490: return vm.mirrorOf(v);
2491: }
2492: if (expression instanceof ByteValue) {
2493: byte v = ((ByteValue) expression).value();
2494: switch (kind) {
2495: case BITWISE_COMPLEMENT:
2496: int i = ~v;
2497: return vm.mirrorOf(i);
2498: case POSTFIX_DECREMENT:
2499: setToMirror(arg0.getExpression(), vm.mirrorOf(v - 1),
2500: evaluationContext);
2501: break;
2502: case POSTFIX_INCREMENT:
2503: setToMirror(arg0.getExpression(), vm.mirrorOf(v + 1),
2504: evaluationContext);
2505: break;
2506: case PREFIX_DECREMENT:
2507: --v;
2508: setToMirror(arg0.getExpression(), vm.mirrorOf(v),
2509: evaluationContext);
2510: break;
2511: case PREFIX_INCREMENT:
2512: ++v;
2513: setToMirror(arg0.getExpression(), vm.mirrorOf(v),
2514: evaluationContext);
2515: break;
2516: case UNARY_MINUS:
2517: i = -v;
2518: return vm.mirrorOf(i);
2519: case UNARY_PLUS:
2520: break;
2521: default:
2522: throw new IllegalStateException("Tree = " + arg0);
2523: }
2524: return vm.mirrorOf(v);
2525: }
2526: if (expression instanceof CharValue) {
2527: char v = ((CharValue) expression).value();
2528: switch (kind) {
2529: case BITWISE_COMPLEMENT:
2530: int i = ~v;
2531: return vm.mirrorOf(i);
2532: case POSTFIX_DECREMENT:
2533: setToMirror(arg0.getExpression(), vm.mirrorOf(v - 1),
2534: evaluationContext);
2535: break;
2536: case POSTFIX_INCREMENT:
2537: setToMirror(arg0.getExpression(), vm.mirrorOf(v + 1),
2538: evaluationContext);
2539: break;
2540: case PREFIX_DECREMENT:
2541: --v;
2542: setToMirror(arg0.getExpression(), vm.mirrorOf(v),
2543: evaluationContext);
2544: break;
2545: case PREFIX_INCREMENT:
2546: ++v;
2547: setToMirror(arg0.getExpression(), vm.mirrorOf(v),
2548: evaluationContext);
2549: break;
2550: case UNARY_MINUS:
2551: i = -v;
2552: return vm.mirrorOf(i);
2553: case UNARY_PLUS:
2554: break;
2555: default:
2556: throw new IllegalStateException("Tree = " + arg0);
2557: }
2558: return vm.mirrorOf(v);
2559: }
2560: if (expression instanceof ShortValue) {
2561: short v = ((ShortValue) expression).value();
2562: switch (kind) {
2563: case BITWISE_COMPLEMENT:
2564: int i = ~v;
2565: return vm.mirrorOf(i);
2566: case POSTFIX_DECREMENT:
2567: setToMirror(arg0.getExpression(), vm.mirrorOf(v - 1),
2568: evaluationContext);
2569: break;
2570: case POSTFIX_INCREMENT:
2571: setToMirror(arg0.getExpression(), vm.mirrorOf(v + 1),
2572: evaluationContext);
2573: break;
2574: case PREFIX_DECREMENT:
2575: --v;
2576: setToMirror(arg0.getExpression(), vm.mirrorOf(v),
2577: evaluationContext);
2578: break;
2579: case PREFIX_INCREMENT:
2580: ++v;
2581: setToMirror(arg0.getExpression(), vm.mirrorOf(v),
2582: evaluationContext);
2583: break;
2584: case UNARY_MINUS:
2585: i = -v;
2586: return vm.mirrorOf(i);
2587: case UNARY_PLUS:
2588: break;
2589: default:
2590: throw new IllegalStateException("Tree = " + arg0);
2591: }
2592: return vm.mirrorOf(v);
2593: }
2594: if (expression instanceof IntegerValue) {
2595: int v = ((IntegerValue) expression).value();
2596: switch (kind) {
2597: case BITWISE_COMPLEMENT:
2598: v = ~v;
2599: break;
2600: case POSTFIX_DECREMENT:
2601: setToMirror(arg0.getExpression(), vm.mirrorOf(v - 1),
2602: evaluationContext);
2603: break;
2604: case POSTFIX_INCREMENT:
2605: setToMirror(arg0.getExpression(), vm.mirrorOf(v + 1),
2606: evaluationContext);
2607: break;
2608: case PREFIX_DECREMENT:
2609: --v;
2610: setToMirror(arg0.getExpression(), vm.mirrorOf(v),
2611: evaluationContext);
2612: break;
2613: case PREFIX_INCREMENT:
2614: ++v;
2615: setToMirror(arg0.getExpression(), vm.mirrorOf(v),
2616: evaluationContext);
2617: break;
2618: case UNARY_MINUS:
2619: v = -v;
2620: break;
2621: case UNARY_PLUS:
2622: break;
2623: default:
2624: throw new IllegalStateException("Tree = " + arg0);
2625: }
2626: return vm.mirrorOf(v);
2627: }
2628: if (expression instanceof LongValue) {
2629: long v = ((LongValue) expression).value();
2630: switch (kind) {
2631: case BITWISE_COMPLEMENT:
2632: v = ~v;
2633: break;
2634: case POSTFIX_DECREMENT:
2635: setToMirror(arg0.getExpression(), vm.mirrorOf(v - 1),
2636: evaluationContext);
2637: break;
2638: case POSTFIX_INCREMENT:
2639: setToMirror(arg0.getExpression(), vm.mirrorOf(v + 1),
2640: evaluationContext);
2641: break;
2642: case PREFIX_DECREMENT:
2643: --v;
2644: setToMirror(arg0.getExpression(), vm.mirrorOf(v),
2645: evaluationContext);
2646: break;
2647: case PREFIX_INCREMENT:
2648: ++v;
2649: setToMirror(arg0.getExpression(), vm.mirrorOf(v),
2650: evaluationContext);
2651: break;
2652: case UNARY_MINUS:
2653: v = -v;
2654: break;
2655: case UNARY_PLUS:
2656: break;
2657: default:
2658: throw new IllegalStateException("Tree = " + arg0);
2659: }
2660: return vm.mirrorOf(v);
2661: }
2662: if (expression instanceof DoubleValue) {
2663: double v = ((DoubleValue) expression).value();
2664: switch (kind) {
2665: case POSTFIX_DECREMENT:
2666: setToMirror(arg0.getExpression(), vm.mirrorOf(v - 1),
2667: evaluationContext);
2668: break;
2669: case POSTFIX_INCREMENT:
2670: setToMirror(arg0.getExpression(), vm.mirrorOf(v + 1),
2671: evaluationContext);
2672: break;
2673: case PREFIX_DECREMENT:
2674: --v;
2675: setToMirror(arg0.getExpression(), vm.mirrorOf(v),
2676: evaluationContext);
2677: break;
2678: case PREFIX_INCREMENT:
2679: ++v;
2680: setToMirror(arg0.getExpression(), vm.mirrorOf(v),
2681: evaluationContext);
2682: break;
2683: case UNARY_MINUS:
2684: v = -v;
2685: break;
2686: case UNARY_PLUS:
2687: break;
2688: default:
2689: throw new IllegalStateException("Tree = " + arg0);
2690: }
2691: return vm.mirrorOf(v);
2692: }
2693: if (expression instanceof FloatValue) {
2694: float v = ((FloatValue) expression).value();
2695: switch (kind) {
2696: case POSTFIX_DECREMENT:
2697: setToMirror(arg0.getExpression(), vm.mirrorOf(v - 1),
2698: evaluationContext);
2699: break;
2700: case POSTFIX_INCREMENT:
2701: setToMirror(arg0.getExpression(), vm.mirrorOf(v + 1),
2702: evaluationContext);
2703: break;
2704: case PREFIX_DECREMENT:
2705: --v;
2706: setToMirror(arg0.getExpression(), vm.mirrorOf(v),
2707: evaluationContext);
2708: break;
2709: case PREFIX_INCREMENT:
2710: ++v;
2711: setToMirror(arg0.getExpression(), vm.mirrorOf(v),
2712: evaluationContext);
2713: break;
2714: case UNARY_MINUS:
2715: v = -v;
2716: break;
2717: case UNARY_PLUS:
2718: break;
2719: default:
2720: throw new IllegalStateException("Tree = " + arg0);
2721: }
2722: return vm.mirrorOf(v);
2723: }
2724: throw new IllegalStateException("Bad expression type: "
2725: + expression);
2726: }
2727:
2728: @Override
2729: public Mirror visitVariable(VariableTree arg0,
2730: EvaluationContext evaluationContext) {
2731: // Variable declaration
2732: Assert2.error(arg0, "unsupported");
2733: return null;
2734: }
2735:
2736: @Override
2737: public Mirror visitWhileLoop(WhileLoopTree arg0,
2738: EvaluationContext evaluationContext) {
2739: Assert2.error(arg0, "unsupported");
2740: return null;
2741: }
2742:
2743: @Override
2744: public Mirror visitWildcard(WildcardTree arg0,
2745: EvaluationContext evaluationContext) {
2746: Assert2.error(arg0, "unsupported");
2747: return null;
2748: }
2749:
2750: @Override
2751: public Mirror visitOther(Tree arg0,
2752: EvaluationContext evaluationContext) {
2753: Assert2.error(arg0, "unsupported");
2754: return null;
2755: }
2756:
2757: private void setToMirror(Tree var, Value value,
2758: EvaluationContext evaluationContext) {
2759: VariableInfo varInfo = evaluationContext.getVariables()
2760: .get(var);
2761: if (varInfo == null) {
2762: throw new IllegalStateException("Unknown variable " + var);
2763: }
2764: try {
2765: if (varInfo.field != null) {
2766: if (varInfo.fieldObject != null) {
2767: varInfo.fieldObject.setValue(varInfo.field, value);
2768: } else {
2769: ((ClassType) varInfo.field.declaringType())
2770: .setValue(varInfo.field, value);
2771: }
2772: } else {
2773: evaluationContext.getFrame().setValue(varInfo.var,
2774: value);
2775: }
2776: } catch (InvalidTypeException itex) {
2777:
2778: } catch (ClassNotLoadedException cnlex) {
2779:
2780: }
2781: }
2782:
2783: private Value invokeMethod(Tree arg0, Method method,
2784: Boolean isStatic, ClassType type,
2785: ObjectReference objectReference, List<Value> argVals,
2786: EvaluationContext evaluationContext) {
2787: if (!evaluationContext.canInvokeMethods()) {
2788: Assert2.error(arg0, "calleeException",
2789: new UnsupportedOperationException(),
2790: evaluationContext);
2791: }
2792: ThreadReference evaluationThread = evaluationContext.getFrame()
2793: .thread();
2794: try {
2795: if (loggerMethod.isLoggable(Level.FINE)) {
2796: loggerMethod.fine("STARTED : " + objectReference + "."
2797: + method + " (" + argVals + ") in thread "
2798: + evaluationThread);
2799: }
2800: evaluationContext.methodToBeInvoked();
2801: Value value;
2802: autoboxArguments(method.argumentTypes(), argVals,
2803: evaluationThread);
2804: if (Boolean.TRUE.equals(isStatic)) {
2805: value = type
2806: .invokeMethod(evaluationThread, method,
2807: argVals,
2808: ObjectReference.INVOKE_SINGLE_THREADED);
2809: } else {
2810: if (type != null) {
2811: if (method.isPrivate()) {
2812: ObjectReference to = findEnclosedObject(
2813: objectReference, type);
2814: if (to != null)
2815: objectReference = to;
2816: } else {
2817: if (!instanceOf(
2818: objectReference.referenceType(), type)) {
2819: ObjectReference to = findEnclosedObject(
2820: objectReference, type);
2821: if (to != null)
2822: objectReference = to;
2823: }
2824: }
2825: }
2826: value = objectReference.invokeMethod(evaluationThread,
2827: method, argVals,
2828: ObjectReference.INVOKE_SINGLE_THREADED);
2829: }
2830: if (loggerMethod.isLoggable(Level.FINE)) {
2831: loggerMethod.fine(" return = " + value);
2832: }
2833: return value;
2834: } catch (InvalidTypeException itex) {
2835: throw new IllegalStateException(
2836: new InvalidExpressionException(itex));
2837: } catch (ClassNotLoadedException cnlex) {
2838: throw new IllegalStateException(
2839: new InvalidExpressionException(cnlex));
2840: } catch (IncompatibleThreadStateException itsex) {
2841: InvalidExpressionException ieex = new InvalidExpressionException(
2842: itsex);
2843: ieex.initCause(itsex);
2844: throw new IllegalStateException(ieex);
2845: } catch (InvocationException iex) {
2846: InvalidExpressionException ieex = new InvalidExpressionException(
2847: iex);
2848: ieex.initCause(iex);
2849: throw new IllegalStateException(ieex);
2850: } catch (UnsupportedOperationException uoex) {
2851: InvalidExpressionException ieex = new InvalidExpressionException(
2852: uoex);
2853: ieex.initCause(uoex);
2854: throw new IllegalStateException(ieex);
2855: } catch (ObjectCollectedException ocex) {
2856: throw new IllegalStateException(
2857: new InvalidExpressionException(NbBundle.getMessage(
2858: Evaluator.class, "CTL_EvalError_collected")));
2859: } finally {
2860: if (loggerMethod.isLoggable(Level.FINE)) {
2861: loggerMethod.fine("FINISHED: " + objectReference + "."
2862: + method + " (" + argVals + ") in thread "
2863: + evaluationThread);
2864: }
2865: try {
2866: evaluationContext.methodInvokeDone();
2867: } catch (IncompatibleThreadStateException itsex) {
2868: InvalidExpressionException ieex = new InvalidExpressionException(
2869: itsex);
2870: ieex.initCause(itsex);
2871: throw new IllegalStateException(ieex);
2872: }
2873: }
2874: }
2875:
2876: /**
2877: * Auto-boxes or un-boxes arguments of a method.
2878: */
2879: private static void autoboxArguments(List<Type> types,
2880: List<Value> argVals, ThreadReference evaluationThread)
2881: throws InvalidTypeException, ClassNotLoadedException,
2882: IncompatibleThreadStateException, InvocationException {
2883: if (types.size() != argVals.size()) {
2884: return;
2885: }
2886: int n = types.size();
2887: for (int i = 0; i < n; i++) {
2888: Type t = types.get(i);
2889: Value v = argVals.get(i);
2890: if (v instanceof ObjectReference
2891: && t instanceof PrimitiveType) {
2892: argVals.set(i, unbox((ObjectReference) v,
2893: (PrimitiveType) t, evaluationThread));
2894: }
2895: if (v instanceof PrimitiveValue
2896: && t instanceof ReferenceType) {
2897: argVals.set(i, box((PrimitiveValue) v,
2898: (ReferenceType) t, evaluationThread));
2899: }
2900: }
2901: }
2902:
2903: /**
2904: * Auto-boxes or un-boxes elements of an array.
2905: */
2906: private void autoboxElements(Tree arg0, Type type,
2907: List<Value> elements, EvaluationContext evaluationContext) {
2908: boolean methodCalled = false;
2909: ThreadReference evaluationThread = null;
2910: try {
2911: if (type instanceof PrimitiveType) {
2912: for (int i = 0; i < elements.size(); i++) {
2913: Value v = elements.get(i);
2914: if (v instanceof ObjectReference) {
2915: if (!methodCalled) {
2916: if (!evaluationContext.canInvokeMethods()) {
2917: Assert2
2918: .error(
2919: arg0,
2920: "calleeException",
2921: new UnsupportedOperationException(),
2922: evaluationContext);
2923: }
2924: evaluationThread = evaluationContext
2925: .getFrame().thread();
2926: if (loggerMethod.isLoggable(Level.FINE)) {
2927: loggerMethod.fine("STARTED : Unbox "
2928: + v + " in thread "
2929: + evaluationThread);
2930: }
2931: evaluationContext.methodToBeInvoked();
2932: methodCalled = true;
2933: }
2934: elements
2935: .set(i, unbox((ObjectReference) v,
2936: (PrimitiveType) type,
2937: evaluationThread));
2938: }
2939: }
2940: } else if (type instanceof ReferenceType) {
2941: for (int i = 0; i < elements.size(); i++) {
2942: Value v = elements.get(i);
2943: if (v instanceof PrimitiveValue) {
2944: if (!methodCalled) {
2945: if (!evaluationContext.canInvokeMethods()) {
2946: Assert2
2947: .error(
2948: arg0,
2949: "calleeException",
2950: new UnsupportedOperationException(),
2951: evaluationContext);
2952: }
2953: evaluationThread = evaluationContext
2954: .getFrame().thread();
2955: if (loggerMethod.isLoggable(Level.FINE)) {
2956: loggerMethod.fine("STARTED : Autobox "
2957: + v + " in thread "
2958: + evaluationThread);
2959: }
2960: evaluationContext.methodToBeInvoked();
2961: methodCalled = true;
2962: }
2963: elements
2964: .set(i, box((PrimitiveValue) v,
2965: (ReferenceType) type,
2966: evaluationThread));
2967: }
2968: }
2969: }
2970: } catch (InvalidTypeException itex) {
2971: throw new IllegalStateException(
2972: new InvalidExpressionException(itex));
2973: } catch (ClassNotLoadedException cnlex) {
2974: throw new IllegalStateException(
2975: new InvalidExpressionException(cnlex));
2976: } catch (IncompatibleThreadStateException itsex) {
2977: InvalidExpressionException ieex = new InvalidExpressionException(
2978: itsex);
2979: ieex.initCause(itsex);
2980: throw new IllegalStateException(ieex);
2981: } catch (InvocationException iex) {
2982: InvalidExpressionException ieex = new InvalidExpressionException(
2983: iex);
2984: ieex.initCause(iex);
2985: throw new IllegalStateException(ieex);
2986: } catch (UnsupportedOperationException uoex) {
2987: InvalidExpressionException ieex = new InvalidExpressionException(
2988: uoex);
2989: ieex.initCause(uoex);
2990: throw new IllegalStateException(ieex);
2991: } catch (ObjectCollectedException ocex) {
2992: throw new IllegalStateException(
2993: new InvalidExpressionException(NbBundle.getMessage(
2994: Evaluator.class, "CTL_EvalError_collected")));
2995: } finally {
2996: if (methodCalled) {
2997: if (loggerMethod.isLoggable(Level.FINE)) {
2998: loggerMethod
2999: .fine("FINISHED: Autobox/unbox in thread "
3000: + evaluationThread);
3001: }
3002: try {
3003: evaluationContext.methodInvokeDone();
3004: } catch (IncompatibleThreadStateException itsex) {
3005: InvalidExpressionException ieex = new InvalidExpressionException(
3006: itsex);
3007: ieex.initCause(itsex);
3008: throw new IllegalStateException(ieex);
3009: }
3010: }
3011: }
3012: }
3013:
3014: private static void unboxMethodToBeCalled(Tree arg0, Mirror v,
3015: EvaluationContext evaluationContext) {
3016: if (!evaluationContext.canInvokeMethods()) {
3017: Assert2.error(arg0, "calleeException",
3018: new UnsupportedOperationException(),
3019: evaluationContext);
3020: }
3021: if (loggerMethod.isLoggable(Level.FINE)) {
3022: loggerMethod.fine("STARTED : Unbox " + v + " in thread "
3023: + evaluationContext.getFrame().thread());
3024: }
3025: evaluationContext.methodToBeInvoked();
3026: }
3027:
3028: private static Mirror unboxIfCan(Tree arg0, ObjectReference r,
3029: EvaluationContext evaluationContext) {
3030: String name = ((ReferenceType) r.type()).name();
3031: boolean methodCalled = false;
3032: try {
3033: if (name.equals(Boolean.class.getName())) {
3034: unboxMethodToBeCalled(arg0, r, evaluationContext);
3035: methodCalled = true;
3036: return invokeUnboxingMethod(r, "booleanValue",
3037: evaluationContext.getFrame().thread());
3038: }
3039: if (name.equals(Byte.class.getName())) {
3040: unboxMethodToBeCalled(arg0, r, evaluationContext);
3041: methodCalled = true;
3042: return invokeUnboxingMethod(r, "byteValue",
3043: evaluationContext.getFrame().thread());
3044: }
3045: if (name.equals(Character.class.getName())) {
3046: unboxMethodToBeCalled(arg0, r, evaluationContext);
3047: methodCalled = true;
3048: return invokeUnboxingMethod(r, "charValue",
3049: evaluationContext.getFrame().thread());
3050: }
3051: if (name.equals(Short.class.getName())) {
3052: unboxMethodToBeCalled(arg0, r, evaluationContext);
3053: methodCalled = true;
3054: return invokeUnboxingMethod(r, "shortValue",
3055: evaluationContext.getFrame().thread());
3056: }
3057: if (name.equals(Integer.class.getName())) {
3058: unboxMethodToBeCalled(arg0, r, evaluationContext);
3059: methodCalled = true;
3060: return invokeUnboxingMethod(r, "intValue",
3061: evaluationContext.getFrame().thread());
3062: }
3063: if (name.equals(Long.class.getName())) {
3064: unboxMethodToBeCalled(arg0, r, evaluationContext);
3065: methodCalled = true;
3066: return invokeUnboxingMethod(r, "longValue",
3067: evaluationContext.getFrame().thread());
3068: }
3069: if (name.equals(Float.class.getName())) {
3070: unboxMethodToBeCalled(arg0, r, evaluationContext);
3071: methodCalled = true;
3072: return invokeUnboxingMethod(r, "floatValue",
3073: evaluationContext.getFrame().thread());
3074: }
3075: if (name.equals(Double.class.getName())) {
3076: unboxMethodToBeCalled(arg0, r, evaluationContext);
3077: methodCalled = true;
3078: return invokeUnboxingMethod(r, "doubleValue",
3079: evaluationContext.getFrame().thread());
3080: }
3081: return r;
3082: } catch (InvalidTypeException itex) {
3083: throw new IllegalStateException(
3084: new InvalidExpressionException(itex));
3085: } catch (ClassNotLoadedException cnlex) {
3086: throw new IllegalStateException(
3087: new InvalidExpressionException(cnlex));
3088: } catch (IncompatibleThreadStateException itsex) {
3089: InvalidExpressionException ieex = new InvalidExpressionException(
3090: itsex);
3091: ieex.initCause(itsex);
3092: throw new IllegalStateException(ieex);
3093: } catch (InvocationException iex) {
3094: InvalidExpressionException ieex = new InvalidExpressionException(
3095: iex);
3096: ieex.initCause(iex);
3097: throw new IllegalStateException(ieex);
3098: } catch (UnsupportedOperationException uoex) {
3099: InvalidExpressionException ieex = new InvalidExpressionException(
3100: uoex);
3101: ieex.initCause(uoex);
3102: throw new IllegalStateException(ieex);
3103: } catch (ObjectCollectedException ocex) {
3104: throw new IllegalStateException(
3105: new InvalidExpressionException(NbBundle.getMessage(
3106: Evaluator.class, "CTL_EvalError_collected")));
3107: } finally {
3108: if (methodCalled) {
3109: if (loggerMethod.isLoggable(Level.FINE)) {
3110: loggerMethod.fine("FINISHED: unbox in thread "
3111: + evaluationContext.getFrame().thread());
3112: }
3113: try {
3114: evaluationContext.methodInvokeDone();
3115: } catch (IncompatibleThreadStateException itsex) {
3116: InvalidExpressionException ieex = new InvalidExpressionException(
3117: itsex);
3118: ieex.initCause(itsex);
3119: throw new IllegalStateException(ieex);
3120: }
3121: }
3122: }
3123: }
3124:
3125: public static PrimitiveValue unbox(ObjectReference val,
3126: PrimitiveType type, ThreadReference thread)
3127: throws InvalidTypeException, ClassNotLoadedException,
3128: IncompatibleThreadStateException, InvocationException {
3129: if (type instanceof BooleanType)
3130: return invokeUnboxingMethod(val, "booleanValue", thread);
3131: if (type instanceof ByteType)
3132: return invokeUnboxingMethod(val, "byteValue", thread);
3133: if (type instanceof CharType)
3134: return invokeUnboxingMethod(val, "charValue", thread);
3135: if (type instanceof ShortType)
3136: return invokeUnboxingMethod(val, "shortValue", thread);
3137: if (type instanceof IntegerType)
3138: return invokeUnboxingMethod(val, "intValue", thread);
3139: if (type instanceof LongType)
3140: return invokeUnboxingMethod(val, "longValue", thread);
3141: if (type instanceof FloatType)
3142: return invokeUnboxingMethod(val, "floatValue", thread);
3143: if (type instanceof DoubleType)
3144: return invokeUnboxingMethod(val, "doubleValue", thread);
3145: throw new RuntimeException("Invalid type while unboxing: "
3146: + type.signature()); // never happens
3147: }
3148:
3149: public static ObjectReference box(PrimitiveValue v,
3150: ReferenceType type, ThreadReference thread)
3151: throws InvalidTypeException, ClassNotLoadedException,
3152: IncompatibleThreadStateException, InvocationException {
3153: try {
3154: Method constructor = null;
3155: List<Method> methods = type.methodsByName("<init>");
3156: String signature = "(" + v.type().signature() + ")";
3157: for (Method method : methods) {
3158: if (!method.isAbstract()
3159: && egualMethodSignatures(method.signature(),
3160: signature)) {
3161: constructor = method;
3162: }
3163: }
3164: if (constructor == null) {
3165: throw new RuntimeException("No constructor " + type
3166: + " " + signature);
3167: }
3168: return ((ClassType) type).newInstance(thread, constructor,
3169: Arrays.asList(new Value[] { v }),
3170: ObjectReference.INVOKE_SINGLE_THREADED);
3171: } catch (InvalidTypeException itex) {
3172: throw itex;
3173: } catch (ClassNotLoadedException cnlex) {
3174: throw cnlex;
3175: } catch (IncompatibleThreadStateException itsex) {
3176: throw itsex;
3177: } catch (InvocationException iex) {
3178: throw iex;
3179: } catch (Exception e) {
3180: // this should never happen, indicates an internal error
3181: throw new RuntimeException(
3182: "Unexpected exception while invoking boxing method",
3183: e);
3184: }
3185: }
3186:
3187: private static PrimitiveValue invokeUnboxingMethod(
3188: ObjectReference reference, String methodName,
3189: ThreadReference thread) throws InvalidTypeException,
3190: ClassNotLoadedException, IncompatibleThreadStateException,
3191: InvocationException {
3192: Method toCall = (Method) reference.referenceType()
3193: .methodsByName(methodName).get(0);
3194: try {
3195: return (PrimitiveValue) reference.invokeMethod(thread,
3196: toCall, new ArrayList<Value>(0),
3197: ObjectReference.INVOKE_SINGLE_THREADED);
3198: } catch (InvalidTypeException itex) {
3199: throw itex;
3200: } catch (ClassNotLoadedException cnlex) {
3201: throw cnlex;
3202: } catch (IncompatibleThreadStateException itsex) {
3203: throw itsex;
3204: } catch (InvocationException iex) {
3205: throw iex;
3206: } catch (Exception e) {
3207: // this should never happen, indicates an internal error
3208: throw new RuntimeException(
3209: "Unexpected exception while invoking unboxing method",
3210: e);
3211: }
3212: }
3213:
3214: private String toString(Tree arg0, Mirror v,
3215: EvaluationContext evaluationContext) {
3216: if (v instanceof PrimitiveValue) {
3217: PrimitiveValue pv = (PrimitiveValue) v;
3218: PrimitiveType t = (PrimitiveType) pv.type();
3219: if (t instanceof ByteType) {
3220: return Byte.toString(pv.byteValue());
3221: }
3222: if (t instanceof BooleanType) {
3223: return Boolean.toString(pv.booleanValue());
3224: }
3225: if (t instanceof CharType) {
3226: return Character.toString(pv.charValue());
3227: }
3228: if (t instanceof ShortType) {
3229: return Short.toString(pv.shortValue());
3230: }
3231: if (t instanceof IntegerType) {
3232: return Integer.toString(pv.intValue());
3233: }
3234: if (t instanceof LongType) {
3235: return Long.toString(pv.longValue());
3236: }
3237: if (t instanceof FloatType) {
3238: return Float.toString(pv.floatValue());
3239: }
3240: if (t instanceof DoubleType) {
3241: return Double.toString(pv.doubleValue());
3242: }
3243: throw new IllegalStateException("Unknown primitive type: "
3244: + t);
3245: }
3246: if (v == null) {
3247: return "" + null;
3248: }
3249: ObjectReference ov = (ObjectReference) v;
3250: // Call toString() method:
3251: List<? extends TypeMirror> typeArguments = Collections
3252: .emptyList();
3253: Method method;
3254: try {
3255: method = getConcreteMethod((ReferenceType) ov.type(),
3256: "toString", typeArguments);
3257: } catch (UnsuitableArgumentsException uaex) {
3258: throw new IllegalStateException(uaex);
3259: }
3260: ((ClassType) ov.type()).methodsByName("toString");
3261: List<Value> argVals = Collections.emptyList();
3262: Value sv = invokeMethod(arg0, method, false, null, ov, argVals,
3263: evaluationContext);
3264: if (sv instanceof StringReference) {
3265: return ((StringReference) sv).value();
3266: } else {
3267: throw new IllegalStateException(
3268: "Result of toString() call on " + ov
3269: + " is not a String, but: " + sv);
3270: }
3271: }
3272:
3273: private static final class UnsuitableArgumentsException extends
3274: Exception {
3275: public UnsuitableArgumentsException() {
3276: }
3277: }
3278:
3279: }
|