Skip to content

Commit 0185405

Browse files
committed
Merge pull request #45 from Genuitec/master
Issue #2: Support for debugging TypeScript with JavaScript Debugger.
2 parents 69395d6 + 43e8215 commit 0185405

File tree

6 files changed

+333
-1
lines changed

6 files changed

+333
-1
lines changed

eclipse/jsdt/ts.eclipse.ide.jsdt.ui/META-INF/MANIFEST.MF

+4-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ Require-Bundle: org.eclipse.core.runtime,
2525
org.eclipse.ui.ide,
2626
ts.eclipse.ide.core,
2727
ts.eclipse.ide.ui,
28-
org.eclipse.ui.workbench.texteditor
28+
org.eclipse.ui.workbench.texteditor,
29+
org.eclipse.debug.ui,
30+
org.eclipse.wst.jsdt.debug.ui,
31+
org.eclipse.wst.jsdt.debug.core
2932
Bundle-ActivationPolicy: lazy
3033
Bundle-Activator: ts.eclipse.ide.jsdt.internal.ui.JSDTTypeScriptUIPlugin
3134
Import-Package: com.eclipsesource.json;version="[0.9.4,0.9.5)"
Loading

eclipse/jsdt/ts.eclipse.ide.jsdt.ui/plugin.properties

+10
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,13 @@ ActionDefinition.format.description= Format the selected text
5656

5757
ActionDefinition.referencesInProject.name= References in Project
5858
ActionDefinition.referencesInProject.description= Search for references to the selected element in the enclosing project
59+
60+
##########################################################################
61+
# Debugging support
62+
##########################################################################
63+
togglebreakpointRulerAction.name = Toggle Breakpoint
64+
breakpointpropertiesRulerAction.name = Breakpoint &Properties
65+
breakpointpropertiesRulerAction.tooltip = Displays the properties dialog for the selected breakpoint
66+
togglebreakpointenablementRulerAction.name = To&ggle Breakpoint Enablement
67+
togglebreakpointenablementRulerAction.tooltip = Allows the enabled state of the breakpoint to be changed
68+

eclipse/jsdt/ts.eclipse.ide.jsdt.ui/plugin.xml

+62
Original file line numberDiff line numberDiff line change
@@ -260,4 +260,66 @@
260260
point="org.eclipse.ui.startup">
261261
<startup class="ts.eclipse.ide.jsdt.internal.ui.JSDTTypeScriptStartup" />
262262
</extension>
263+
264+
<!-- debugging support -->
265+
<extension
266+
point="org.eclipse.core.runtime.adapters">
267+
<factory
268+
adaptableType="ts.eclipse.ide.jsdt.internal.ui.editor.TypeScriptEditor"
269+
class="ts.eclipse.ide.jsdt.internal.ui.editor.breakpoints.TypeScriptAdapterFactory">
270+
<adapter
271+
type="org.eclipse.debug.ui.actions.IToggleBreakpointsTarget">
272+
</adapter>
273+
</factory>
274+
</extension>
275+
276+
<extension
277+
point="org.eclipse.ui.editorActions">
278+
<editorContribution
279+
id="ts.eclipse.ide.jsdt.debug.ui.togglebreakpoint"
280+
targetID="ts.eclipse.ide.jsdt.ui.editor.TypeScriptEditor">
281+
<action
282+
actionID="RulerDoubleClick"
283+
class="org.eclipse.debug.ui.actions.RulerToggleBreakpointActionDelegate"
284+
helpContextId="editor_toggle_breakpoint_action_context"
285+
icon="icons/full/obj16/brkp_obj.gif"
286+
id="org.eclipse.wst.jsdt.debug.ui.RulerToggleBreakpoint"
287+
label="%togglebreakpointRulerAction.name">
288+
</action>
289+
</editorContribution>
290+
</extension>
291+
292+
293+
<extension
294+
point="org.eclipse.ui.popupMenus">
295+
<viewerContribution
296+
id="ts.eclipse.ide.jsdt.debug.ui.ruler.popup.actions"
297+
targetID="ts.eclipse.ide.jsdt.ui.editor.TypeScriptEditor.RulerContext">
298+
<action
299+
class="org.eclipse.debug.ui.actions.RulerToggleBreakpointActionDelegate"
300+
helpContextId="editor_toggle_breakpoint_action_context"
301+
icon="icons/full/obj16/brkp_obj.gif"
302+
id="org.eclipse.wst.jsdt.debug.ui.toggle.breakpoint.ruler.delegate"
303+
label="%togglebreakpointRulerAction.name"
304+
menubarPath="debug">
305+
</action>
306+
<action
307+
class="org.eclipse.wst.jsdt.debug.internal.ui.breakpoints.BreakpointPropertiesEditorActionDelegate"
308+
helpContextId="breakpoint_properties_editor_ruler_context"
309+
id="org.eclipse.wst.jsdt.debug.ui.ruler.breakpoint.properties"
310+
label="%breakpointpropertiesRulerAction.name"
311+
menubarPath="group.properties"
312+
tooltip="%breakpointpropertiesRulerAction.tooltip">
313+
</action>
314+
<action
315+
class="org.eclipse.wst.jsdt.debug.internal.ui.breakpoints.ToggleBreakpointEnablementEditorDelegate"
316+
helpContextId="toggle_breakpoint_anablement_ruler_context"
317+
id="org.eclipse.wst.jsdt.debug.ui.toggle.breakpoint.enablement"
318+
label="%togglebreakpointenablementRulerAction.name"
319+
menubarPath="debug"
320+
tooltip="%togglebreakpointenablementRulerAction.tooltip">
321+
</action>
322+
</viewerContribution>
323+
</extension>
324+
263325
</plugin>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2010-2016 IBM Corporation and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* IBM Corporation - initial API and implementation
10+
* Genuitec LLC - adapted for TypeScript editor
11+
*******************************************************************************/
12+
package ts.eclipse.ide.jsdt.internal.ui.editor.breakpoints;
13+
14+
import java.util.HashMap;
15+
16+
import org.eclipse.core.resources.IFile;
17+
import org.eclipse.core.resources.IResource;
18+
import org.eclipse.core.runtime.CoreException;
19+
import org.eclipse.core.runtime.IProgressMonitor;
20+
import org.eclipse.core.runtime.IStatus;
21+
import org.eclipse.core.runtime.Status;
22+
import org.eclipse.core.runtime.jobs.Job;
23+
import org.eclipse.debug.core.DebugPlugin;
24+
import org.eclipse.debug.core.model.IBreakpoint;
25+
import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension;
26+
import org.eclipse.jface.text.BadLocationException;
27+
import org.eclipse.jface.text.IDocument;
28+
import org.eclipse.jface.text.IRegion;
29+
import org.eclipse.jface.text.ITextSelection;
30+
import org.eclipse.jface.text.TextSelection;
31+
import org.eclipse.jface.viewers.ISelection;
32+
import org.eclipse.swt.widgets.Display;
33+
import org.eclipse.ui.IEditorInput;
34+
import org.eclipse.ui.IEditorPart;
35+
import org.eclipse.ui.IWorkbenchPart;
36+
import org.eclipse.ui.texteditor.IDocumentProvider;
37+
import org.eclipse.ui.texteditor.IEditorStatusLine;
38+
import org.eclipse.ui.texteditor.ITextEditor;
39+
import org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptBreakpoint;
40+
import org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptLineBreakpoint;
41+
import org.eclipse.wst.jsdt.debug.core.model.JavaScriptDebugModel;
42+
43+
/**
44+
* Adapter for toggling JavaScript breakpoints in the TypeScript editor
45+
*/
46+
public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtension {
47+
48+
public boolean canToggleBreakpoints(IWorkbenchPart part, ISelection selection) {
49+
return selection instanceof ITextSelection;
50+
}
51+
52+
public boolean canToggleLineBreakpoints(IWorkbenchPart part, ISelection selection) {
53+
return selection instanceof ITextSelection;
54+
}
55+
56+
public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) {
57+
return false;
58+
}
59+
60+
public boolean canToggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) {
61+
return false;
62+
}
63+
64+
public void toggleWatchpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
65+
//do nothing
66+
}
67+
68+
public void toggleMethodBreakpoints(final IWorkbenchPart part, final ISelection selection) throws CoreException {
69+
//do nothing
70+
}
71+
72+
public void toggleBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
73+
if(selection instanceof ITextSelection) {
74+
ITextEditor textEditor = getTextEditor(part);
75+
if(textEditor == null) {
76+
reportToStatusLine(part, "No editor could be found for the associated part");
77+
return;
78+
}
79+
toggleLineBreakpoint(part, (ITextSelection) selection, ((TextSelection)selection).getStartLine()+1);
80+
}
81+
}
82+
83+
public void toggleLineBreakpoints(final IWorkbenchPart part, final ISelection selection) throws CoreException {
84+
if (!(part instanceof IEditorPart) || !(selection instanceof ITextSelection)) {
85+
return;
86+
}
87+
88+
ITextEditor textEditor = (ITextEditor) part.getAdapter(ITextEditor.class);
89+
if (textEditor != null) {
90+
IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
91+
if (document != null) {
92+
int lineNumber;
93+
try {
94+
lineNumber = document.getLineOfOffset(((ITextSelection) selection).getOffset());
95+
IResource res = getResource((IEditorPart) part);
96+
if (res != null) {
97+
addBreakpoint(res, document, lineNumber + 1);
98+
}
99+
}
100+
catch (BadLocationException e) {
101+
e.printStackTrace();
102+
}
103+
}
104+
}
105+
}
106+
107+
void toggleLineBreakpoint(final IWorkbenchPart part, final ITextSelection selection, final int linenumber) {
108+
Job job = new Job("Toggle Line Breakpoints") {
109+
protected IStatus run(IProgressMonitor monitor) {
110+
try {
111+
ITextEditor editor = getTextEditor(part);
112+
if(editor != null && part instanceof IEditorPart) {
113+
IResource resource = getResource((IEditorPart)part);
114+
if(resource == null) {
115+
resource = getResource((IEditorPart)part);
116+
reportToStatusLine(part, "Failed to create Javascript line breakpoint - the resource could no be computed");
117+
return Status.CANCEL_STATUS;
118+
}
119+
IBreakpoint bp = lineBreakpointExists(resource, linenumber);
120+
if(bp != null) {
121+
DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(bp, true);
122+
return Status.OK_STATUS;
123+
}
124+
IDocumentProvider documentProvider = editor.getDocumentProvider();
125+
IDocument document = documentProvider.getDocument(editor.getEditorInput());
126+
int charstart = -1, charend = -1;
127+
try {
128+
IRegion line = document.getLineInformation(linenumber - 1);
129+
charstart = line.getOffset();
130+
charend = charstart + line.getLength();
131+
}
132+
catch (BadLocationException ble) {}
133+
HashMap<String, String> attributes = new HashMap<String, String>();
134+
attributes.put(IJavaScriptBreakpoint.TYPE_NAME, null);
135+
attributes.put(IJavaScriptBreakpoint.SCRIPT_PATH, resource.getFullPath().makeAbsolute().toString());
136+
attributes.put(IJavaScriptBreakpoint.ELEMENT_HANDLE, null);
137+
JavaScriptDebugModel.createLineBreakpoint(resource, linenumber, charstart, charend, attributes, true);
138+
return Status.OK_STATUS;
139+
}
140+
reportToStatusLine(part, "Failed to create Javascript line breakpoint");
141+
return Status.CANCEL_STATUS;
142+
}
143+
catch(CoreException ce) {
144+
return ce.getStatus();
145+
}
146+
}
147+
};
148+
job.setPriority(Job.INTERACTIVE);
149+
job.setSystem(true);
150+
job.schedule();
151+
}
152+
153+
void addBreakpoint(IResource resource, IDocument document, int linenumber) throws CoreException {
154+
IBreakpoint bp = lineBreakpointExists(resource, linenumber);
155+
if(bp != null) {
156+
DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(bp, true);
157+
}
158+
int charstart = -1, charend = -1;
159+
try {
160+
IRegion line = document.getLineInformation(linenumber - 1);
161+
charstart = line.getOffset();
162+
charend = charstart + line.getLength();
163+
}
164+
catch (BadLocationException ble) {}
165+
HashMap<String, String> attributes = new HashMap<String, String>();
166+
attributes.put(IJavaScriptBreakpoint.TYPE_NAME, null);
167+
attributes.put(IJavaScriptBreakpoint.SCRIPT_PATH, resource.getFullPath().makeAbsolute().toString());
168+
attributes.put(IJavaScriptBreakpoint.ELEMENT_HANDLE, null);
169+
JavaScriptDebugModel.createLineBreakpoint(resource, linenumber, charstart, charend, attributes, true);
170+
}
171+
172+
void reportToStatusLine(final IWorkbenchPart part, final String message) {
173+
getStandardDisplay().asyncExec(new Runnable() {
174+
public void run() {
175+
IEditorStatusLine statusLine = (IEditorStatusLine) part.getAdapter(IEditorStatusLine.class);
176+
if (statusLine != null) {
177+
if (message != null) {
178+
statusLine.setMessage(true, message, null);
179+
} else {
180+
statusLine.setMessage(true, null, null);
181+
}
182+
}
183+
}
184+
});
185+
}
186+
187+
Display getStandardDisplay() {
188+
Display display;
189+
display = Display.getCurrent();
190+
if (display == null) {
191+
display = Display.getDefault();
192+
}
193+
return display;
194+
}
195+
196+
IBreakpoint lineBreakpointExists(IResource resource, int linenumber) {
197+
IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(JavaScriptDebugModel.MODEL_ID);
198+
IJavaScriptLineBreakpoint breakpoint = null;
199+
for (int i = 0; i < breakpoints.length; i++) {
200+
if(breakpoints[i] instanceof IJavaScriptLineBreakpoint) {
201+
breakpoint = (IJavaScriptLineBreakpoint) breakpoints[i];
202+
try {
203+
if(IJavaScriptLineBreakpoint.MARKER_ID.equals(breakpoint.getMarker().getType()) &&
204+
resource.equals(breakpoint.getMarker().getResource()) &&
205+
linenumber == breakpoint.getLineNumber()) {
206+
return breakpoint;
207+
}
208+
} catch (CoreException e) {}
209+
}
210+
}
211+
return null;
212+
}
213+
214+
IResource getResource(IEditorPart editor) {
215+
IEditorInput editorInput = editor.getEditorInput();
216+
return (IResource) editorInput.getAdapter(IFile.class);
217+
}
218+
219+
ITextEditor getTextEditor(IWorkbenchPart part) {
220+
if (part instanceof ITextEditor) {
221+
return (ITextEditor) part;
222+
}
223+
return (ITextEditor) part.getAdapter(ITextEditor.class);
224+
}
225+
226+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package ts.eclipse.ide.jsdt.internal.ui.editor.breakpoints;
2+
3+
import org.eclipse.core.runtime.IAdapterFactory;
4+
import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
5+
6+
/**
7+
* Adapter factory for breakpoints
8+
*/
9+
public class TypeScriptAdapterFactory implements IAdapterFactory {
10+
11+
static ToggleBreakpointAdapter tbadapter = null;
12+
13+
public Object getAdapter(Object adaptableObject, Class adapterType) {
14+
if (adapterType.equals(IToggleBreakpointsTarget.class)) {
15+
return getToggleBreakpointAdapter();
16+
}
17+
return null;
18+
}
19+
20+
public Class[] getAdapterList() {
21+
return new Class[] { IToggleBreakpointsTarget.class };
22+
}
23+
24+
public static synchronized ToggleBreakpointAdapter getToggleBreakpointAdapter() {
25+
if (tbadapter == null) {
26+
tbadapter = new ToggleBreakpointAdapter();
27+
}
28+
return tbadapter;
29+
}
30+
31+
}

0 commit comments

Comments
 (0)