@@ -20,6 +20,7 @@ import { XdebugCloudConnection } from './cloud'
2020import { shouldIgnoreException } from './ignore'
2121import { varExportProperty } from './varExport'
2222import { supportedEngine } from './xdebugUtils'
23+ import { varJsonProperty } from './varJson'
2324
2425if ( process . env [ 'VSCODE_NLS_CONFIG' ] ) {
2526 try {
@@ -31,7 +32,7 @@ if (process.env['VSCODE_NLS_CONFIG']) {
3132}
3233
3334/** formats a xdebug property value for VS Code */
34- function formatPropertyValue ( property : xdebug . BaseProperty ) : string {
35+ function formatPropertyValue ( property : xdebug . BaseProperty , quoteString : boolean = true ) : string {
3536 let displayValue : string
3637 if ( property . hasChildren || property . type === 'array' || property . type === 'object' ) {
3738 if ( property . type === 'array' ) {
@@ -47,7 +48,7 @@ function formatPropertyValue(property: xdebug.BaseProperty): string {
4748 } else {
4849 // for null, uninitialized, resource, etc. show the type
4950 displayValue = property . value || property . type === 'string' ? property . value : property . type
50- if ( property . type === 'string' ) {
51+ if ( property . type === 'string' && quoteString ) {
5152 displayValue = `"${ displayValue } "`
5253 } else if ( property . type === 'bool' ) {
5354 displayValue = Boolean ( parseInt ( displayValue , 10 ) ) . toString ( )
@@ -56,6 +57,11 @@ function formatPropertyValue(property: xdebug.BaseProperty): string {
5657 return displayValue
5758}
5859
60+ export interface EvaluateExtendedArguments extends VSCodeDebugProtocol . EvaluateArguments {
61+ /** The variable for which to retrieve its children. The `variablesReference` must have been obtained in the current suspended state. See 'Lifetime of Object References' in the Overview section for details. */
62+ variablesReference ?: number
63+ }
64+
5965/**
6066 * This interface should always match the schema found in the mock-debug extension manifest.
6167 */
@@ -1496,9 +1502,18 @@ class PhpDebugSession extends vscode.DebugSession {
14961502 this . shutdown ( )
14971503 }
14981504
1505+ private getPropertyFromReference ( variablesReference ?: number ) : xdebug . Property | undefined {
1506+ if ( variablesReference && this . _properties . has ( variablesReference ) ) {
1507+ return this . _properties . get ( variablesReference ) !
1508+ } /*else if (variablesReference && this._evalResultProperties.has(variablesReference)) {
1509+ return this._evalResultProperties.get(variablesReference)!
1510+ }*/
1511+ return
1512+ }
1513+
14991514 protected async evaluateRequest (
15001515 response : VSCodeDebugProtocol . EvaluateResponse ,
1501- args : VSCodeDebugProtocol . EvaluateArguments
1516+ args : EvaluateExtendedArguments
15021517 ) : Promise < void > {
15031518 try {
15041519 if ( ! args . frameId ) {
@@ -1510,40 +1525,54 @@ class PhpDebugSession extends vscode.DebugSession {
15101525 const stackFrame = this . _stackFrames . get ( args . frameId ) !
15111526 const connection = stackFrame . connection
15121527 let result : xdebug . BaseProperty | null = null
1528+
15131529 if ( args . context === 'hover' ) {
15141530 // try to get variable from property_get
15151531 const ctx = await stackFrame . getContexts ( ) // TODO CACHE THIS
15161532 const res = await connection . sendPropertyGetNameCommand ( args . expression , ctx [ 0 ] )
15171533 if ( res . property ) {
15181534 result = res . property
15191535 }
1520- } else if ( args . context === 'repl' ) {
1521- const uuid = randomUUID ( )
1522- await connection . sendEvalCommand ( `$GLOBALS['eval_cache']['${ uuid } ']=${ args . expression } ` )
1523- const ctx = await stackFrame . getContexts ( ) // TODO CACHE THIS
1524- const res = await connection . sendPropertyGetNameCommand ( `$eval_cache['${ uuid } ']` , ctx [ 1 ] )
1525- if ( res . property ) {
1526- result = res . property
1536+ } else {
1537+ let property = this . getPropertyFromReference ( args . variablesReference )
1538+ let ctx : xdebug . Context [ ]
1539+ if ( ! property ) {
1540+ // try to get variable
1541+ ctx = await stackFrame . getContexts ( ) // TODO CACHE THIS
1542+ try {
1543+ // we might need to try other contexts too?
1544+ const res = await connection . sendPropertyGetNameCommand ( args . expression , ctx [ 0 ] )
1545+ property = res . property
1546+ } catch {
1547+ // ignore we failed, lets try evaling
1548+ }
15271549 }
1528- } else if ( args . context === 'clipboard' ) {
1529- const ctx = await stackFrame . getContexts ( ) // TODO CACHE THIS
1530- const res = await connection . sendPropertyGetNameCommand ( args . expression , ctx [ 0 ] )
1531- response . body = { result : await varExportProperty ( res . property ) , variablesReference : 0 }
1550+ if ( ! property ) {
1551+ const uuid = randomUUID ( )
1552+ await connection . sendEvalCommand ( `$GLOBALS['eval_cache']['${ uuid } ']=${ args . expression } ` )
1553+ const res = await connection . sendPropertyGetNameCommand ( `$eval_cache['${ uuid } ']` , ctx ! [ 1 ] )
1554+ property = res . property
1555+ }
1556+ result = property
1557+ }
1558+
1559+ if ( result && args . context === 'clipboard-var_export' ) {
1560+ response . body = { result : await varExportProperty ( result as xdebug . Property ) , variablesReference : 0 }
1561+ this . sendResponse ( response )
1562+ return
1563+ } else if ( result && args . context === 'clipboard-json' ) {
1564+ response . body = { result : await varJsonProperty ( result as xdebug . Property ) , variablesReference : 0 }
1565+ this . sendResponse ( response )
1566+ return
1567+ } else if ( result && args . context === 'clipboard-raw' ) {
1568+ response . body = { result : formatPropertyValue ( result , false ) , variablesReference : 0 }
1569+ this . sendResponse ( response )
1570+ return
1571+ } else if ( result && this . _initializeArgs . clientID !== 'vscode' && args . context === 'clipboard' ) {
1572+ // special case for NON-vscode clients where we cant add extra clipboard related contexts and var_export should be the default
1573+ response . body = { result : await varExportProperty ( result as xdebug . Property ) , variablesReference : 0 }
15321574 this . sendResponse ( response )
15331575 return
1534- } else if ( args . context === 'watch' ) {
1535- const uuid = randomUUID ( )
1536- await connection . sendEvalCommand ( `$GLOBALS['eval_cache']['watch']['${ uuid } ']=${ args . expression } ` )
1537- const ctx = await stackFrame . getContexts ( ) // TODO CACHE THIS
1538- const res = await connection . sendPropertyGetNameCommand ( `$eval_cache['watch']['${ uuid } ']` , ctx [ 1 ] )
1539- if ( res . property ) {
1540- result = res . property
1541- }
1542- } else {
1543- const res = await connection . sendEvalCommand ( args . expression )
1544- if ( res . result ) {
1545- result = res . result
1546- }
15471576 }
15481577
15491578 if ( result ) {
0 commit comments