Skip to content

Commit

Permalink
Disable breakpoint functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
haydar-metin committed Aug 21, 2024
1 parent e668f5d commit ad8062a
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 106 deletions.
57 changes: 1 addition & 56 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,36 +92,6 @@
"title": "Go to value in Memory Inspector",
"category": "Memory"
},
{
"command": "memory-inspector.data-breakpoint.set.read",
"title": "Break on Value Read",
"enablement": "memory-inspector.canWrite",
"category": "Memory"
},
{
"command": "memory-inspector.data-breakpoint.set.readWrite",
"title": "Break on Value Access",
"enablement": "memory-inspector.canWrite",
"category": "Memory"
},
{
"command": "memory-inspector.data-breakpoint.set.write",
"title": "Break on Value Change",
"enablement": "memory-inspector.canWrite",
"category": "Memory"
},
{
"command": "memory-inspector.data-breakpoint.remove",
"title": "Remove Breakpoint",
"enablement": "memory-inspector.canWrite",
"category": "Memory"
},
{
"command": "memory-inspector.data-breakpoint.remove-all",
"title": "Remove All Breakpoints",
"enablement": "memory-inspector.canWrite",
"category": "Memory"
},
{
"command": "memory-inspector.toggle-variables-column",
"title": "Toggle Variables Column",
Expand Down Expand Up @@ -267,31 +237,6 @@
"command": "memory-inspector.reset-display-options",
"group": "a_reset@2",
"when": "webviewId === memory-inspector.memory && optionsMenu"
},
{
"command": "memory-inspector.data-breakpoint.set.read",
"group": "breakpoints@1",
"when": "webviewId === memory-inspector.memory && memory-inspector.breakpoint.isBreakable"
},
{
"command": "memory-inspector.data-breakpoint.set.write",
"group": "breakpoints@2",
"when": "webviewId === memory-inspector.memory && memory-inspector.breakpoint.isBreakable"
},
{
"command": "memory-inspector.data-breakpoint.set.readWrite",
"group": "breakpoints@3",
"when": "webviewId === memory-inspector.memory && memory-inspector.breakpoint.isBreakable"
},
{
"command": "memory-inspector.data-breakpoint.remove",
"group": "breakpoints@4",
"when": "webviewId === memory-inspector.memory && memory-inspector.breakpoint.type === 'internal'"
},
{
"command": "memory-inspector.data-breakpoint.remove-all",
"group": "breakpoints@5",
"when": "webviewId === memory-inspector.memory && memory-inspector.breakpoint.type === 'internal'"
}
]
},
Expand Down Expand Up @@ -501,4 +446,4 @@
"extensionKind": [
"ui"
]
}
}
8 changes: 7 additions & 1 deletion src/common/breakpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ export interface TrackedDataBreakpoint {
/**
* The respective response for the breakpoint.
*/
response: DebugProtocol.SetDataBreakpointsResponse['body']['breakpoints'][0]
response: DebugProtocol.Breakpoint;
}

/**
* Temp. workaround till we have a proper API for this within VSCode.
*/
export interface TrackedDataBreakpoints {
/**
* Breakpoints set from external contributors.
Expand All @@ -37,6 +40,9 @@ export interface TrackedDataBreakpoints {
internal: TrackedDataBreakpoint[]
}

/**
* Temp. workaround till we have a proper API for this within VSCode.
*/
export type TrackedBreakpointType = 'internal' | 'external';

export type DataBreakpointInfoArguments = DebugRequestTypes['dataBreakpointInfo'][0];
Expand Down
70 changes: 70 additions & 0 deletions src/plugin/breakpoints/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Steps to enable the breakpoint service again:

This service has been disabled for now, as it is not used.
It is kept here until VSCode extends the breakpoints API.

- package.json

```json
"commands": [
{
"command": "memory-inspector.data-breakpoint.set.read",
"title": "Break on Value Read",
"enablement": "memory-inspector.canWrite",
"category": "Memory"
},
{
"command": "memory-inspector.data-breakpoint.set.readWrite",
"title": "Break on Value Access",
"enablement": "memory-inspector.canWrite",
"category": "Memory"
},
{
"command": "memory-inspector.data-breakpoint.set.write",
"title": "Break on Value Change",
"enablement": "memory-inspector.canWrite",
"category": "Memory"
},
{
"command": "memory-inspector.data-breakpoint.remove",
"title": "Remove Breakpoint",
"enablement": "memory-inspector.canWrite",
"category": "Memory"
},
{
"command": "memory-inspector.data-breakpoint.remove-all",
"title": "Remove All Breakpoints",
"enablement": "memory-inspector.canWrite",
"category": "Memory"
},
]

"webview/context": [
...
{
"command": "memory-inspector.data-breakpoint.set.read",
"group": "breakpoints@1",
"when": "false && webviewId === memory-inspector.memory && memory-inspector.breakpoint.isBreakable"
},
{
"command": "memory-inspector.data-breakpoint.set.write",
"group": "breakpoints@2",
"when": "false && webviewId === memory-inspector.memory && memory-inspector.breakpoint.isBreakable"
},
{
"command": "memory-inspector.data-breakpoint.set.readWrite",
"group": "breakpoints@3",
"when": "false && webviewId === memory-inspector.memory && memory-inspector.breakpoint.isBreakable"
},
{
"command": "memory-inspector.data-breakpoint.remove",
"group": "breakpoints@4",
"when": "false && webviewId === memory-inspector.memory && memory-inspector.breakpoint.type === 'internal'"
},
{
"command": "memory-inspector.data-breakpoint.remove-all",
"group": "breakpoints@5",
"when": "false && webviewId === memory-inspector.memory && memory-inspector.breakpoint.type === 'internal'"
}
]
```
22 changes: 8 additions & 14 deletions src/plugin/breakpoints/breakpoint-tracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ import { SetDataBreakpointsResult, TrackedDataBreakpoint, TrackedDataBreakpoints
import { isDebugRequest, isDebugResponse } from '../../common/debug-requests';
import { isSessionEvent, SessionContinuedEvent, SessionEvent, SessionRequest, SessionResponse, SessionStoppedEvent, SessionTracker } from '../session-tracker';

/**
* Tracks data breakpoints and provides events for changes.
*
* Currently the webview part is disabled and does not react to the changes.
* It will be enabled again after VSCode extends the breakpoint API.
*/
export class BreakpointTracker {
protected _dataBreakpoints: TrackedDataBreakpoints = { external: [], internal: [] };
protected _stoppedEvent?: SessionStoppedEvent;
Expand Down Expand Up @@ -84,20 +90,8 @@ export class BreakpointTracker {
}

if (isSessionEvent('stopped', event)) {
// TODO: Only for demo purposes
// Reason: The debugger does not set the hitBreakpointIds property
const demoEvent: SessionStoppedEvent = {
...event,
data: {
...event.data,
body: {
...event.data.body,
hitBreakpointIds: this.externalDataBreakpoints.map(bp => bp.response.id ?? -1)
}
}
};
this._stoppedEvent = demoEvent;
this._onStopped.fire(demoEvent);
this._stoppedEvent = event;
this._onStopped.fire(event);
} else if (isSessionEvent('continued', event)) {
this._stoppedEvent = undefined;
this._onContinued.fire(event);
Expand Down
4 changes: 0 additions & 4 deletions src/plugin/session-tracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,6 @@ export class SessionTracker implements vscode.DebugAdapterTrackerFactory {
}

protected willSendClientMessage(session: vscode.DebugSession, message: unknown): void {
// TODO: ONLY FOR DEMO PURPOSES
console.log('[SEND] ==>', message);
if (isDebugRequest('initialize', message)) {
this.sessionInfo(session).clientCapabilities = message.arguments;
}
Expand All @@ -157,8 +155,6 @@ export class SessionTracker implements vscode.DebugAdapterTrackerFactory {
}

protected adapterMessageReceived(session: vscode.DebugSession, message: unknown): void {
// TODO: ONLY FOR DEMO PURPOSES
console.log('[RECV] <==', message);
if (isDebugResponse('initialize', message)) {
this.sessionInfo(session).debugCapabilities = message.body;
} else if (isDebugEvent('stopped', message)) {
Expand Down
138 changes: 138 additions & 0 deletions src/webview/breakpoints/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Steps to enable the breakpoint service again:

This service has been disabled for now, as it is not used.
It is kept here until VSCode extends the breakpoints API.

1. src/webview/memory-webview-view.tsx

```typescript
componentDidMount() {
...
breakpointService.activate();
breakpointService.onDidChange(() => this.forceUpdate());
}

doFetchMemory() {
...
await Promise.all(Array.from(
new Set(columnContributionService
.getUpdateExecutors()
.concat(decorationService.getUpdateExecutors())
.concat(breakpointService)),
executor => executor.fetchData(memoryOptions)
));
}
```

2. src/webview/columns/address-column.tsx

Extend rendering (Should be done through a decorator)

```typescript
render(columnIndex: number, row: MemoryRowData, config: ColumnRenderProps): ReactNode {
const selectionProps: SelectionProps = {
createSelection: (event, position) => createDefaultSelection(event, position, AddressColumn.ID, row),
getSelection: () => config.selection,
setSelection: config.setSelection
};

const breakpointMetadata = breakpointService.inRange(row)
.map(bp => breakpointService.metadata(bp))
.filter((bp): bp is BreakpointMetadata => bp !== undefined);
const statusClasses = BreakpointService.statusClasses(breakpointMetadata);

const groupProps = groupAttributes({ columnIndex, rowIndex: row.rowIndex, groupIndex: 0, maxGroupIndex: 0 }, selectionProps);
return <span className='memory-start-address hoverable' data-column='address' {...groupProps}>
{statusClasses.length > 0 && <span className={classNames('address-status', statusClasses)}></span>}
{config.tableConfig.showRadixPrefix && <span className='radix-prefix'>{getRadixMarker(config.tableConfig.addressRadix)}</span>}
<span className='address'>{getAddressString(row.startAddress, config.tableConfig.addressRadix, config.tableConfig.effectiveAddressLength)}</span>
</span>;
}
```

3. src/webview/columns/data-column.tsx

Extend Context (Should be done through a contribution)

```typescript
protected renderGroup(maus: React.ReactNode, startAddress: bigint, endAddress: bigint, idx: number): React.ReactNode {
const { config, row, columnIndex } = this.props;
const groupProps = groupAttributes({
rowIndex: row.rowIndex,
columnIndex: columnIndex,
groupIndex: idx,
maxGroupIndex: this.props.config.groupsPerRowToRender - 1
}, this.selectionProps);
const breakpointMetadata = breakpointService.metadata(toHexStringWithRadixMarker(startAddress));

return <span
tabIndex={0}
className={classNames('byte-group', 'hoverable', ...BreakpointService.inlineClasses(breakpointMetadata))}
data-column='data'
{...groupProps}
data-range-start={startAddress}
data-range-end={endAddress}
key={startAddress.toString(16)}
onKeyDown={this.onKeyDown}
onDoubleClick={this.setGroupEdit}
{...createGroupVscodeContext(startAddress, toOffset(startAddress, endAddress, config.tableConfig.bytesPerMau * 8), breakpointMetadata)}
>
{maus}
</span>;
}
```

4. src/webview/utils/vscode-contexts.ts

```typescript
export function createGroupVscodeContext(
startAddress: bigint,
length: number,
breakpoint?: BreakpointMetadata
): VscodeContext {
return createVscodeContext({
memoryData: { group: { startAddress, length } },
breakpoint: { ...breakpoint, isBreakable: true },
});
}

export function createVariableVscodeContext(
variable: BigIntVariableRange,
breakpoint?: BreakpointMetadata
): VscodeContext {
const { name, type, value, parentVariablesReference, isPointer } = variable;
return createVscodeContext({
variable: { name, type, value, parentVariablesReference, isPointer },
breakpoint: { ...breakpoint, isBreakable: true },
});
}
```

5. src/webview/variables/variable-decorations.ts

Extend rendering (Should be done through a decorator)

```typescript
render(columnIndex: number, row: MemoryRowData, config: ColumnRenderProps): ReactNode {
const selectionProps: SelectionProps = {
createSelection: (event, position) => createDefaultSelection(event, position, VariableDecorator.ID, row),
getSelection: () => config.selection,
setSelection: config.setSelection
};
const variables = this.getVariablesInRange(row);
return variables?.reduce<ReactNode[]>((result, current, index) => {
if (index > 0) { result.push(', '); }
const breakpointMetadata = breakpointService.metadata(current.variable.name);
result.push(React.createElement('span', {
style: { color: current.color },
key: current.variable.name,
className: classNames('hoverable', ...BreakpointService.inlineClasses(breakpointMetadata)),
'data-column': 'variables',
'data-variables': stringifyWithBigInts(current.variable),
...createVariableVscodeContext(current.variable, breakpointMetadata),
...groupAttributes({ columnIndex, rowIndex: row.rowIndex, groupIndex: index, maxGroupIndex: variables.length - 1 }, selectionProps)
}, current.variable.name));
return result;
}, []);
}
```
8 changes: 0 additions & 8 deletions src/webview/columns/address-column.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { classNames } from 'primereact/utils';
import React, { ReactNode } from 'react';
import { getAddressString, getRadixMarker } from '../../common/memory-range';
import { BreakpointMetadata, BreakpointService, breakpointService } from '../breakpoints/breakpoint-service';
import { MemoryRowData } from '../components/memory-table';
import { ColumnContribution, ColumnFittingType, ColumnRenderProps } from './column-contribution-service';
import { createDefaultSelection, groupAttributes, SelectionProps } from './table-group';
Expand All @@ -40,14 +38,8 @@ export class AddressColumn implements ColumnContribution {
setSelection: config.setSelection
};

const breakpointMetadata = breakpointService.inRange(row)
.map(bp => breakpointService.metadata(bp))
.filter((bp): bp is BreakpointMetadata => bp !== undefined);
const statusClasses = BreakpointService.statusClasses(breakpointMetadata);

const groupProps = groupAttributes({ columnIndex, rowIndex: row.rowIndex, groupIndex: 0, maxGroupIndex: 0 }, selectionProps);
return <span className='memory-start-address hoverable' data-column='address' {...groupProps}>
{statusClasses.length > 0 && <span className={classNames('address-status', statusClasses)}></span>}
{config.tableConfig.showRadixPrefix && <span className='radix-prefix'>{getRadixMarker(config.tableConfig.addressRadix)}</span>}
<span className='address'>{getAddressString(row.startAddress, config.tableConfig.addressRadix, config.tableConfig.effectiveAddressLength)}</span>
</span>;
Expand Down
Loading

0 comments on commit ad8062a

Please sign in to comment.