Skip to content
This repository has been archived by the owner on Jan 13, 2021. It is now read-only.

Commit

Permalink
fix(variables): fix variable handling
Browse files Browse the repository at this point in the history
  • Loading branch information
hoehrmann committed Sep 16, 2019
1 parent 2fc998d commit 8f5e823
Show file tree
Hide file tree
Showing 10 changed files with 1,333 additions and 1,147 deletions.
630 changes: 630 additions & 0 deletions debugger-functions.pl

Large diffs are not rendered by default.

330 changes: 144 additions & 186 deletions src/adapter.ts

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,15 @@ class PerlDebugConfigurationProvider implements vscode.DebugConfigurationProvide

const editor = vscode.window.activeTextEditor;

if (!config.request && editor.document.languageId === 'perl') {
const perlEditor = (
editor
&&
editor.document
&&
editor.document.languageId === 'perl'
);

if (!config.request && perlEditor) {

const defaultConfig = vscode.extensions.getExtension(
"mortenhenriksen.perl-debug"
Expand Down
848 changes: 388 additions & 460 deletions src/perlDebug.ts

Large diffs are not rendered by default.

11 changes: 1 addition & 10 deletions src/remoteSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,7 @@ export class RemoteSession extends EventEmitter implements DebugSession {
}

socket.on('data', data => {
// const str = data.toString('utf8');
// const signature = str.split('\n').pop();
// xxx: We should figure out a more stable way of differentiating between
// command result and application output
this.stderr.push(data); // xxx: For now we don't forward application output
/* if (debuggerSignature.test(signature)) {
this.stderr.push(data);
} else {
this.stdout.push(data);
}*/
this.stderr.push(data);
});

socket.on('end', data => {
Expand Down
131 changes: 123 additions & 8 deletions src/tests/adapter.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import assert = require('assert');
import * as Path from 'path';
import * as fs from 'fs';
Expand All @@ -27,6 +22,7 @@ describe('Perl debug Adapter', () => {
const FILE_PRINT_ARGUMENTS = 'print_arguments.pl';
const FILE_FAST_TEST_PL = 'fast_test.pl';
const FILE_LONG_RUNNING_PL = 'long_running.pl';
const FILE_VARS_TEST_PL = "vars_test.pl";

const PERL_DEBUG_LOG = 'perl_debugger.log';

Expand All @@ -40,6 +36,11 @@ describe('Perl debug Adapter', () => {
program: Path.join(DATA_ROOT, FILE_FAST_TEST_PL),
inc: [],
args: [],
env: {
// User perlbrew installations should take priority over system
// Perl installations.
PATH: process.env.PATH,
},
stopOnEntry: false,
console: 'none',
trace: false,
Expand All @@ -61,6 +62,29 @@ describe('Perl debug Adapter', () => {
}
};

const getScopedVars = async (
dc: DebugClient,
frameId: number,
name: string,
): Promise<DebugProtocol.VariablesResponse> => {

const st = await dc.stackTraceRequest({
threadId: undefined
});

const scopes = await dc.scopesRequest({
frameId: st.body.stackFrames[frameId].id
});

const vars = await dc.variablesRequest({
variablesReference: scopes.body.scopes.filter(
x => x.name === name
)[0].variablesReference
});

return vars;

};

let dc: DebugClient;

Expand Down Expand Up @@ -152,6 +176,97 @@ describe('Perl debug Adapter', () => {
});
});

describe('variables', () => {

it('variable retrieval should work', async () => {

await dc.launch(Configuration({
program: FILE_VARS_TEST_PL,
stopOnEntry: true
}));

const globalVars = await getScopedVars(dc, 0, 'Global');

const perlVer = globalVars.body.variables.filter(
x => x.name === '$]'
)[0];

assert.ok(/^5\./.test(perlVer.value));

const bpRespone = await dc.setBreakpointsRequest({
source: {
path: FILE_VARS_TEST_PL,
},
lines: [17],
});

assert(bpRespone.success, 'set breakpoint');

await Promise.all([
dc.continueRequest({ threadId: undefined }),
dc.assertStoppedLocation('breakpoint', {
line: 17
})
]);

const lexicals1 = async () => {

const lexicalVars = await getScopedVars(dc, 0, 'Lexical');

assert.ok(
lexicalVars.body.variables.filter(
x => x.name === '$PKG_MY' && x.value.indexOf('PKG_MY') > 0
).length > 0,
'can see a PKG_MY variable'
);

assert.ok(
lexicalVars.body.variables.filter(
x => x.name === '$arg' && x.value.indexOf('inner') > 0
).length > 0,
'can see a arg variable'
);

assert.ok(
lexicalVars.body.variables.filter(
x => x.name === '$outer_my' && x.value.indexOf('outer_my') > 0
).length === 0,
'cannot see a $outer_my variable from other stack frame'
);

const globalVars = await getScopedVars(dc, 0, 'Global');

assert.ok(
globalVars.body.variables.filter(
x => x.name === '$/'
&&
x.value.toLowerCase().indexOf('20ac') > 0
).length > 0,
'can see a localised $/ variable set to EURO sign'
);

};

const lexicals2 = async () => {

const lexicalVars = await getScopedVars(dc, 1, 'Lexical');

assert.ok(
lexicalVars.body.variables.filter(
x => x.name === '$outer_my' && x.value.indexOf('outer_my') > 0
).length > 0,
'can see a $outer_my variable in middle stack frame'
);

};

await lexicals1();
await lexicals2();

});

});

describe('pause', () => {

(platform() === "win32" ? it.skip : it)('should be able to pause programs', async () => {
Expand All @@ -172,7 +287,7 @@ describe('Perl debug Adapter', () => {
// NOTE(bh): Perl's built-in `sleep` function only supports
// integer resolution sleeps, so this test is a bit slow.

await new Promise(resolve => setTimeout(resolve, 2200));
await new Promise(resolve => setTimeout(resolve, 1200));

await dc.pauseRequest({
threadId: undefined,
Expand All @@ -192,8 +307,8 @@ describe('Perl debug Adapter', () => {
});

assert.ok(
parseInt(result.body.result) > 3,
'must have gone at least twice through the loop'
parseInt(result.body.result, 10) > 2,
'must have gone at least once through the loop'
);

});
Expand Down
22 changes: 0 additions & 22 deletions src/tests/connection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,28 +319,6 @@ describe('Perl debugger connection', () => {
});
});

describe('getVariableList', () => {
it('Should get more scope variables types', async function() {
await testLaunch(conn, FILE_TEST_PL, DATA_ROOT, []);
await conn.setBreakPoint(23, FILE_MODULE);

await conn.continue();

const vars0 = await conn.getVariableList(0);
const actual = Object.keys(vars0).length;
const expected = [0, 44, 45, 46]; // xxx: Investigate 44+46 might be a perser issue
assert(expected.indexOf(actual) > -1, 'variable count level 0, actual: ' +
actual + ' expected: ' + expected.join(' or '));

const vars1 = await conn.getVariableList(1);
assert.equal(Object.keys(vars1).length, 7, 'variable count level 1');
const vars2 = await conn.getVariableList(2);
assert.equal(Object.keys(vars2).length, 1, 'variable count level 2');
const vars3 = await conn.getVariableList(3);
assert.equal(Object.keys(vars3).length, 0, 'variable count level 3');
});
});

describe('restart', () => {
it('Should start from the beginning', async () => {
let res = await testLaunch(conn, FILE_TEST_PL, DATA_ROOT, []);
Expand Down
38 changes: 38 additions & 0 deletions src/tests/data/vars_test.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env perl
package Local::Package;
use strict;
use warnings;

our $PKG_OUR = "our Local::Package PKG_OUR";
my $PKG_MY = "my Local::Package PKG_MY";

sub outer_sub {
my $outer_my = "outer_my";
inner_sub("argument to inner_sub");
}

sub inner_sub {
my ($arg) = @_;
local $/ = "\x{20ac}";
return $arg;
}

package main;
use strict;
use warnings;

my $main_my = "main_my";
my %hash = ("\%hash_key" => "\%hash_value");
my $hash_ref = {
"hash_ref_key" => "hash_ref_value"
};

my $array_ref = [1..9];

my $string = "string";

my $ref_to_ref_to_string = \(\("ref_to_ref_to_string"));

Local::Package::outer_sub();

exit 0;
Loading

0 comments on commit 8f5e823

Please sign in to comment.