blob: a7f6bfafe01a46b40b41fa8dc79d6fa057a2d61d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.jsdt.debug.internal.ui.breakpoints;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.wst.jsdt.core.IFunction;
import org.eclipse.wst.jsdt.core.IJavaScriptElement;
import org.eclipse.wst.jsdt.core.IMember;
import org.eclipse.wst.jsdt.core.IType;
import org.eclipse.wst.jsdt.core.ITypeRoot;
import org.eclipse.wst.jsdt.core.JavaScriptCore;
import org.eclipse.wst.jsdt.core.JavaScriptModelException;
import org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptBreakpoint;
import org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptFunctionBreakpoint;
import org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptLineBreakpoint;
import org.eclipse.wst.jsdt.debug.internal.ui.JavaScriptDebugUIPlugin;
/**
* Collection of utility methods to help get additional information
* from breakpoints
*
* @since 1.0
*/
public class BreakpointHelper {
/**
* Returns the member associated with the line number of
* the given breakpoint.
*
* @param breakpoint JavaScript line breakpoint
* @return member at the given line number in the type
* associated with the breakpoint
* @exception CoreException if an exception occurs accessing
* the breakpoint
*/
public static IMember getMember(IJavaScriptLineBreakpoint breakpoint) throws CoreException {
if (breakpoint instanceof IJavaScriptFunctionBreakpoint) {
return getMethod((IJavaScriptFunctionBreakpoint)breakpoint);
}
int start = breakpoint.getCharStart();
int end = breakpoint.getCharEnd();
IType type = getType(breakpoint);
if (start == -1 && end == -1) {
start = breakpoint.getCharStart();
end = breakpoint.getCharEnd();
}
IMember member = null;
if ((type != null && type.exists()) && (end >= start) && (start >= 0)) {
member = binSearch(type, start, end);
}
if (member == null) {
member= type;
}
return member;
}
/**
* Returns the function associated with the function
* breakpoint.
*
* @param breakpoint JavaScript function breakpoint
* @return function
*/
public static IFunction getMethod(IJavaScriptFunctionBreakpoint breakpoint) {
String handle = breakpoint.getModelIdentifier();
if (handle != null) {
IJavaScriptElement jse = JavaScriptCore.create(handle);
if (jse != null) {
if (jse instanceof IFunction) {
return (IFunction)jse;
}
}
}
return null;
}
/**
* Returns the type that the given JavaScript breakpoint refers to
*
* @param breakpoint JavaScript breakpoint
* @return the type the breakpoint is associated with
*/
public static IType getType(IJavaScriptBreakpoint breakpoint) {
String handle = breakpoint.getModelIdentifier();
if (handle != null) {
IJavaScriptElement jse = JavaScriptCore.create(handle);
if (jse != null) {
if (jse instanceof IType) {
return (IType)jse;
}
if (jse instanceof IMember) {
return ((IMember)jse).getDeclaringType();
}
}
}
return null;
}
/**
* Returns the type that the given JavaScript breakpoint refers to
*
* @param breakpoint JavaScript breakpoint
* @return the type the breakpoint is associated with
*/
public static ITypeRoot getTypeRoot(IJavaScriptBreakpoint breakpoint) {
try {
String handle = breakpoint.getJavaScriptElementHandle();
if (handle != null) {
IJavaScriptElement jse = JavaScriptCore.create(handle);
if (jse != null && jse.exists()) {
if (jse instanceof IType) {
return ((IType)jse).getTypeRoot();
}
if (jse instanceof IMember) {
return ((IMember)jse).getTypeRoot();
}
}
}
}
catch(CoreException ce) {
JavaScriptDebugUIPlugin.log(ce);
}
return null;
}
/**
* Searches the given source range of the container for a member that is
* not the same as the given type.
*/
static IMember binSearch(IType type, int start, int end) throws JavaScriptModelException {
IJavaScriptElement je = getElementAt(type, start);
if (je != null && !je.equals(type)) {
return asMember(je);
}
if (end > start) {
je = getElementAt(type, end);
if (je != null && !je.equals(type)) {
return asMember(je);
}
int mid = ((end - start) / 2) + start;
if (mid > start) {
je = binSearch(type, start + 1, mid);
if (je == null) {
je = binSearch(type, mid + 1, end - 1);
}
return asMember(je);
}
}
return null;
}
/**
* Returns the given JavaScript element if it is an
* <code>IMember</code>, otherwise <code>null</code>.
*
* @param element JavaScript element
* @return the given element if it is a type member,
* otherwise <code>null</code>
*/
static IMember asMember(IJavaScriptElement element) {
if (element instanceof IMember) {
return (IMember)element;
}
return null;
}
/**
* Returns the element at the given position in the given type
*/
static IJavaScriptElement getElementAt(IType type, int pos) throws JavaScriptModelException {
if (type.isBinary()) {
return type.getClassFile().getElementAt(pos);
}
return type.getJavaScriptUnit().getElementAt(pos);
}
}