1 /*
   2  * Copyright (c) 2014, 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  * JDK-8044798: API for debugging Nashorn
  26  *
  27  * @test
  28  * @option -Dnashorn.mirror.always=false
  29  * @fork
  30  * @run
  31  */
  32 
  33 // basic API exercise checks
  34 
  35 var Arrays = Java.type("java.util.Arrays");
  36 var CharArray = Java.type("char[]");
  37 var DebuggerSupport = Java.type("jdk.nashorn.internal.runtime.DebuggerSupport");
  38 var DebuggerValueDesc = Java.type("jdk.nashorn.internal.runtime.DebuggerSupport.DebuggerValueDesc");
  39 
  40 var valueDescFields = DebuggerValueDesc.class.declaredFields;
  41 Arrays.sort(valueDescFields, function(f1, f2) f1.name.compareTo(f2.name));
  42 for each (var f in valueDescFields) {
  43     f.accessible = true;
  44 }
  45 
  46 var debuggerSupportMethods = DebuggerSupport.class.declaredMethods;
  47 
  48 // methods of DebuggerSupport that we use
  49 var evalMethod, valueInfoMethod, valueInfosMethod;
  50 var getSourceInfoMethod, valueAsStringMethod;
  51 
  52 for each (var m in debuggerSupportMethods) {
  53     m.accessible = true;
  54     switch (m.name) {
  55         case "eval":
  56             evalMethod = m;
  57             break;
  58         case "valueInfo":
  59             if (m.parameterCount == 3) {
  60                 valueInfoMethod = m;
  61             }
  62             break;
  63         case "valueInfos":
  64             valueInfosMethod = m;
  65             break;
  66         case "valueAsString":
  67             valueAsStringMethod = m;
  68             break;
  69         case "getSourceInfo":
  70             getSourceInfoMethod = m;
  71             break;
  72     }
  73 }
  74 
  75 // eval
  76 var value = evalMethod.invoke(null, null, null, "33 + 55", false);
  77 print(value);
  78 
  79 // valueInfo
  80 var info = valueInfoMethod.invoke(null, "apply", Function, true);
  81 for each (var f in valueDescFields) {
  82     print(f.name, "=", f.get(info));
  83 }
  84 
  85 // valueInfo - user defined object
  86 var info = valueInfoMethod.invoke(null, "foo", { foo: 343 }, true);
  87 for each (var f in valueDescFields) {
  88     print(f.name, "=", f.get(info));
  89 }
  90 
  91 // valueInfos
  92 var infos = valueInfosMethod.invoke(null, Object, true);
  93 for each (var info in infos) {
  94     for each (var f in valueDescFields) {
  95         print(f.name, "=", f.get(info));
  96     }
  97 }
  98 
  99 // valueInfos - user defined object
 100 var infos = valueInfosMethod.invoke(null, { foo: 34, bar: "hello" }, true);
 101 for each (var info in infos) {
 102     for each (var f in valueDescFields) {
 103         print(f.name, "=", f.get(info));
 104     }
 105 }
 106 
 107 // valueAsString
 108 function printValue(value) {
 109     print(valueAsStringMethod.invoke(null, value));
 110 }
 111 
 112 printValue(undefined);
 113 printValue(null);
 114 printValue("hello");
 115 printValue(Math.PI);
 116 printValue(this);
 117 
 118 // The below are not part of DebuggerSupport. But we need these to
 119 // test DebuggerSupport.getSourceInfo etc. which need compiled script class
 120 
 121 var Source = Java.type("jdk.nashorn.internal.runtime.Source");
 122 var Context = Java.type("jdk.nashorn.internal.runtime.Context");
 123 var sourceCls = Source.class;
 124 var errorMgrCls = Java.type("jdk.nashorn.internal.runtime.ErrorManager").class;
 125 var booleanCls = Java.type("java.lang.Boolean").TYPE;
 126 
 127 // private compile method of Context class
 128 var compileMethod = Context.class.getDeclaredMethod("compile",
 129                 sourceCls, errorMgrCls, booleanCls);
 130 compileMethod.accessible = true;
 131 
 132 var scriptCls = compileMethod.invoke(Context.context,
 133     Source.sourceFor("test", "print('hello')"),
 134     new Context.ThrowErrorManager(), false);
 135 
 136 var SCRIPT_CLASS_NAME_PREFIX = "jdk.nashorn.internal.scripts.Script$";
 137 print("script class name pattern satisfied? " +
 138     scriptCls.name.startsWith(SCRIPT_CLASS_NAME_PREFIX));
 139 
 140 var srcInfo = getSourceInfoMethod.invoke(null, scriptCls);
 141 var srcInfoFields = srcInfo.class.declaredFields;
 142 Arrays.sort(srcInfoFields, function(f1, f2) f1.name.compareTo(f2.name));
 143 
 144 print("Source info");
 145 for each (var f in srcInfoFields) {
 146     f.accessible = true;
 147     var fieldValue = f.get(srcInfo);
 148     if (fieldValue instanceof CharArray) {
 149         fieldValue = new java.lang.String(fieldValue);
 150     }
 151 
 152     print(f.name, "=", fieldValue);
 153 }