/*
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.nashorn.internal.runtime;

import static jdk.nashorn.internal.parser.TokenType.EOF;

import jdk.nashorn.api.scripting.NashornException;
import jdk.nashorn.internal.parser.Lexer;
import jdk.nashorn.internal.parser.Token;
import jdk.nashorn.internal.parser.TokenStream;
import jdk.nashorn.internal.parser.TokenType;

Utilities for debugging Nashorn.
/** * Utilities for debugging Nashorn. * */
public final class Debug { private Debug() { }
Return the topmost JavaScript frame in a stack trace
Params:
  • t – throwable that contains the stack trace
Returns:line describing the topmost JavaScript frame
/** * Return the topmost JavaScript frame in a stack trace * @param t throwable that contains the stack trace * @return line describing the topmost JavaScript frame */
public static String firstJSFrame(final Throwable t) { for (final StackTraceElement ste : t.getStackTrace()) { if (ECMAErrors.isScriptFrame(ste)) { return ste.toString(); } } return "<native code>"; }
Return the topmost JavaScript frame from the current continuation
Returns:line describing the topmost JavaScript frame
/** * Return the topmost JavaScript frame from the current * continuation * @return line describing the topmost JavaScript frame */
public static String firstJSFrame() { return firstJSFrame(new Throwable()); }
Return a formatted script stack trace string with frames information separated by '\n'. This is a shortcut for NashornException.getScriptStackString(new Throwable()).
Returns:formatted stack trace string
/** * Return a formatted script stack trace string with frames information separated by '\n'. * This is a shortcut for {@code NashornException.getScriptStackString(new Throwable())}. * @return formatted stack trace string */
public static String scriptStack() { return NashornException.getScriptStackString(new Throwable()); }
Return the system identity hashcode for an object as a human readable string
Params:
  • x – object
Returns:system identity hashcode as string
/** * Return the system identity hashcode for an object as a human readable * string * * @param x object * @return system identity hashcode as string */
public static String id(final Object x) { return String.format("0x%08x", System.identityHashCode(x)); }
Same as id but returns the identity hashcode as an integer
Params:
  • x – object
Returns:system identity hashcode
/** * Same as {@link Debug#id} but returns the identity hashcode as * an integer * * @param x object * @return system identity hashcode */
public static int intId(final Object x) { return System.identityHashCode(x); }
Return a stack trace element description at a depth from where we are not
Params:
  • depth – depth
Returns:stack trace element as string
/** * Return a stack trace element description at a depth from where we are not * * @param depth depth * @return stack trace element as string */
public static String stackTraceElementAt(final int depth) { return new Throwable().getStackTrace()[depth + 1].toString(); // add 1 to compensate for this method }
Determine caller for tracing purposes.
Params:
  • depth – depth to trace
  • count – max depth
  • ignores – elements to ignore in stack trace
Returns:caller
/** * Determine caller for tracing purposes. * @param depth depth to trace * @param count max depth * @param ignores elements to ignore in stack trace * @return caller */
public static String caller(final int depth, final int count, final String... ignores) { String result = ""; final StackTraceElement[] callers = Thread.currentThread().getStackTrace(); int c = count; loop: for (int i = depth + 1; i < callers.length && c != 0; i++) { final StackTraceElement element = callers[i]; final String method = element.getMethodName(); for (final String ignore : ignores) { if (method.compareTo(ignore) == 0) { continue loop; } } result += (method + ":" + element.getLineNumber() + " ").substring(0, 30); c--; } return result.isEmpty() ? "<no caller>" : result; }
Dump a token stream to stdout TODO: most other bugging goes to stderr, change?
Params:
  • source – the source
  • lexer – the lexer
  • stream – the stream to dump
/** * Dump a token stream to stdout * * TODO: most other bugging goes to stderr, change? * * @param source the source * @param lexer the lexer * @param stream the stream to dump */
public static void dumpTokens(final Source source, final Lexer lexer, final TokenStream stream) { TokenType type; int k = 0; do { while (k > stream.last()) { // Get more tokens. lexer.lexify(); } final long token = stream.get(k); type = Token.descType(token); System.out.println("" + k + ": " + Token.toString(source, token, true)); k++; } while(type != EOF); } }