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  * @author Robert Field
  28  *
  29  * @run build JDIScaffold VMConnection
  30  * @run compile -g Vars.java
  31  * @run driver Vars
  32  */
  33 
  34 import com.sun.jdi.*;
  35 import com.sun.jdi.event.*;
  36 import java.util.*;
  37 
  38 /*
  39  * This class is internal
  40  */
  41 abstract class AbstractTestVars {
  42     abstract float test1(String blah, int i);
  43     native int test2(double k, boolean b);
  44     String test3(short sh, long lo) {
  45         String st = "roses";
  46         return st;
  47     }
  48 }
  49 
  50 /*
  51  * This class is internal
  52  */
  53 class TestVars extends AbstractTestVars {
  54     float test1(String blah, int i) {
  55         return (float)1.1;
  56     }
  57 
  58     void hi() {
  59         return;
  60     }
  61 
  62     public static void main(String[] args) throws Exception {
  63         new TestVars().hi();
  64         return;
  65     }
  66 }
  67 
  68 /*
  69  * "Vars" test runs TestVars and makes LocalVariable queries
  70  */
  71 public class Vars extends JDIScaffold {
  72     final String[] args;
  73 
  74     boolean failed = false;
  75 
  76     Vars(String args[]) {
  77         super();
  78         this.args = args;
  79     }
  80 
  81     public static void main(String[] args) throws Exception {
  82         new Vars(args).runTests();
  83     }
  84 
  85     static final int VARIABLES = 1;
  86     static final int BYNAME = 2;
  87     static final int ARGUMENTS = 3;
  88 
  89     String testCase(Method method, int which) {
  90         try {
  91             List vars;
  92             switch (which) {
  93                 case VARIABLES:
  94                     vars = method.variables();
  95                     break;
  96                 case BYNAME:
  97                     vars = method.variablesByName("st");
  98                     break;
  99                 case ARGUMENTS:
 100                     vars = method.arguments();
 101                     break;
 102                 default:
 103                     throw new InternalException("should not happen");
 104             }
 105             StringBuffer sb = new StringBuffer();
 106             for (Iterator it = vars.iterator(); it.hasNext(); ) {
 107                 LocalVariable lv = (LocalVariable)it.next();
 108                 if (sb.length() > 0) {
 109                     sb.append(",");
 110                 }
 111                 sb.append(lv.name());
 112             }
 113             return sb.toString();
 114         } catch (Exception exc) {
 115             String st = exc.getClass().getName();
 116             int inx = st.lastIndexOf('.');
 117             return st.substring(inx+1);
 118         }
 119     }
 120 
 121     /**
 122      * Sets failed if fails.
 123      */
 124     void test(Method method, int which, String name, String expected) {
 125         String got = testCase(method, which);
 126         if (got.equals(expected)) {
 127             System.out.println(name + ": got expected: " + got);
 128         } else {
 129             failed = true;
 130             System.out.println(name + ": ERROR expected: " + expected);
 131             System.out.println("      got: " + got);
 132         }
 133     }
 134 
 135     void test2(Method method, int which, String name, String expected, String expected2) {
 136         String got = testCase(method, which);
 137         if (got.equals(expected) || got.equals(expected2)) {
 138             System.out.println(name + ": got expected: " + got);
 139         } else {
 140             failed = true;
 141             System.out.println(name + ": ERROR expected: " + expected);
 142             System.out.println("      got: " + got);
 143         }
 144     }
 145 
 146     protected void runTests() throws Exception {
 147         List argList = new ArrayList(Arrays.asList(args));
 148         argList.add("TestVars");
 149         System.out.println("run args: " + argList);
 150         connect((String[])argList.toArray(args));
 151         waitForVMStart();
 152 
 153         /*
 154          * Get to a point where the classes are loaded.
 155          */
 156         BreakpointEvent bp = resumeTo("TestVars", "hi", "()V");
 157 
 158         /*
 159          * These classes should have no line numbers, except for
 160          * one in the implicit constructor.
 161          */
 162         ReferenceType rt = findReferenceType("AbstractTestVars");
 163         if (rt == null) {
 164             throw new Exception("AbstractTestVars: not loaded");
 165         }
 166         Method method = findMethod(rt, "test1", "(Ljava/lang/String;I)F");
 167         if (method == null) {
 168             throw new Exception("Method not found");
 169         }
 170         test(method, VARIABLES, "abstract/variables",
 171              "AbsentInformationException");
 172         test(method, BYNAME, "abstract/variablesByName",
 173              "AbsentInformationException");
 174         test(method, ARGUMENTS, "abstract/arguments",
 175              "AbsentInformationException");
 176 
 177         method = findMethod(rt, "test2", "(DZ)I");
 178         if (method == null) {
 179             throw new Exception("Method not found");
 180         }
 181         test(method, VARIABLES, "native/variables",
 182              "AbsentInformationException");
 183         test(method, BYNAME, "native/variablesByName",
 184              "AbsentInformationException");
 185         test(method, ARGUMENTS, "native/arguments",
 186              "AbsentInformationException");
 187 
 188         method = findMethod(rt, "test3", "(SJ)Ljava/lang/String;");
 189         if (method == null) {
 190             throw new Exception("Method not found");
 191         }
 192         // javac can put these in whatever order it desires.  hopper
 193         // does it one way and mantis another.
 194         test2(method, VARIABLES, "normal/variables", "sh,lo,st", "st,sh,lo");
 195         test(method, BYNAME, "normal/variablesByName", "st");
 196         test(method, ARGUMENTS, "normal/arguments", "sh,lo");
 197 
 198         // Allow application to complete
 199         resumeToVMDeath();
 200 
 201         if (failed) {
 202             throw new Exception("Vars: failed");
 203         } else {
 204             System.out.println("Vars: passed");
 205         }
 206     }
 207 }