-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support storing and applying of memory content (#96)
* Support storing and applying of memory content Add commands to store and apply memory content as Intel HEX file - Encapsulate behavior in new MemoryStorage class - Trigger 'store' from Memory view, Variables view and command palette - Trigger 'apply' from Memory view, Explorer view and command palette - Use nrf-intel-hex library for read/write file licensed under BSD-3 Use quick inputs to guide user through necessary input - Initialize as much of the input as possible through command args Communicate with webview through messenger requests and notifications -- Request to trigger store and apply from webview -- Notify webview about any written memory so it can update properly Minor improvements - Move some common types and functionality into 'common' area - Avoid bleeding Debug Adapter types into webview, use messaging types - Common style: 'getVariables' -> 'getVariablesType' - Provide utility functions and types for debug requests - Fix 'Enter' handling for numpad by checking key value of event Closes #50
- Loading branch information
1 parent
3cd4184
commit bbf3e9d
Showing
29 changed files
with
965 additions
and
246 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/******************************************************************************** | ||
* Copyright (C) 2024 EclipseSource. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the Eclipse | ||
* Public License v. 2.0 are satisfied: GNU General Public License, version 2 | ||
* with the GNU Classpath Exception which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
********************************************************************************/ | ||
// inspired by https://github.com/eclipse-theia/theia/blob/master/packages/debug/src/browser/debug-session-connection.ts | ||
|
||
import type { DebugProtocol } from '@vscode/debugprotocol'; | ||
import type { DebugSession } from 'vscode'; | ||
|
||
export interface DebugRequestTypes { | ||
'evaluate': [DebugProtocol.EvaluateArguments, DebugProtocol.EvaluateResponse['body']] | ||
'initialize': [DebugProtocol.InitializeRequestArguments, DebugProtocol.InitializeResponse['body']] | ||
'readMemory': [DebugProtocol.ReadMemoryArguments, DebugProtocol.ReadMemoryResponse['body']] | ||
'scopes': [DebugProtocol.ScopesArguments, DebugProtocol.ScopesResponse['body']] | ||
'variables': [DebugProtocol.VariablesArguments, DebugProtocol.VariablesResponse['body']] | ||
'writeMemory': [DebugProtocol.WriteMemoryArguments, DebugProtocol.WriteMemoryResponse['body']] | ||
} | ||
|
||
export interface DebugEvents { | ||
'memory': DebugProtocol.MemoryEvent, | ||
'stopped': DebugProtocol.StoppedEvent | ||
} | ||
|
||
export type DebugRequest<C, A> = Omit<DebugProtocol.Request, 'command' | 'arguments'> & { command: C, arguments: A }; | ||
export type DebugResponse<C, B> = Omit<DebugProtocol.Response, 'command' | 'body'> & { command: C, body: B }; | ||
export type DebugEvent<T> = DebugProtocol.Event & { body: T }; | ||
|
||
export async function sendRequest<K extends keyof DebugRequestTypes>(session: DebugSession, | ||
command: K, args: DebugRequestTypes[K][0]): Promise<DebugRequestTypes[K][1]> { | ||
return session.customRequest(command, args); | ||
} | ||
|
||
export function isDebugVariable(variable: DebugProtocol.Variable | unknown): variable is DebugProtocol.Variable { | ||
const assumed = variable ? variable as DebugProtocol.Variable : undefined; | ||
return typeof assumed?.name === 'string' && typeof assumed?.value === 'string'; | ||
} | ||
|
||
export function isDebugScope(scope: DebugProtocol.Scope | unknown): scope is DebugProtocol.Scope { | ||
const assumed = scope ? scope as DebugProtocol.Scope : undefined; | ||
return typeof assumed?.name === 'string' && typeof assumed?.variablesReference === 'number'; | ||
} | ||
|
||
export function isDebugEvaluateArguments(args: DebugProtocol.EvaluateArguments | unknown): args is DebugProtocol.EvaluateArguments { | ||
const assumed = args ? args as DebugProtocol.EvaluateArguments : undefined; | ||
return typeof assumed?.expression === 'string'; | ||
} | ||
|
||
export function isDebugRequest<K extends keyof DebugRequestTypes>(command: K, message: unknown): message is DebugRequest<K, DebugRequestTypes[K][0]> { | ||
const assumed = message ? message as DebugProtocol.Request : undefined; | ||
return !!assumed && assumed.type === 'request' && assumed.command === command; | ||
} | ||
|
||
export function isDebugResponse<K extends keyof DebugRequestTypes>(command: K, message: unknown): message is DebugResponse<K, DebugRequestTypes[K][1]> { | ||
const assumed = message ? message as DebugProtocol.Response : undefined; | ||
return !!assumed && assumed.type === 'response' && assumed.command === command; | ||
} | ||
|
||
export function isDebugEvent<K extends keyof DebugEvents>(event: K, message: unknown): message is DebugEvents[K] { | ||
const assumed = message ? message as DebugProtocol.Event : undefined; | ||
return !!assumed && assumed.type === 'event' && assumed.event === event; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/******************************************************************************** | ||
* Copyright (C) 2024 EclipseSource. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the Eclipse | ||
* Public License v. 2.0 are satisfied: GNU General Public License, version 2 | ||
* with the GNU Classpath Exception which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
********************************************************************************/ | ||
|
||
import { URI, Utils } from 'vscode-uri'; | ||
|
||
export namespace IntelHEX { | ||
export namespace FileExtensions { | ||
export const All = [ | ||
// General | ||
'hex', 'mcs', 'int', 'ihex', 'ihe', 'ihx', | ||
// Platform-specific | ||
'h80', 'h86', 'a43', 'a90', | ||
// Binary or Intel hex | ||
'obj', 'obl', 'obh', 'rom', 'eep' | ||
]; | ||
export const Default = 'hex'; | ||
|
||
export function applyIfMissing(file: URI): URI { | ||
const extWithDot = Utils.extname(file); | ||
if (extWithDot.length === 0 || !IntelHEX.FileExtensions.All.includes(extWithDot.slice(1))) { | ||
return URI.file(file.fsPath + '.' + IntelHEX.FileExtensions.Default); | ||
} | ||
return file; | ||
}; | ||
}; | ||
export const DialogFilters = { | ||
'Intel HEX Files': IntelHEX.FileExtensions.All, | ||
'All Files': ['*'] | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/******************************************************************************** | ||
* Copyright (C) 2024 EclipseSource. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the Eclipse | ||
* Public License v. 2.0 are satisfied: GNU General Public License, version 2 | ||
* with the GNU Classpath Exception which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
********************************************************************************/ | ||
|
||
import { ReadMemoryArguments, ReadMemoryResult } from './messaging'; | ||
|
||
export interface Memory { | ||
address: bigint; | ||
bytes: Uint8Array; | ||
} | ||
|
||
export function createMemoryFromRead(result: ReadMemoryResult, request?: ReadMemoryArguments): Memory { | ||
if (!result?.data) { | ||
const message = request ? `No memory provided for address ${request.memoryReference}` | ||
+ `, offset ${request.offset} and count ${request.count}!` : 'No memory provided.'; | ||
throw new Error(message); | ||
} | ||
const address = BigInt(result.address); | ||
const bytes = stringToBytesMemory(result.data); | ||
return { bytes, address }; | ||
} | ||
|
||
export function stringToBytesMemory(data: string): Uint8Array { | ||
return Uint8Array.from(Buffer.from(data, 'base64')); | ||
} | ||
|
||
export function bytesToStringMemory(data: Uint8Array): string { | ||
return Buffer.from(data).toString('base64'); | ||
} | ||
|
||
export function validateMemoryReference(reference: string): string | undefined { | ||
const asNumber = Number(reference); | ||
// we allow an address that is not a number, e.g., an expression, but if it is a number it must be >= 0 | ||
return !isNaN(asNumber) && asNumber < 0 ? 'Value must be >= 0' : undefined; | ||
} | ||
|
||
export function validateOffset(offset: string): string | undefined { | ||
const asNumber = Number(offset); | ||
return isNaN(asNumber) ? 'Must be number' : undefined; | ||
} | ||
|
||
export function validateCount(count: string): string | undefined { | ||
const asNumber = Number(count); | ||
if (isNaN(asNumber)) { | ||
return 'Must be number'; | ||
} else if (asNumber <= 0) { | ||
return 'Value must be > 0'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.