Skip to content

Commit 3636325

Browse files
committed
Introduce debug adapter protocol
Signed-off-by: Anatoliy Bazko <[email protected]>
1 parent ca50055 commit 3636325

39 files changed

+5318
-121
lines changed

examples/browser/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
"@theia/callhierarchy": "^0.3.13",
77
"@theia/core": "^0.3.13",
88
"@theia/cpp": "^0.3.13",
9+
"@theia/debug": "^0.3.13",
10+
"@theia/debug-nodejs": "^0.3.13",
911
"@theia/editor": "^0.3.13",
1012
"@theia/editorconfig": "^0.3.13",
1113
"@theia/extension-manager": "^0.3.13",

examples/electron/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
"@theia/callhierarchy": "^0.3.13",
1010
"@theia/core": "^0.3.13",
1111
"@theia/cpp": "^0.3.13",
12+
"@theia/debug": "^0.3.13",
13+
"@theia/debug-nodejs": "^0.3.13",
1214
"@theia/editor": "^0.3.13",
1315
"@theia/editorconfig": "^0.3.13",
1416
"@theia/extension-manager": "^0.3.13",
@@ -55,4 +57,4 @@
5557
"devDependencies": {
5658
"@theia/cli": "^0.3.13"
5759
}
58-
}
60+
}

packages/core/src/browser/shell/tab-bars.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export class TabBarRenderer extends TabBar.Renderer {
104104
const iconSize = data.iconSize;
105105
let height: string | undefined;
106106
if (labelSize || iconSize) {
107-
const labelHeight = labelSize ? labelSize.width : 0;
107+
const labelHeight = labelSize ? (this.tabBar && this.tabBar.orientation === 'horizontal' ? labelSize.height : labelSize.width) : 0;
108108
const iconHeight = iconSize ? iconSize.height : 0;
109109
let paddingTop = data.paddingTop || 0;
110110
if (labelHeight > 0 && iconHeight > 0) {

packages/debug-nodejs/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Theia - NodeJS Debug Extension
2+
3+
See [here](https://github.com/theia-ide/theia) for a detailed documentation.
4+
5+
## License
6+
[Apache-2.0](https://github.com/theia-ide/theia/blob/master/LICENSE)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"extends": "../../configs/base.tsconfig",
3+
"compilerOptions": {
4+
"rootDir": "src",
5+
"outDir": "lib"
6+
},
7+
"include": [
8+
"src"
9+
]
10+
}
Binary file not shown.

packages/debug-nodejs/gulpfile.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// @ts-ignore
2+
const packageJson = require('./package.json');
3+
4+
// @ts-check
5+
const fs = require('fs');
6+
const path = require('path');
7+
const gulp = require('gulp');
8+
const cp = require('child_process');
9+
const decompress = require('gulp-decompress');
10+
const download = require('gulp-download');
11+
const debugAdapterDir = packageJson['debugAdapter']['dir'];
12+
const debugAdapterDownloadUri = packageJson['debugAdapter']['downloadUri'];
13+
const downloadPath = path.join(__dirname, 'download');
14+
const archivePath = path.join(downloadPath, path.basename(debugAdapterDownloadUri));
15+
16+
function decompressArchive() {
17+
gulp.src(archivePath)
18+
.pipe(decompress())
19+
.pipe(gulp.dest(debugAdapterDir))
20+
}
21+
22+
gulp.task('download_nodejs_debug_adapter', () => {
23+
if (fs.existsSync(archivePath)) {
24+
decompressArchive();
25+
} else {
26+
download(debugAdapterDownloadUri)
27+
.pipe(gulp.dest(downloadPath))
28+
.on('end', () =>
29+
decompressArchive()
30+
);
31+
}
32+
});

packages/debug-nodejs/package.json

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"name": "@theia/debug-nodejs",
3+
"version": "0.3.13",
4+
"description": "Theia - NodeJS Debug Extension",
5+
"dependencies": {
6+
"@theia/debug": "^0.3.13",
7+
"vscode-debugprotocol": "^1.26.0"
8+
},
9+
"publishConfig": {
10+
"access": "public"
11+
},
12+
"theiaExtensions": [
13+
{
14+
"backend": "lib/node/debug-nodejs-backend-module"
15+
}
16+
],
17+
"keywords": [
18+
"theia-extension, debug, nodejs"
19+
],
20+
"license": "Apache-2.0",
21+
"repository": {
22+
"type": "git",
23+
"url": "https://github.com/theia-ide/theia.git"
24+
},
25+
"bugs": {
26+
"url": "https://github.com/theia-ide/theia/issues"
27+
},
28+
"homepage": "https://github.com/theia-ide/theia",
29+
"files": [
30+
"lib",
31+
"src"
32+
],
33+
"scripts": {
34+
"prepare": "yarn run clean && yarn run build",
35+
"clean": "theiaext clean",
36+
"build": "concurrently -n download,build -c red,blue \"gulp download_nodejs_debug_adapter\" \"theiaext build\"",
37+
"watch": "theiaext watch",
38+
"test": "theiaext test",
39+
"docs": "theiaext docs"
40+
},
41+
"devDependencies": {
42+
"@theia/ext-scripts": "^0.3.13",
43+
"gulp": "^3.9.1",
44+
"gulp-decompress": "^2.0.1",
45+
"gulp-download": "0.0.1"
46+
},
47+
"nyc": {
48+
"extends": "../../configs/nyc.json"
49+
},
50+
"debugAdapter": {
51+
"downloadUri": "https://github.com/tolusha/node-debug/releases/download/v1.23.5/vscode-node-debug.tar.gz",
52+
"dir": "lib/adapter"
53+
}
54+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/********************************************************************************
2+
* Copyright (C) 2018 Red Hat, Inc. and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the Eclipse
10+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
11+
* with the GNU Classpath Exception which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
********************************************************************************/
16+
17+
import { ContainerModule } from 'inversify';
18+
import { NodeJsDebugAdapterContribution } from './debug-nodejs';
19+
import { DebugAdapterContribution } from '@theia/debug/lib/node/debug-model';
20+
21+
export default new ContainerModule(bind => {
22+
bind(DebugAdapterContribution).to(NodeJsDebugAdapterContribution).inSingletonScope();
23+
});
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/********************************************************************************
2+
* Copyright (C) 2018 Red Hat, Inc. and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the Eclipse
10+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
11+
* with the GNU Classpath Exception which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
********************************************************************************/
16+
17+
const path = require('path');
18+
const packageJson = require('../../package.json');
19+
const debugAdapterDir = packageJson['debugAdapter']['dir'];
20+
21+
import { injectable } from 'inversify';
22+
import { DebugConfiguration } from '@theia/debug/lib/common/debug-common';
23+
import { DebugAdapterContribution, DebugAdapterExecutable } from '@theia/debug/lib/node/debug-model';
24+
25+
@injectable()
26+
export class NodeJsDebugAdapterContribution implements DebugAdapterContribution {
27+
readonly debugType = 'node';
28+
29+
provideDebugConfigurations = [{
30+
type: this.debugType,
31+
breakpoints: { filePatterns: ['[.]js$', '[.]ts$'] },
32+
request: 'attach',
33+
name: 'Attach by PID',
34+
processId: ''
35+
}];
36+
37+
resolveDebugConfiguration(config: DebugConfiguration): DebugConfiguration {
38+
config.breakpoints = { filePatterns: ['[.]js$', '[.]ts$'] };
39+
40+
if (!config.request) {
41+
throw new Error('Debug request type is not provided.');
42+
}
43+
44+
switch (config.request) {
45+
case 'attach': this.validateAttachConfig(config);
46+
}
47+
48+
return config;
49+
}
50+
51+
provideDebugAdapterExecutable(config: DebugConfiguration): DebugAdapterExecutable {
52+
const program = path.join(__dirname, `../../${debugAdapterDir}/out/src/nodeDebug.js`);
53+
return {
54+
program,
55+
runtime: 'node'
56+
};
57+
}
58+
59+
private validateAttachConfig(config: DebugConfiguration) {
60+
if (!config.processId) {
61+
throw new Error('PID is not provided.');
62+
}
63+
}
64+
}

packages/debug/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Theia - Debug Extension
2+
3+
See [here](https://github.com/theia-ide/theia) for a detailed documentation.
4+
5+
## License
6+
[Apache-2.0](https://github.com/theia-ide/theia/blob/master/LICENSE)

packages/debug/compile.tsconfig.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"extends": "../../configs/base.tsconfig",
3+
"compilerOptions": {
4+
"rootDir": "src",
5+
"outDir": "lib"
6+
},
7+
"include": [
8+
"src"
9+
]
10+
}

packages/debug/package.json

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"name": "@theia/debug",
3+
"version": "0.3.13",
4+
"description": "Theia - Debug Extension",
5+
"dependencies": {
6+
"@theia/core": "^0.3.13",
7+
"@theia/editor": "^0.3.13",
8+
"@theia/monaco": "^0.3.13",
9+
"@theia/process": "^0.3.13",
10+
"vscode-debugprotocol": "^1.26.0"
11+
},
12+
"publishConfig": {
13+
"access": "public"
14+
},
15+
"theiaExtensions": [
16+
{
17+
"frontend": "lib/browser/debug-frontend-module",
18+
"backend": "lib/node/debug-backend-module"
19+
}
20+
],
21+
"keywords": [
22+
"theia-extension, debug"
23+
],
24+
"license": "Apache-2.0",
25+
"repository": {
26+
"type": "git",
27+
"url": "https://github.com/theia-ide/theia.git"
28+
},
29+
"bugs": {
30+
"url": "https://github.com/theia-ide/theia/issues"
31+
},
32+
"homepage": "https://github.com/theia-ide/theia",
33+
"files": [
34+
"lib"
35+
],
36+
"scripts": {
37+
"prepare": "yarn run clean && yarn run build",
38+
"clean": "theiaext clean",
39+
"build": "theiaext build",
40+
"watch": "theiaext watch",
41+
"test": "theiaext test",
42+
"docs": "theiaext docs"
43+
},
44+
"devDependencies": {
45+
"@theia/ext-scripts": "^0.3.13"
46+
},
47+
"nyc": {
48+
"extends": "../../configs/nyc.json"
49+
}
50+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/********************************************************************************
2+
* Copyright (C) 2018 Red Hat, Inc. and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the Eclipse
10+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
11+
* with the GNU Classpath Exception which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
********************************************************************************/
16+
17+
import { injectable, inject } from 'inversify';
18+
import { DebugProtocol } from 'vscode-debugprotocol';
19+
import { BreakpointStorage } from './breakpoint-marker';
20+
import { DebugUtils } from '../debug-utils';
21+
import { DebugSession } from '../debug-model';
22+
23+
/**
24+
* Applies session breakpoints.
25+
*/
26+
@injectable()
27+
export class BreakpointsApplier {
28+
constructor(@inject(BreakpointStorage) protected readonly storage: BreakpointStorage) { }
29+
30+
applySessionBreakpoints(debugSession: DebugSession, source?: DebugProtocol.Source): Promise<void> {
31+
const promises: Promise<void>[] = [];
32+
33+
const breakpoints = this.storage.get(DebugUtils.isSourceBreakpoint)
34+
.filter(b => b.sessionId === debugSession.sessionId)
35+
.filter(b => source ? DebugUtils.checkUri(b, DebugUtils.toUri(source)) : true);
36+
37+
for (const breakpointsBySource of DebugUtils.groupBySource(breakpoints).values()) {
38+
const args: DebugProtocol.SetBreakpointsArguments = {
39+
source: breakpointsBySource[0].source!,
40+
breakpoints: breakpointsBySource.map(b => b.origin as DebugProtocol.SourceBreakpoint),
41+
// Although marked as deprecated, some debug adapters still use lines
42+
lines: breakpointsBySource.map(b => (b.origin as DebugProtocol.SourceBreakpoint).line)
43+
};
44+
45+
// The array elements are in the same order as the elements
46+
// of the 'breakpoints' in the SetBreakpointsArguments.
47+
promises.push(debugSession.setBreakpoints(args)
48+
.then(response => {
49+
for (const i in breakpointsBySource) {
50+
if (breakpointsBySource) {
51+
if (response.body.breakpoints) {
52+
breakpointsBySource[i].created = response.body.breakpoints[i];
53+
}
54+
}
55+
}
56+
return breakpointsBySource;
57+
}).then(result => this.storage.update(result)));
58+
}
59+
60+
return Promise.all(promises).then(() => { });
61+
}
62+
}

0 commit comments

Comments
 (0)