2 // Use of this source code is governed by a BSD-style license that can be |
2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. |
3 // found in the LICENSE file. |
4 |
4 |
5 package org.chromium.debug.core.model; |
5 package org.chromium.debug.core.model; |
6 |
6 |
|
7 import java.util.ArrayList; |
|
8 import java.util.List; |
|
9 |
7 import org.chromium.debug.core.ChromiumDebugPlugin; |
10 import org.chromium.debug.core.ChromiumDebugPlugin; |
8 import org.chromium.sdk.Breakpoint; |
11 import org.chromium.sdk.Breakpoint; |
|
12 import org.chromium.sdk.JavascriptVm; |
|
13 import org.chromium.sdk.SyncCallback; |
|
14 import org.chromium.sdk.JavascriptVm.BreakpointCallback; |
|
15 import org.eclipse.core.resources.IFile; |
9 import org.eclipse.core.resources.IMarker; |
16 import org.eclipse.core.resources.IMarker; |
10 import org.eclipse.core.resources.IResource; |
17 import org.eclipse.core.resources.IResource; |
11 import org.eclipse.core.resources.IWorkspaceRunnable; |
18 import org.eclipse.core.resources.IWorkspaceRunnable; |
12 import org.eclipse.core.runtime.CoreException; |
19 import org.eclipse.core.runtime.CoreException; |
13 import org.eclipse.core.runtime.IProgressMonitor; |
20 import org.eclipse.core.runtime.IProgressMonitor; |
|
21 import org.eclipse.debug.core.IBreakpointManager; |
14 import org.eclipse.debug.core.model.IBreakpoint; |
22 import org.eclipse.debug.core.model.IBreakpoint; |
15 import org.eclipse.debug.core.model.LineBreakpoint; |
23 import org.eclipse.debug.core.model.LineBreakpoint; |
16 import org.eclipse.osgi.util.NLS; |
24 import org.eclipse.osgi.util.NLS; |
17 |
25 |
18 /** |
26 /** |
23 /** Ignore count */ |
31 /** Ignore count */ |
24 private static final String IGNORE_COUNT_ATTR = ChromiumDebugPlugin.PLUGIN_ID + ".ignoreCount"; //$NON-NLS-1$ |
32 private static final String IGNORE_COUNT_ATTR = ChromiumDebugPlugin.PLUGIN_ID + ".ignoreCount"; //$NON-NLS-1$ |
25 |
33 |
26 /** Condition */ |
34 /** Condition */ |
27 private static final String CONDITION_ATTR = ChromiumDebugPlugin.PLUGIN_ID + ".condition"; //$NON-NLS-1$ |
35 private static final String CONDITION_ATTR = ChromiumDebugPlugin.PLUGIN_ID + ".condition"; //$NON-NLS-1$ |
28 |
|
29 private Breakpoint browserBreakpoint; |
|
30 |
36 |
31 /** |
37 /** |
32 * Default constructor is required for the breakpoint manager to re-create |
38 * Default constructor is required for the breakpoint manager to re-create |
33 * persisted breakpoints. After instantiating a breakpoint, the setMarker |
39 * persisted breakpoints. After instantiating a breakpoint, the setMarker |
34 * method is called to restore this breakpoint's attributes. |
40 * method is called to restore this breakpoint's attributes. |
35 */ |
41 */ |
36 // FIXME(apavlov): now this does not restore the browserBreakpoint value |
|
37 public ChromiumLineBreakpoint() { |
42 public ChromiumLineBreakpoint() { |
38 } |
|
39 |
|
40 public void setBreakpoint(Breakpoint breakpoint) { |
|
41 this.browserBreakpoint = breakpoint; |
|
42 } |
|
43 |
|
44 public Breakpoint getBrowserBreakpoint() { |
|
45 return browserBreakpoint; |
|
46 } |
43 } |
47 |
44 |
48 /** |
45 /** |
49 * Constructs a line breakpoint on the given resource at the given line number |
46 * Constructs a line breakpoint on the given resource at the given line number |
50 * (line number is 1-based). |
47 * (line number is 1-based). |
51 * |
48 * |
52 * @param resource file on which to set the breakpoint |
49 * @param resource file on which to set the breakpoint |
53 * @param lineNumber 1-based line number of the breakpoint |
50 * @param lineNumber 1-based line number of the breakpoint |
54 * @throws CoreException if unable to create the breakpoint |
51 * @throws CoreException if unable to create the breakpoint |
55 */ |
52 */ |
56 public ChromiumLineBreakpoint(final IResource resource, final int lineNumber) |
53 public ChromiumLineBreakpoint(final IResource resource, final int lineNumber, |
57 throws CoreException { |
54 final String modelId) throws CoreException { |
58 IWorkspaceRunnable runnable = new IWorkspaceRunnable() { |
55 IWorkspaceRunnable runnable = new IWorkspaceRunnable() { |
59 public void run(IProgressMonitor monitor) throws CoreException { |
56 public void run(IProgressMonitor monitor) throws CoreException { |
60 IMarker marker = resource.createMarker(ChromiumDebugPlugin.BP_MARKER); |
57 IMarker marker = resource.createMarker(ChromiumDebugPlugin.BP_MARKER); |
61 setMarker(marker); |
58 setMarker(marker); |
62 marker.setAttribute(IBreakpoint.ENABLED, Boolean.TRUE); |
59 marker.setAttribute(IBreakpoint.ENABLED, Boolean.TRUE); |
63 marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); |
60 marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); |
64 marker.setAttribute(IBreakpoint.ID, getModelIdentifier()); |
61 marker.setAttribute(IBreakpoint.ID, modelId); |
65 marker.setAttribute(IMarker.MESSAGE, NLS.bind( |
62 marker.setAttribute(IMarker.MESSAGE, NLS.bind( |
66 Messages.JsLineBreakpoint_MessageMarkerFormat, resource.getName(), lineNumber)); |
63 Messages.JsLineBreakpoint_MessageMarkerFormat, resource.getName(), lineNumber)); |
67 } |
64 } |
68 }; |
65 }; |
69 run(getMarkerRule(resource), runnable); |
66 run(getMarkerRule(resource), runnable); |
102 public String getCondition() { |
99 public String getCondition() { |
103 return getMarker().getAttribute(CONDITION_ATTR, null); |
100 return getMarker().getAttribute(CONDITION_ATTR, null); |
104 } |
101 } |
105 |
102 |
106 public String getModelIdentifier() { |
103 public String getModelIdentifier() { |
107 return VProjectWorkspaceBridge.DEBUG_MODEL_ID; |
104 return getMarker().getAttribute(IBreakpoint.ID, ""); |
108 } |
105 } |
109 |
106 |
110 public void changed() { |
107 /** |
111 if (browserBreakpoint != null) { |
108 * A helper that propagates changes in Eclipse Debugger breakpoints (i.e. |
112 browserBreakpoint.setCondition(getCondition()); |
109 * {@link ChromiumLineBreakpoint}) to ChromeDevTools SDK breakpoints. Note that |
113 browserBreakpoint.setEnabled(isEnabled()); |
110 * {@link ChromiumLineBreakpoint} can't do it itself, because it may correspond to several |
114 browserBreakpoint.setIgnoreCount(getIgnoreCount()); |
111 * SDK {@link JavascriptVm}'s simultaneously. |
115 browserBreakpoint.flush(null); |
112 */ |
116 } |
113 public static class Helper { |
117 } |
114 public interface CreateOnRemoveCallback { |
118 |
115 void success(Breakpoint breakpoint); |
119 public void clear() { |
116 void failure(String errorMessage); |
120 if (browserBreakpoint != null) { |
117 } |
121 browserBreakpoint.clear(null); |
118 |
|
119 public static void createOnRemote(ChromiumLineBreakpoint uiBreakpoint, |
|
120 VmResourceId scriptId, DebugTargetImpl debugTarget, |
|
121 final CreateOnRemoveCallback createOnRemoveCallback, |
|
122 SyncCallback syncCallback) throws CoreException { |
|
123 JavascriptVm javascriptVm = debugTarget.getJavascriptEmbedder().getJavascriptVm(); |
|
124 |
|
125 // ILineBreakpoint lines are 1-based while V8 lines are 0-based |
|
126 final int line = (uiBreakpoint.getLineNumber() - 1); |
|
127 BreakpointCallback callback = new BreakpointCallback() { |
|
128 public void success(Breakpoint sdkBreakpoint) { |
|
129 createOnRemoveCallback.success(sdkBreakpoint); |
|
130 } |
|
131 public void failure(String errorMessage) { |
|
132 createOnRemoveCallback.failure(errorMessage); |
|
133 } |
|
134 }; |
|
135 |
|
136 javascriptVm.setBreakpoint(scriptId.getTypeForBreakpoint(), |
|
137 scriptId.getTargetForBreakpoint(), |
|
138 line, |
|
139 Breakpoint.EMPTY_VALUE, |
|
140 uiBreakpoint.isEnabled(), |
|
141 uiBreakpoint.getCondition(), |
|
142 uiBreakpoint.getIgnoreCount(), |
|
143 callback, syncCallback); |
|
144 } |
|
145 |
|
146 public static void updateOnRemote(Breakpoint sdkBreakpoint, |
|
147 ChromiumLineBreakpoint uiBreakpoint) { |
|
148 sdkBreakpoint.setCondition(uiBreakpoint.getCondition()); |
|
149 sdkBreakpoint.setEnabled(uiBreakpoint.isEnabled()); |
|
150 sdkBreakpoint.setIgnoreCount(uiBreakpoint.getIgnoreCount()); |
|
151 sdkBreakpoint.flush(null, null); |
|
152 } |
|
153 |
|
154 public static ChromiumLineBreakpoint createLocal(Breakpoint sdkBreakpoint, |
|
155 IBreakpointManager breakpointManager, IFile resource, int script_line_offset, |
|
156 String debugModelId) throws CoreException { |
|
157 ChromiumLineBreakpoint uiBreakpoint = new ChromiumLineBreakpoint(resource, |
|
158 (int) sdkBreakpoint.getLineNumber() + 1 + script_line_offset, |
|
159 debugModelId); |
|
160 uiBreakpoint.setCondition(sdkBreakpoint.getCondition()); |
|
161 uiBreakpoint.setEnabled(sdkBreakpoint.isEnabled()); |
|
162 uiBreakpoint.setIgnoreCount(sdkBreakpoint.getIgnoreCount()); |
|
163 ignoreList.add(uiBreakpoint); |
|
164 try { |
|
165 breakpointManager.addBreakpoint(uiBreakpoint); |
|
166 } finally { |
|
167 ignoreList.remove(uiBreakpoint); |
|
168 } |
|
169 return uiBreakpoint; |
|
170 } |
|
171 } |
|
172 |
|
173 private static final BreakpointIgnoreList ignoreList = new BreakpointIgnoreList(); |
|
174 |
|
175 public static BreakpointIgnoreList getIgnoreList() { |
|
176 return ignoreList; |
|
177 } |
|
178 |
|
179 public static class BreakpointIgnoreList { |
|
180 private final List<ChromiumLineBreakpoint> list = new ArrayList<ChromiumLineBreakpoint>(1); |
|
181 |
|
182 public boolean contains(IBreakpoint breakpoint) { |
|
183 return list.contains(breakpoint); |
|
184 } |
|
185 |
|
186 public void remove(ChromiumLineBreakpoint lineBreakpoint) { |
|
187 boolean res = list.remove(lineBreakpoint); |
|
188 if (!res) { |
|
189 throw new IllegalStateException(); |
|
190 } |
|
191 } |
|
192 |
|
193 public void add(ChromiumLineBreakpoint lineBreakpoint) { |
|
194 if (list.contains(lineBreakpoint)) { |
|
195 throw new IllegalStateException(); |
|
196 } |
|
197 list.add(lineBreakpoint); |
122 } |
198 } |
123 } |
199 } |
124 } |
200 } |