1 /*
   2  * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  *  @test
  26  *  @summary Test Method.variables() and the like.
  27  *
  28  *  @author Robert Field
  29  *
  30  *  @library scaffold
  31  *  @modules jdk.jdi
  32  *  @run build JDIScaffold VMConnection
  33  *  @run compile -g Vars.java
  34  *  @run driver Vars
  35  */
  36 
  37 import com.sun.jdi.*;
  38 import com.sun.jdi.event.*;
  39 import java.util.*;
  40 
  41 /*
  42  * This class is internal
  43  */
  44 abstract class AbstractTestVars {
  45     abstract float test1(String blah, int i);
  46     native int test2(double k, boolean b);
  47     String test3(short sh, long lo) {
  48         String st = "roses";
  49         return st;
  50     }
  51 }
  52 
  53 /*
  54  * This class is internal
  55  */
  56 class TestVars extends AbstractTestVars {
  57     float test1(String blah, int i) {
  58         return (float)1.1;
  59     }
  60 
  61     void hi() {
  62         return;
  63     }
  64 
  65     public static void main(String[] args) throws Exception {
  66         new TestVars().hi();
  67         return;
  68     }
  69 }
  70 
  71 /*
  72  * "Vars" test runs TestVars and makes LocalVariable queries
  73  */
  74 public class Vars extends JDIScaffold {
  75     final String[] args;
  76 
  77     boolean failed = false;
  78 
  79     Vars(String args[]) {
  80         super();
  81         this.args = args;
  82     }
  83 
  84     public static void main(String[] args) throws Exception {
  85         new Vars(args).runTests();
  86     }
  87 
  88     static final int VARIABLES = 1;
  89     static final int BYNAME = 2;
  90     static final int ARGUMENTS = 3;
  91 
  92     String testCase(Method method, int which) {
  93         try {
  94             List vars;
  95             switch (which) {
  96                 case VARIABLES:
  97                     vars = method.variables();
  98                     break;
  99                 case BYNAME:
 100                     vars = method.variablesByName("st");
 101                     break;
 102                 case ARGUMENTS:
 103                     vars = method.arguments();
 104                     break;
 105                 default:
 106                     throw new InternalException("should not happen");
 107             }
 108             StringBuffer sb = new StringBuffer();
 109             for (Iterator it = vars.iterator(); it.hasNext(); ) {
 110                 LocalVariable lv = (LocalVariable)it.next();
 111                 if (sb.length() > 0) {
 112                     sb.append(",");
 113                 }
 114                 sb.append(lv.name());
 115             }
 116             return sb.toString();
 117         } catch (Exception exc) {
 118             String st = exc.getClass().getName();
 119             int inx = st.lastIndexOf('.');
 120             return st.substring(inx+1);
 121         }
 122     }
 123 
 124     /**
 125      * Sets failed if fails.
 126      */
 127     void test(Method method, int which, String name, String expected) {
 128         String got = testCase(method, which);
 129         if (got.equals(expected)) {
 130             System.out.println(name + ": got expected: " + got);
 131         } else {
 132             failed = true;
 133             System.out.println(name + ": ERROR expected: " + expected);
 134             System.out.println("      got: " + got);
 135         }
 136     }
 137 
 138     void test2(Method method, int which, String name, String expected, String expected2) {
 139         String got = testCase(method, which);
 140         if (got.equals(expected) || got.equals(expected2)) {
 141             System.out.println(name + ": got expected: " + got);
 142         } else {
 143             failed = true;
 144             System.out.println(name + ": ERROR expected: " + expected);
 145             System.out.println("      got: " + got);
 146         }
 147     }
 148 
 149     protected void runTests() throws Exception {
 150         List argList = new ArrayList(Arrays.asList(args));
 151         argList.add("TestVars");
 152         System.out.println("run args: " + argList);
 153         connect((String[])argList.toArray(args));
 154         waitForVMStart();
 155 
 156         /*
 157          * Get to a point where the classes are loaded.
 158          */
 159         BreakpointEvent bp = resumeTo("TestVars", "hi", "()V");
 160 
 161         /*
 162          * These classes should have no line numbers, except for
 163          * one in the implicit constructor.
 164          */
 165         ReferenceType rt = findReferenceType("AbstractTestVars");
 166         if (rt == null) {
 167             throw new Exception("AbstractTestVars: not loaded");
 168         }
 169         Method method = findMethod(rt, "test1", "(Ljava/lang/String;I)F");
 170         if (method == null) {
 171             throw new Exception("Method not found");
 172         }
 173         test(method, VARIABLES, "abstract/variables",
 174              "AbsentInformationException");
 175         test(method, BYNAME, "abstract/variablesByName",
 176              "AbsentInformationException");
 177         test(method, ARGUMENTS, "abstract/arguments",
 178              "AbsentInformationException");
 179 
 180         method = findMethod(rt, "test2", "(DZ)I");
 181         if (method == null) {
 182             throw new Exception("Method not found");
 183         }
 184         test(method, VARIABLES, "native/variables",
 185              "AbsentInformationException");
 186         test(method, BYNAME, "native/variablesByName",
 187              "AbsentInformationException");
 188         test(method, ARGUMENTS, "native/arguments",
 189              "AbsentInformationException");
 190 
 191         method = findMethod(rt, "test3", "(SJ)Ljava/lang/String;");
 192         if (method == null) {
 193             throw new Exception("Method not found");
 194         }
 195         // javac can put these in whatever order it desires.  hopper
 196         // does it one way and mantis another.
 197         test2(method, VARIABLES, "normal/variables", "sh,lo,st", "st,sh,lo");
 198         test(method, BYNAME, "normal/variablesByName", "st");
 199         test(method, ARGUMENTS, "normal/arguments", "sh,lo");
 200 
 201         // Allow application to complete
 202         resumeToVMDeath();
 203 
 204         if (failed) {
 205             throw new Exception("Vars: failed");
 206         } else {
 207             System.out.println("Vars: passed");
 208         }
 209     }
 210 }