Skip to content

Commit 1773ad8

Browse files
committed
Use property_value to get clipboard evaluation, tests.
1 parent c485164 commit 1773ad8

File tree

3 files changed

+93
-8
lines changed

3 files changed

+93
-8
lines changed

src/phpDebug.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,15 +1444,15 @@ class PhpDebugSession extends vscode.DebugSession {
14441444
}
14451445
} else if (args.context === 'clipboard') {
14461446
const uuid = randomUUID()
1447-
await connection.sendEvalCommand(`$GLOBALS['eval_cache']['${uuid}']=var_export(${args.expression}, true)`)
1447+
await connection.sendEvalCommand(
1448+
`$GLOBALS['eval_cache']['${uuid}']=var_export(${args.expression}, true)`
1449+
)
14481450
const ctx = await stackFrame.getContexts() // TODO CACHE THIS
1449-
const res = await connection.sendPropertyGetNameCommand(`$eval_cache['${uuid}']`, ctx[1])
1450-
if (res.property) {
1451-
// force a string response
1452-
response.body = { result: res.property.value, variablesReference: 0 }
1453-
this.sendResponse(response)
1454-
return
1455-
}
1451+
const res = await connection.sendPropertyValueNameCommand(`$eval_cache['${uuid}']`, ctx[1])
1452+
// force a string response
1453+
response.body = { result: res.value, variablesReference: 0 }
1454+
this.sendResponse(response)
1455+
return
14561456
} else {
14571457
const response = await connection.sendEvalCommand(args.expression)
14581458
if (response.result) {

src/test/adapter.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,52 @@ describe('PHP Debug Adapter', () => {
810810
assert.deepEqual(vars.body.variables[0].name, '0')
811811
assert.deepEqual(vars.body.variables[0].value, '1')
812812
})
813+
it('should return the eval result for clipboard', async () => {
814+
const program = path.join(TEST_PROJECT, 'variables.php')
815+
816+
await client.launch({
817+
program,
818+
})
819+
await client.setBreakpointsRequest({ source: { path: program }, breakpoints: [{ line: 19 }] })
820+
await client.configurationDoneRequest()
821+
const { frame } = await assertStoppedLocation('breakpoint', program, 19)
822+
823+
const response = (
824+
await client.evaluateRequest({
825+
context: 'clipboard',
826+
frameId: frame.id,
827+
expression: '$anInt',
828+
})
829+
).body
830+
831+
assert.equal(response.result, '123')
832+
assert.equal(response.variablesReference, 0)
833+
834+
const response2 = (
835+
await client.evaluateRequest({
836+
context: 'clipboard',
837+
frameId: frame.id,
838+
expression: '$aString',
839+
})
840+
).body
841+
842+
assert.equal(response2.result, "'123'")
843+
assert.equal(response2.variablesReference, 0)
844+
845+
const response3 = (
846+
await client.evaluateRequest({
847+
context: 'clipboard',
848+
frameId: frame.id,
849+
expression: '$anArray',
850+
})
851+
).body
852+
853+
assert.equal(
854+
response3.result,
855+
"array (\n 0 => 1,\n 'test' => 2,\n 'test2' => \n array (\n 't' => 123,\n ),\n)"
856+
)
857+
assert.equal(response3.variablesReference, 0)
858+
})
813859
})
814860

815861
describe.skip('output events', () => {

src/xdebugConnection.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,33 @@ export class PropertyGetNameResponse extends Response {
666666
}
667667
}
668668

669+
/** The response to a property_value command */
670+
export class PropertyValueResponse extends Response {
671+
/** the size of the value */
672+
size: number
673+
/** the data type of the variable. Can be string, int, float, bool, array, object, uninitialized, null or resource */
674+
type: string
675+
/** the value of the property for primitive types */
676+
value: string
677+
constructor(document: XMLDocument, connection: Connection) {
678+
super(document, connection)
679+
if (document.documentElement.hasAttribute('size')) {
680+
this.size = parseInt(document.documentElement.getAttribute('size') ?? '0')
681+
}
682+
this.type = document.documentElement.getAttribute('type') ?? ''
683+
if (document.documentElement.getElementsByTagName('value').length > 0) {
684+
this.value = decodeTag(document.documentElement, 'value')
685+
} else {
686+
const encoding = document.documentElement.getAttribute('encoding')
687+
if (encoding) {
688+
this.value = iconv.encode(document.documentElement.textContent!, encoding).toString()
689+
} else {
690+
this.value = document.documentElement.textContent!
691+
}
692+
}
693+
}
694+
}
695+
669696
/** class for properties returned from eval commands. These don't have a full name or an ID, but have all children already inlined. */
670697
export class EvalResultProperty extends BaseProperty {
671698
children: EvalResultProperty[]
@@ -1091,6 +1118,18 @@ export class Connection extends DbgpConnection {
10911118
)
10921119
}
10931120

1121+
/** Sends a property_value by name command */
1122+
public async sendPropertyValueNameCommand(name: string, context: Context): Promise<PropertyValueResponse> {
1123+
const escapedFullName = '"' + name.replace(/("|\\)/g, '\\$1') + '"'
1124+
return new PropertyValueResponse(
1125+
await this._enqueueCommand(
1126+
'property_value',
1127+
`-d ${context.stackFrame.level} -c ${context.id} -n ${escapedFullName}`
1128+
),
1129+
context.stackFrame.connection
1130+
)
1131+
}
1132+
10941133
/** Sends a property_set command */
10951134
public async sendPropertySetCommand(property: Property, value: string): Promise<Response> {
10961135
return new Response(

0 commit comments

Comments
 (0)