/* * Copyright (c) 2012, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.tools.debug.core.webkit; import com.google.dart.tools.debug.core.util.DebuggerUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.List; /** * A WIP frame object. * * @see http://code.google.com/chrome/devtools/docs/protocol/tot/debugger.html#type-CallFrame */ public class WebkitCallFrame { static List<WebkitCallFrame> createFrom(JSONArray arr) throws JSONException { List<WebkitCallFrame> frames = new ArrayList<WebkitCallFrame>(); for (int i = 0; i < arr.length(); i++) { WebkitCallFrame frame = createFrom(arr.getJSONObject(i)); // If we are on the first frame and there are at least 3 frames: if (i == 0 && arr.length() > 2) { if (DebuggerUtils.isInternalMethodName(frame.getFunctionName())) { // Strip out the first frame if it's _noSuchMethod. There will be another // "Object.noSuchMethod" on the stack. This sucks, but it's where we're choosing to put // the fix. continue; } } frames.add(frame); } return frames; } private static WebkitCallFrame createFrom(JSONObject object) throws JSONException { WebkitCallFrame frame = new WebkitCallFrame(); frame.callFrameId = JsonUtils.getString(object, "callFrameId"); frame.functionName = JsonUtils.getString(object, "functionName"); frame.location = WebkitLocation.createFrom(object.getJSONObject("location")); frame.thisObject = WebkitRemoteObject.createFrom(object.getJSONObject("this")); if ("null".equals(frame.thisObject.className)) { frame.thisObject = null; } if (object.has("scopeChain")) { frame.scopeChain = WebkitScope.createFrom(object.getJSONArray("scopeChain")); } return frame; } private String callFrameId; private String functionName; private WebkitLocation location; private WebkitScope[] scopeChain; private WebkitRemoteObject thisObject; /** * Call frame identifier. This identifier is only valid while the virtual machine is paused. */ public String getCallFrameId() { return callFrameId; } /** * Name of the Dart function called on this call frame. */ public String getFunctionName() { return functionName; } /** * Return the 'isolate' scope - the list of libraries for the current isolate. */ public WebkitRemoteObject getIsolateScope() { for (WebkitScope scope : getScopeChain()) { if (scope.isIsolate()) { return scope.getObject(); } } return null; } /** * Return the 'libraries' scope - the list of libraries for the current isolate. */ public WebkitRemoteObject getLibrariesScope() { for (WebkitScope scope : getScopeChain()) { if (scope.isLibraries()) { return scope.getObject(); } } return null; } /** * Location in the source code. */ public WebkitLocation getLocation() { return location; } /** * Scope chain for this call frame. */ public WebkitScope[] getScopeChain() { return scopeChain; } /** * This object for this call frame. */ public WebkitRemoteObject getThisObject() { return thisObject; } public boolean isPrivateMethod() { // _bar or foo._bar return functionName.startsWith("_") || functionName.contains("._"); } public boolean isStaticMethod() { return thisObject == null || thisObject.getObjectId() == null; } @Override public String toString() { return "[" + callFrameId + "," + functionName + "]"; } }