├── CHANGELOG.md ├── docs └── images │ ├── .gitkeep │ ├── VSCode_DebugBar_01.png │ ├── VSCode_RunMenu_01.png │ ├── VSCode_WatchView_01.png │ ├── VSCode_CallStackView_01.png │ ├── VSCode_VariablesView_01.png │ ├── VSCode_BreakpointsView_01.png │ ├── VSCode_BreakpointsViewPopup_01.png │ └── VSCode_VariablesViewContextMenu_01.png ├── tests ├── TestProjects │ ├── BasicProject │ │ ├── main.c │ │ ├── BasicProjectCompilationDatabase.json │ │ └── BasicProject.ewp │ ├── RegistersTest │ │ └── main.c │ ├── ListWindowTests │ │ ├── main.c │ │ ├── TestWs.eww │ │ └── TestProj.ewp │ ├── ConfigTests │ │ ├── settings │ │ │ ├── BasicDebugging.Debug.driver.xcl │ │ │ ├── BasicDebugging.Release.driver.xcl │ │ │ ├── BasicDebugging.Debug.general.xcl │ │ │ └── BasicDebugging.Release.general.xcl │ │ └── .vscode │ │ │ ├── settings.json │ │ │ ├── iar-vsc.json │ │ │ ├── tasks.json │ │ │ └── launch.json │ └── GettingStarted │ │ ├── Stl.cpp │ │ ├── Utilities.h │ │ ├── Fibonacci.h │ │ ├── Utilities.c │ │ └── Fibonacci.c ├── .eslintrc.json ├── suites │ ├── config │ │ └── index.ts │ ├── dbg │ │ ├── index.ts │ │ └── debugSession.test.ts │ └── listwindow │ │ └── index.ts ├── README.md └── runTests.ts ├── images ├── logo.png ├── icons │ ├── form_dark.svg │ ├── form_light.svg │ ├── DgCoresLockstepOn_dark.svg │ ├── DgCoresLockstepOn_light.svg │ ├── DgCoresLockstepOff_dark.svg │ └── DgCoresLockstepOff_light.svg └── logo-transparent.svg ├── .markdownlint.jsonc ├── md-images ├── overview.png ├── debug-dropdown.png ├── debug-session.png ├── start-session.gif ├── start-session2.gif ├── artchitecture-overview.png └── debug-session-screenshot.png ├── samples └── GettingStarted │ ├── .gitignore │ ├── GettingStarted.eww │ ├── Fibonacci.h │ ├── Utilities.h │ ├── Fibonacci.c │ └── Utilities.c ├── src ├── tsconfig.json ├── dap │ ├── breakpoints │ │ ├── descriptors │ │ │ ├── accessType.ts │ │ │ ├── locOnlyDescriptor.ts │ │ │ ├── breakpointDescriptor.ts │ │ │ ├── tdlEmulTraceBreakpointDescriptor.ts │ │ │ ├── dataLocEtcDescriptor.ts │ │ │ ├── emuTimerBreakpointDescriptor.ts │ │ │ ├── emulCodeBreakpointDescriptor.ts │ │ │ ├── descriptorWriter.ts │ │ │ ├── locEtcDescriptor.ts │ │ │ ├── emulDataBreakpointDescriptor.ts │ │ │ └── logDescriptor.ts │ │ ├── breakpointCategory.ts │ │ └── exceptionBreakpoint.ts │ ├── debugAdapter.ts │ ├── listWindowConstants.ts │ ├── configresolution │ │ ├── configurationResolver.ts │ │ └── launchArgumentConfigurationResolver.ts │ ├── thrift │ │ └── cspyServerLauncher.ts │ ├── timelineFrontendHandler.ts │ ├── multicoreProtocolExtension.ts │ ├── commandRegistry.ts │ └── debugEventListenerHandler.ts ├── settingsConstants.ts ├── listwindows │ ├── listwindowClientFactory.ts │ ├── README.md │ ├── testListwindow.ts │ └── clients │ │ ├── registersLegacyClient.ts │ │ ├── quickwatchLegacyClient.ts │ │ └── stackLegacyClient.ts ├── debugSessionTracker.ts ├── contextChangedHandler.ts └── utils.ts ├── .husky ├── pre-commit └── pre-commit.js ├── .gitignore ├── webviews ├── shared │ ├── thrift │ │ ├── sim_types.d.ts │ │ ├── dialogs_types.d.ts │ │ ├── breakpoints_types.d.ts │ │ ├── codecoverage_types.d.ts │ │ ├── libsupport_types.d.ts │ │ ├── sourcelookup_types.d.ts │ │ ├── sim_types.js │ │ ├── dialogs_types.js │ │ ├── libsupport_types.js │ │ ├── breakpoints_types.js │ │ ├── codecoverage_types.js │ │ ├── sourcelookup_types.js │ │ ├── memory_types.d.ts │ │ ├── HeartbeatService.d.ts │ │ ├── CMSISEventListener.d.ts │ │ ├── Watch.d.ts │ │ ├── MultiCoreLog.d.ts │ │ ├── QuickWatch.d.ts │ │ ├── ServiceListener.d.ts │ │ ├── Simulator.d.ts │ │ ├── SourceLookup.d.ts │ │ ├── ListWindowFrontend.d.ts │ │ ├── CPUStatusPollControl.d.ts │ │ ├── disassembly_types.d.ts │ │ ├── PowerLogSetup.d.ts │ │ ├── SoftCTI.d.ts │ │ ├── event_types.d.ts │ │ ├── DialogService.d.ts │ │ ├── SessionSynchronizer.d.ts │ │ ├── ExecutionControl.d.ts │ │ ├── EventBus.d.ts │ │ ├── ServiceManager_types.d.ts │ │ ├── ServiceRegistry_types.d.ts │ │ ├── SymbolicMemory.d.ts │ │ ├── CSpyMemory.d.ts │ │ ├── Stack.d.ts │ │ ├── crun_types.d.ts │ │ ├── logservice_types.d.ts │ │ ├── LogService.d.ts │ │ ├── CRunDisplay.d.ts │ │ ├── PartnerRegistry.d.ts │ │ ├── DebuggerStarter.d.ts │ │ ├── TimelineBackend.d.ts │ │ ├── Disassembly.d.ts │ │ ├── CRunBackend.d.ts │ │ ├── CodeCoverage.d.ts │ │ ├── CoresRegistry.d.ts │ │ ├── TimelineFrontend.d.ts │ │ ├── Breakpoints.d.ts │ │ ├── memory_types.js │ │ ├── DebugEventListener.d.ts │ │ ├── CSpyServiceRegistry.d.ts │ │ ├── themes_types.d.ts │ │ ├── OptionsService.d.ts │ │ ├── LibSupportService2.d.ts │ │ ├── CMSISAgent2.d.ts │ │ ├── frontend_types.d.ts │ │ ├── timeline_types.d.ts │ │ └── Gatekeeper.d.ts │ ├── rendering │ │ └── toolbar │ │ │ ├── toolbarUtils.ts │ │ │ └── toolbarConstants.ts │ ├── messageService.ts │ ├── utils.ts │ └── events.ts ├── test │ ├── tsconfig.json │ ├── .eslintrc.js │ └── listwindow │ │ ├── tooltip.test.ts │ │ ├── scrollbar.test.ts │ │ └── dragging.test.ts ├── tsconfig.json ├── global.d.ts ├── .eslintrc.js ├── README.md └── listwindow │ ├── state.ts │ └── rendering │ ├── styles │ └── sharedStyles.ts │ └── cell │ └── cellBorders.ts ├── .vscodeignore ├── prettier.config.js ├── .vscode ├── settings.json ├── tasks.json └── extensions.json ├── .github ├── workflows │ ├── deploy.yml │ └── build.yml └── ISSUE_TEMPLATE │ └── bug_report.md ├── tsconfig.base.json ├── CONTRIBUTING.md ├── .eslintrc.js └── webpack.config.js /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/images/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/TestProjects/BasicProject/main.c: -------------------------------------------------------------------------------- 1 | 2 | int main(){ 3 | return 1; 4 | } -------------------------------------------------------------------------------- /tests/TestProjects/RegistersTest/main.c: -------------------------------------------------------------------------------- 1 | 2 | int main() 3 | { 4 | return 0; 5 | } 6 | -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/images/logo.png -------------------------------------------------------------------------------- /.markdownlint.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "MD013": false, 3 | "MD033": false, 4 | "MD036": false 5 | } 6 | -------------------------------------------------------------------------------- /md-images/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/md-images/overview.png -------------------------------------------------------------------------------- /md-images/debug-dropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/md-images/debug-dropdown.png -------------------------------------------------------------------------------- /md-images/debug-session.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/md-images/debug-session.png -------------------------------------------------------------------------------- /md-images/start-session.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/md-images/start-session.gif -------------------------------------------------------------------------------- /md-images/start-session2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/md-images/start-session2.gif -------------------------------------------------------------------------------- /samples/GettingStarted/.gitignore: -------------------------------------------------------------------------------- 1 | Backup* 2 | Debug/** 3 | Debug2/** 4 | Release/** 5 | STM/** 6 | .vscode/** 7 | settings/ -------------------------------------------------------------------------------- /docs/images/VSCode_DebugBar_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/docs/images/VSCode_DebugBar_01.png -------------------------------------------------------------------------------- /docs/images/VSCode_RunMenu_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/docs/images/VSCode_RunMenu_01.png -------------------------------------------------------------------------------- /docs/images/VSCode_WatchView_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/docs/images/VSCode_WatchView_01.png -------------------------------------------------------------------------------- /md-images/artchitecture-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/md-images/artchitecture-overview.png -------------------------------------------------------------------------------- /docs/images/VSCode_CallStackView_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/docs/images/VSCode_CallStackView_01.png -------------------------------------------------------------------------------- /docs/images/VSCode_VariablesView_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/docs/images/VSCode_VariablesView_01.png -------------------------------------------------------------------------------- /md-images/debug-session-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/md-images/debug-session-screenshot.png -------------------------------------------------------------------------------- /docs/images/VSCode_BreakpointsView_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/docs/images/VSCode_BreakpointsView_01.png -------------------------------------------------------------------------------- /src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "include": [ 4 | "**/*", 5 | "../tests/**/*" 6 | ] 7 | } -------------------------------------------------------------------------------- /docs/images/VSCode_BreakpointsViewPopup_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/docs/images/VSCode_BreakpointsViewPopup_01.png -------------------------------------------------------------------------------- /docs/images/VSCode_VariablesViewContextMenu_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iarsystems/iar-vsc-debug/HEAD/docs/images/VSCode_VariablesViewContextMenu_01.png -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | # check license headers 5 | node .husky/pre-commit.js 6 | # run linters 7 | npx lint-staged 8 | -------------------------------------------------------------------------------- /tests/TestProjects/ListWindowTests/main.c: -------------------------------------------------------------------------------- 1 | 2 | static int a = 1; 3 | 4 | int main() 5 | { 6 | int b = 1; 7 | 8 | while(1){ 9 | a++; 10 | b++; 11 | } 12 | return a*b; 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | out/ 4 | dist/ 5 | test-sandbox/ 6 | npm-debug.log 7 | mock-debug.txt 8 | *.vsix 9 | runtime.log 10 | outdebug_adapter.log 11 | package-lock.json 12 | .vscode-test/ -------------------------------------------------------------------------------- /samples/GettingStarted/GettingStarted.eww: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | $WS_DIR$\BasicDebugging.ewp 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/TestProjects/ListWindowTests/TestWs.eww: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $WS_DIR$\TestProj.ewp 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/TestProjects/ConfigTests/settings/BasicDebugging.Debug.driver.xcl: -------------------------------------------------------------------------------- 1 | "--endian=little" 2 | 3 | "--cpu=ARM7TDMI" 4 | 5 | "--fpu=None" 6 | 7 | "--semihosting" 8 | 9 | "--multicore_nr_of_cores=1" 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/TestProjects/ConfigTests/settings/BasicDebugging.Release.driver.xcl: -------------------------------------------------------------------------------- 1 | "--endian=little" 2 | 3 | "--cpu=ARM7TDMI" 4 | 5 | "--fpu=None" 6 | 7 | "--semihosting" 8 | 9 | "--multicore_nr_of_cores=1" 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | // We can allow some type trickery in tests, we will notice if they crash 3 | "rules": { 4 | "@typescript-eslint/no-non-null-assertion": "off", 5 | "@typescript-eslint/no-explicit-any": "off" 6 | } 7 | } -------------------------------------------------------------------------------- /tests/TestProjects/GettingStarted/Stl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef __ICC430__ 4 | // MSP430 has some weird concept of how the stl:s work... 5 | vector LargeVector(25, 42.0); 6 | #else 7 | std::vector LargeVector(25, 42.0); 8 | #endif 9 | -------------------------------------------------------------------------------- /webviews/shared/thrift/sim_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import Int64 = require('node-int64'); 7 | 8 | 9 | export declare var SIM_SERVICE: string; 10 | -------------------------------------------------------------------------------- /webviews/shared/thrift/dialogs_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import Int64 = require('node-int64'); 7 | 8 | 9 | export declare var DIALOG_SERVICE: string; 10 | -------------------------------------------------------------------------------- /webviews/test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "module": "CommonJS", 5 | "lib": ["es2021"], 6 | "skipLibCheck": true 7 | }, 8 | "include": [ 9 | "**/*" 10 | ], 11 | "exclude": [] 12 | } -------------------------------------------------------------------------------- /webviews/shared/thrift/breakpoints_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import Int64 = require('node-int64'); 7 | 8 | 9 | export declare var BREAKPOINTS_SERVICE: string; 10 | -------------------------------------------------------------------------------- /webviews/shared/thrift/codecoverage_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import Int64 = require('node-int64'); 7 | 8 | 9 | export declare var CODECOVERAGE_SERVICE: string; 10 | -------------------------------------------------------------------------------- /webviews/shared/thrift/libsupport_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import Int64 = require('node-int64'); 7 | 8 | 9 | export declare var LIBSUPPORT_SERVICE: string; 10 | -------------------------------------------------------------------------------- /webviews/shared/thrift/sourcelookup_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import Int64 = require('node-int64'); 7 | 8 | 9 | export declare var SOURCE_LOOKUP_SERVICE: string; 10 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | # Ignore everything 2 | * 3 | */** 4 | 5 | # Include only the files that should be in the .vsix 6 | !out/src/extension.js 7 | !out/webviews/**/* 8 | !README.md 9 | !CHANGELOG.md 10 | !LICENSE 11 | !KNOWN_ISSUES.md 12 | !md-images/**/* 13 | !images/**/* 14 | !node_modules/@vscode/codicons/dist/* -------------------------------------------------------------------------------- /tests/TestProjects/ConfigTests/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings.FALSE 2 | { 3 | "javascript.validate.enable": false, 4 | "typescript.tsdk": "node_modules/typescript/lib", 5 | "files.trimTrailingWhitespace": true, 6 | "editor.insertSpaces": false 7 | } -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @see https://prettier.io/docs/en/configuration.html 3 | * @type {import("prettier").Config} 4 | */ 5 | const config = { 6 | trailingComma: "all", 7 | tabWidth: 4, 8 | semi: true, 9 | singleQuote: false, 10 | printWidth: 80, 11 | arrowParens: "avoid", 12 | }; 13 | 14 | module.exports = config; -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings.FALSE 2 | { 3 | "files.trimTrailingWhitespace": true, 4 | "editor.insertSpaces": true, 5 | "editor.defaultFormatter": "esbenp.prettier-vscode", 6 | "[typescript]": { 7 | "editor.defaultFormatter": "esbenp.prettier-vscode" 8 | }, 9 | 10 | } -------------------------------------------------------------------------------- /webviews/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "experimentalDecorators": true, 7 | "sourceMap": true 8 | }, 9 | "include": [ 10 | "**/*" 11 | ], 12 | "exclude": [ 13 | "test/**/*" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /webviews/shared/thrift/sim_types.js: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | if (typeof Int64 === 'undefined' && typeof require === 'function') { 7 | var Int64 = require('node-int64'); 8 | } 9 | 10 | 11 | var ttypes = module.exports = {}; 12 | ttypes.SIM_SERVICE = 'simulator'; 13 | -------------------------------------------------------------------------------- /webviews/shared/thrift/dialogs_types.js: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | if (typeof Int64 === 'undefined' && typeof require === 'function') { 7 | var Int64 = require('node-int64'); 8 | } 9 | 10 | 11 | var ttypes = module.exports = {}; 12 | ttypes.DIALOG_SERVICE = 'dialogs'; 13 | -------------------------------------------------------------------------------- /webviews/shared/thrift/libsupport_types.js: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | if (typeof Int64 === 'undefined' && typeof require === 'function') { 7 | var Int64 = require('node-int64'); 8 | } 9 | 10 | 11 | var ttypes = module.exports = {}; 12 | ttypes.LIBSUPPORT_SERVICE = 'libsupport'; 13 | -------------------------------------------------------------------------------- /webviews/shared/thrift/breakpoints_types.js: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | if (typeof Int64 === 'undefined' && typeof require === 'function') { 7 | var Int64 = require('node-int64'); 8 | } 9 | 10 | 11 | var ttypes = module.exports = {}; 12 | ttypes.BREAKPOINTS_SERVICE = 'breakpoints'; 13 | -------------------------------------------------------------------------------- /webviews/shared/thrift/codecoverage_types.js: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | if (typeof Int64 === 'undefined' && typeof require === 'function') { 7 | var Int64 = require('node-int64'); 8 | } 9 | 10 | 11 | var ttypes = module.exports = {}; 12 | ttypes.CODECOVERAGE_SERVICE = 'codecoverage'; 13 | -------------------------------------------------------------------------------- /webviews/shared/thrift/sourcelookup_types.js: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | if (typeof Int64 === 'undefined' && typeof require === 'function') { 7 | var Int64 = require('node-int64'); 8 | } 9 | 10 | 11 | var ttypes = module.exports = {}; 12 | ttypes.SOURCE_LOOKUP_SERVICE = 'sourcelookup'; 13 | -------------------------------------------------------------------------------- /tests/TestProjects/ListWindowTests/TestProj.ewp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 2 4 | 5 | Debug 6 | 7 | ARM 8 | 9 | 1 10 | 11 | 12 | $PROJ_DIR$/main.c 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/TestProjects/ConfigTests/.vscode/iar-vsc.json: -------------------------------------------------------------------------------- 1 | { 2 | "ewp": "/home/power/iar-vs-code/iar-vsc-debug/src/tests/TestProjects/ConfigTests/BasicDebugging.ewp", 3 | "compiler": "/home/power/iar-vs-code/release-scripts/getstage/stages/stage-arm/8.10/StageLinux_x86_64/Release/arm/bin/iccarm", 4 | "workbench": "/home/power/iar-vs-code/release-scripts/getstage/stages/stage-arm/8.10/StageLinux_x86_64/Release", 5 | "configuration": "Release" 6 | } -------------------------------------------------------------------------------- /samples/GettingStarted/Fibonacci.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 - 2016 IAR Systems AB. 3 | * 4 | * IAR Embedded Workbench tutorial. 5 | * 6 | * Fibonacci.h 7 | * 8 | * Header file for Fibonacci.c. 9 | * 10 | * See the file /doc/licenses/IARSourceLicense.txt for detailed 11 | * license information. 12 | * 13 | * $Revision: 113247 $ 14 | */ 15 | 16 | #ifndef TUTOR_H 17 | #define TUTOR_H 18 | #include "Utilities.h" 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/dap/breakpoints/descriptors/accessType.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | /** 6 | * Access types avaiable to data breakpoints. These seem to be universal to all drivers. 7 | */ 8 | export enum AccessType { 9 | ReadWrite = 0, 10 | Read, 11 | Write, 12 | } -------------------------------------------------------------------------------- /tests/TestProjects/ConfigTests/settings/BasicDebugging.Debug.general.xcl: -------------------------------------------------------------------------------- 1 | "E:\Program Files (x86)\IAR Systems\Embedded Workbench for ARM 8.50.6\arm\bin\armproc.dll" 2 | 3 | "E:\Program Files (x86)\IAR Systems\Embedded Workbench for ARM 8.50.6\arm\bin\armsim2.dll" 4 | 5 | "E:\iar-vscode-github\iar-vsc-debug\samples\GettingStarted\Debug\Exe\BasicDebugging.out" 6 | 7 | --plugin="E:\Program Files (x86)\IAR Systems\Embedded Workbench for ARM 8.50.6\arm\bin\armbat.dll" 8 | -------------------------------------------------------------------------------- /tests/TestProjects/ConfigTests/settings/BasicDebugging.Release.general.xcl: -------------------------------------------------------------------------------- 1 | "E:\Program Files (x86)\IAR Systems\Embedded Workbench for ARM 8.50.6\arm\bin\armproc.dll" 2 | 3 | "E:\Program Files (x86)\IAR Systems\Embedded Workbench for ARM 8.50.6\arm\bin\armsim2.dll" 4 | 5 | "E:\iar-vscode-github\iar-vsc-debug\samples\GettingStarted\Release\Exe\BasicDebugging.out" 6 | 7 | --plugin="E:\Program Files (x86)\IAR Systems\Embedded Workbench for ARM 8.50.6\arm\bin\armbat.dll" 8 | -------------------------------------------------------------------------------- /tests/suites/config/index.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import * as path from "path"; 5 | import {getTestPromise} from "iar-vsc-common/testutils/testUtils"; 6 | 7 | export function run(): Promise { 8 | return getTestPromise(path.resolve(__dirname), 20000); 9 | } 10 | -------------------------------------------------------------------------------- /tests/suites/dbg/index.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import * as path from "path"; 5 | import {getTestPromise} from "iar-vsc-common/testutils/testUtils"; 6 | 7 | export function run(): Promise { 8 | return getTestPromise(path.resolve(__dirname), 20000); 9 | } 10 | -------------------------------------------------------------------------------- /webviews/shared/thrift/memory_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import Int64 = require('node-int64'); 7 | 8 | 9 | export declare class CSpyMemoryBlock { 10 | data: string; 11 | status: string; 12 | 13 | constructor(args?: { data: string; status: string; }); 14 | read(input: Object): void; 15 | write(input: Object): void; 16 | } 17 | -------------------------------------------------------------------------------- /tests/suites/listwindow/index.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import * as path from "path"; 5 | import {getTestPromise} from "iar-vsc-common/testutils/testUtils"; 6 | 7 | export function run(): Promise { 8 | return getTestPromise(path.resolve(__dirname), 20000); 9 | } 10 | -------------------------------------------------------------------------------- /tests/TestProjects/ConfigTests/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "npm", 6 | "identifier": "npm", 7 | "script": "watch", 8 | "problemMatcher": [ 9 | "$tsc-watch" 10 | ], 11 | "isBackground": true, 12 | "group": { 13 | "kind": "build", 14 | "isDefault": true 15 | } 16 | }, 17 | { 18 | "type": "npm", 19 | "script": "compile", 20 | "problemMatcher": [] 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /src/dap/debugAdapter.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | /** 6 | * Standalone script for running the debug adapter --- used for testing 7 | */ 8 | import { DebugSession } from "@vscode/debugadapter"; 9 | import { CSpyDebugSession } from "./cspyDebug"; 10 | 11 | DebugSession.run(CSpyDebugSession); 12 | console.log("ready to accept connections"); 13 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "npm", 6 | "script": "webpack-watch", 7 | "problemMatcher": [ 8 | "$ts-webpack-watch" 9 | ], 10 | "isBackground": true, 11 | "group": { 12 | "kind": "build", 13 | "isDefault": true 14 | } 15 | }, 16 | { 17 | "type": "npm", 18 | "script": "test-compile", 19 | "group": "build", 20 | "problemMatcher": [], 21 | "label": "npm: test-compile", 22 | "detail": "npm run webpack && tsc -p ./" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /webviews/test/.eslintrc.js: -------------------------------------------------------------------------------- 1 | const { overrides } = require("../../.eslintrc"); 2 | 3 | const config = { 4 | env: { 5 | browser: false, 6 | }, 7 | parserOptions: { 8 | project: "./test/tsconfig.json", 9 | tsonfigRootDir: __dirname + "/test" 10 | }, 11 | // We can allow some type trickery in tests, we will notice if they crash 12 | rules: { 13 | "@typescript-eslint/no-non-null-assertion": "off", 14 | "@typescript-eslint/no-explicit-any": "off" 15 | } 16 | } 17 | module.exports = config; -------------------------------------------------------------------------------- /src/dap/listWindowConstants.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | 6 | 7 | /** 8 | * Contains names for all C-SPY windows used by this adapter 9 | */ 10 | export namespace WindowNames { 11 | export const REGISTERS = "WIN_REGISTER_1"; 12 | export const STATICS = "WIN_STATICS"; 13 | export const LOCALS = "WIN_LOCALS"; 14 | export const CORES = "WIN_CORES"; 15 | } -------------------------------------------------------------------------------- /samples/GettingStarted/Utilities.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 - 2016 IAR Systems AB. 3 | * 4 | * IAR Embedded Workbench tutorial 5 | * 6 | * Utilities.h 7 | * 8 | * Utility header file for Utilities.c. 9 | * 10 | * See the file /doc/licenses/IARSourceLicense.txt for detailed 11 | * license information. 12 | * 13 | * $Revision: 113247 $ 14 | */ 15 | 16 | #ifndef UTILITIES_H 17 | #define UTILITIES_H 18 | 19 | #include 20 | 21 | #define MAX_FIB 10 22 | void InitFib(void); 23 | uint32_t GetFib(int_fast8_t n); 24 | void PutFib(uint32_t out); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /tests/TestProjects/GettingStarted/Utilities.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 - 2016 IAR Systems AB. 3 | * 4 | * IAR Embedded Workbench tutorial 5 | * 6 | * Utilities.h 7 | * 8 | * Utility header file for Utilities.c. 9 | * 10 | * See the file /doc/licenses/IARSourceLicense.txt for detailed 11 | * license information. 12 | * 13 | * $Revision: 113247 $ 14 | */ 15 | 16 | #ifndef UTILITIES_H 17 | #define UTILITIES_H 18 | 19 | #include 20 | 21 | #define MAX_FIB 10 22 | void InitFib(void); 23 | uint32_t GetFib(int_fast8_t n); 24 | void PutFib(uint32_t out); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /webviews/shared/thrift/HeartbeatService.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { shared } from "./shared_types"; 10 | 11 | 12 | export declare class Client { 13 | input: Thrift.TJSONProtocol; 14 | output: Thrift.TJSONProtocol; 15 | seqid: number; 16 | 17 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 18 | 19 | isAlive(): Q.Promise; 20 | 21 | isAlive(callback?: (data: void)=>void): void; 22 | } 23 | -------------------------------------------------------------------------------- /tests/TestProjects/BasicProject/BasicProjectCompilationDatabase.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "directory": "$DIR$", 4 | "arguments": ["$COMPILER_NAME$", "$DIR$/main.c", "-o", "$DIR$/Test/Obj/"], 5 | "file": "$DIR$/main.c", 6 | "output": "$DIR$/Test/Obj/main.o", 7 | "type": "COMPILER" 8 | }, 9 | { 10 | "directory": "$DIR$", 11 | "arguments": ["$LINKER_NAME$", "$DIR$/Test/Obj/main.o", "-o", "$DIR$/Test/Exe/$PROJ_NAME$.out"], 12 | "file": "$DIR$/Test/Obj/main.o", 13 | "output": "$DIR$/Test/Exe/$PROJ_NAME$.out", 14 | "type": "LINKER" 15 | } 16 | ] -------------------------------------------------------------------------------- /webviews/shared/thrift/CMSISEventListener.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { cmsisagent } from "./cmsisagent_types"; 10 | 11 | 12 | export declare class Client { 13 | input: Thrift.TJSONProtocol; 14 | output: Thrift.TJSONProtocol; 15 | seqid: number; 16 | 17 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 18 | 19 | onRteEvent(event: RteEvent): Q.Promise; 20 | 21 | onRteEvent(event: RteEvent, callback?: (data: void)=>void): void; 22 | } 23 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. 3 | // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp 4 | 5 | // List of extensions which should be recommended for users of this workspace. 6 | "recommendations": [ 7 | "dbaeumer.vscode-eslint", 8 | "Tobermory.es6-string-html", 9 | "amodio.tsl-problem-matcher", 10 | "DavidAnson.vscode-markdownlint", 11 | "esbenp.prettier-vscode" 12 | ], 13 | // List of extensions recommended by VS Code that should not be recommended for users of this workspace. 14 | "unwantedRecommendations": [ 15 | 16 | ] 17 | } -------------------------------------------------------------------------------- /webviews/shared/thrift/Watch.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { listwindow } from "./listwindow_types"; 11 | 12 | 13 | export declare class Client extends ListWindowBackend.Client { 14 | input: Thrift.TJSONProtocol; 15 | output: Thrift.TJSONProtocol; 16 | seqid: number; 17 | 18 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 19 | 20 | add(expr: string): Q.Promise; 21 | 22 | add(expr: string, callback?: (data: void)=>void): void; 23 | } 24 | -------------------------------------------------------------------------------- /webviews/shared/thrift/MultiCoreLog.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { ampsync } from "./ampsync_types"; 10 | 11 | 12 | export declare class Client { 13 | input: Thrift.TJSONProtocol; 14 | output: Thrift.TJSONProtocol; 15 | seqid: number; 16 | 17 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 18 | 19 | Log(cores: CoreRange, color: number, timeStamp: string, text: string): Q.Promise; 20 | 21 | Log(cores: CoreRange, color: number, timeStamp: string, text: string, callback?: (data: void)=>void): void; 22 | } 23 | -------------------------------------------------------------------------------- /webviews/shared/thrift/QuickWatch.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { listwindow } from "./listwindow_types"; 11 | 12 | 13 | export declare class Client extends ListWindowBackend.Client { 14 | input: Thrift.TJSONProtocol; 15 | output: Thrift.TJSONProtocol; 16 | seqid: number; 17 | 18 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 19 | 20 | evaluate(expr: string): Q.Promise; 21 | 22 | evaluate(expr: string, callback?: (data: void)=>void): void; 23 | } 24 | -------------------------------------------------------------------------------- /webviews/shared/thrift/ServiceListener.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { ServiceRegistry } from "./ServiceRegistry_types"; 10 | 11 | 12 | export declare class Client { 13 | input: Thrift.TJSONProtocol; 14 | output: Thrift.TJSONProtocol; 15 | seqid: number; 16 | 17 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 18 | 19 | servicesChanged(services: { [k: string]: ServiceLocation; }): Q.Promise; 20 | 21 | servicesChanged(services: { [k: string]: ServiceLocation; }, callback?: (data: void)=>void): void; 22 | } 23 | -------------------------------------------------------------------------------- /webviews/shared/thrift/Simulator.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { sim } from "./sim_types"; 10 | 11 | 12 | export declare class Client { 13 | input: Thrift.TJSONProtocol; 14 | output: Thrift.TJSONProtocol; 15 | seqid: number; 16 | 17 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 18 | 19 | getFrequency(): Q.Promise; 20 | 21 | getFrequency(callback?: (data: Int64)=>void): void; 22 | 23 | setFrequency(freq: Int64): Q.Promise; 24 | 25 | setFrequency(freq: Int64, callback?: (data: void)=>void): void; 26 | } 27 | -------------------------------------------------------------------------------- /webviews/shared/thrift/SourceLookup.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { sourcelookup } from "./sourcelookup_types"; 11 | 12 | 13 | export declare class Client extends HeartbeatService.Client { 14 | input: Thrift.TJSONProtocol; 15 | output: Thrift.TJSONProtocol; 16 | seqid: number; 17 | 18 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 19 | 20 | getSourceRanges(loc: Location): Q.Promise; 21 | 22 | getSourceRanges(loc: Location, callback?: (data: SourceRange[])=>void): void; 23 | } 24 | -------------------------------------------------------------------------------- /images/icons/form_dark.svg: -------------------------------------------------------------------------------- 1 | 4 | 9 | 10 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /images/icons/form_light.svg: -------------------------------------------------------------------------------- 1 | 4 | 9 | 10 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /webviews/shared/thrift/ListWindowFrontend.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { listwindow } from "./listwindow_types"; 10 | 11 | 12 | export declare class Client { 13 | input: Thrift.TJSONProtocol; 14 | output: Thrift.TJSONProtocol; 15 | seqid: number; 16 | 17 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 18 | 19 | notify(note: Note): Q.Promise; 20 | 21 | notify(note: Note, callback?: (data: void)=>void): void; 22 | 23 | notifyToolbar(note: ToolbarNote): Q.Promise; 24 | 25 | notifyToolbar(note: ToolbarNote, callback?: (data: void)=>void): void; 26 | } 27 | -------------------------------------------------------------------------------- /webviews/shared/thrift/CPUStatusPollControl.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { ampsync } from "./ampsync_types"; 10 | 11 | 12 | export declare class Client { 13 | input: Thrift.TJSONProtocol; 14 | output: Thrift.TJSONProtocol; 15 | seqid: number; 16 | 17 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 18 | 19 | SetCPUStatusPoll(core: number, on: boolean): Q.Promise; 20 | 21 | SetCPUStatusPoll(core: number, on: boolean, callback?: (data: void)=>void): void; 22 | 23 | GetCPUStatusPoll(): Q.Promise; 24 | 25 | GetCPUStatusPoll(callback?: (data: boolean)=>void): void; 26 | } 27 | -------------------------------------------------------------------------------- /webviews/global.d.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | // Get the VS Code webview API typings globally (e.g. acquireVsCodeApi) 6 | import "vscode-webview"; 7 | 8 | declare module 'csstype' { 9 | interface PropertiesFallback { 10 | borderTopStyle?: StandardPropertiesFallback["borderTopStyle"] | `var(${string})`; 11 | borderRightStyle?: StandardPropertiesFallback["borderRightStyle"] | `var(${string})`; 12 | borderBottomStyle?: StandardPropertiesFallback["borderBottomStyle"] | `var(${string})`; 13 | borderLeftStyle?: StandardPropertiesFallback["borderLeftStyle"] | `var(${string})`; 14 | } 15 | } -------------------------------------------------------------------------------- /webviews/shared/thrift/disassembly_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import Int64 = require('node-int64'); 7 | 8 | 9 | /** 10 | * A disassembly operation result, matching a memory location with instructions 11 | */ 12 | export declare class DisassembledLocation { 13 | location: Location; 14 | instructions: string[]; 15 | _function: string; 16 | offset: Int64; 17 | 18 | constructor(args?: { location: Location; instructions: string[]; _function: string; offset: Int64; }); 19 | read(input: Object): void; 20 | write(input: Object): void; 21 | } 22 | 23 | /** 24 | * Unique identifier for the Disassembly service 25 | */ 26 | export declare var DISASSEMBLY_SERVICE: string; 27 | -------------------------------------------------------------------------------- /images/icons/DgCoresLockstepOn_dark.svg: -------------------------------------------------------------------------------- 1 | 4 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /images/icons/DgCoresLockstepOn_light.svg: -------------------------------------------------------------------------------- 1 | 4 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/TestProjects/BasicProject/BasicProject.ewp: -------------------------------------------------------------------------------- 1 | 2 | 5 | 2 6 | 7 | Test 8 | 9 | $TOOLCHAIN_NAME$ 10 | 11 | 1 12 | 13 | General 14 | 3 15 | 16 | 0 17 | 1 18 | 1 19 | 20 | 21 | 22 | 23 | $PROJ_DIR$/main.c 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | # Integration test suite for the iar-vsc-debug plugins 2 | 3 | These are the intergration tests for the debugger implementation for C-SPY to VS-Code. The tests launches a vscode environment to which commands should be passed using vscode interface defined in node_modules/@types/vscode/index.d.ts. 4 | 5 | The test-suite can be executed from within vscode using the "Run Extension Tests"-configuration of from the commands line using the command "node ./out/tests/runTest.js" in the same folder as the package.json file. 6 | 7 | A small set of testproject are placed in the TestProjects folder. 8 | 9 | ## Writing a new test 10 | 11 | The integration tests uses the DAP protocol directly to communicate with the backend. A command is sent to the session using "vscode.debug.activeDebugSession.customRequest("...")" where the commands can be obtained from . 12 | -------------------------------------------------------------------------------- /webviews/shared/thrift/PowerLogSetup.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { listwindow } from "./listwindow_types"; 11 | 12 | 13 | export declare class Client extends ListWindowBackend.Client { 14 | input: Thrift.TJSONProtocol; 15 | output: Thrift.TJSONProtocol; 16 | seqid: number; 17 | 18 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 19 | 20 | setRate(sampleRate: number): Q.Promise; 21 | 22 | setRate(sampleRate: number, callback?: (data: void)=>void): void; 23 | 24 | getRateOfSample(): Q.Promise; 25 | 26 | getRateOfSample(callback?: (data: number)=>void): void; 27 | 28 | getMaxRate(): Q.Promise; 29 | 30 | getMaxRate(callback?: (data: number)=>void): void; 31 | } 32 | -------------------------------------------------------------------------------- /webviews/.eslintrc.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | env: { 3 | browser: true 4 | }, 5 | parserOptions: { 6 | project: "./tsconfig.json", 7 | tsconfigRootDir: __dirname 8 | }, 9 | ignorePatterns: ["*.d.ts"], 10 | rules: { 11 | // Workaround for a bug in decorator indentation, see: 12 | // https://github.com/typescript-eslint/typescript-eslint/issues/1824#issuecomment-957559729 13 | indent: "off", 14 | "@typescript-eslint/indent": [ 15 | "warn", 16 | 4, 17 | { 18 | ignoredNodes: [ 19 | "FunctionExpression > .params[decorators.length > 0]", 20 | "FunctionExpression > .params > :matches(Decorator, :not(:first-child))", 21 | "ClassBody.body > PropertyDefinition[decorators.length > 0] > .key" 22 | ], 23 | SwitchCase: 1, 24 | } 25 | ] 26 | }, 27 | 28 | }; 29 | module.exports = config; -------------------------------------------------------------------------------- /webviews/shared/thrift/SoftCTI.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { ampsync } from "./ampsync_types"; 10 | 11 | 12 | export declare class Client { 13 | input: Thrift.TJSONProtocol; 14 | output: Thrift.TJSONProtocol; 15 | seqid: number; 16 | 17 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 18 | 19 | SetSoftCTI(on: boolean): Q.Promise; 20 | 21 | SetSoftCTI(on: boolean, callback?: (data: void)=>void): void; 22 | 23 | GetSoftCTI(): Q.Promise; 24 | 25 | GetSoftCTI(callback?: (data: boolean)=>void): void; 26 | 27 | CoreStarting(core: number): Q.Promise; 28 | 29 | CoreStarting(core: number, callback?: (data: void)=>void): void; 30 | 31 | CoreStopping(core: number): Q.Promise; 32 | 33 | CoreStopping(core: number, callback?: (data: Int64)=>void): void; 34 | } 35 | -------------------------------------------------------------------------------- /webviews/shared/thrift/event_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import thrift = require('thrift'); 7 | import Thrift = thrift.Thrift; 8 | import Q = thrift.Q; 9 | import Int64 = require('node-int64'); 10 | import shared_ttypes = require('./shared_types'); 11 | 12 | 13 | 14 | declare enum EventId { 15 | kReloadWorkspace = 0, 16 | kReloadProject = 1, 17 | kReloadConfiguration = 2, 18 | kProjectAdded = 3, 19 | kConfigurationAdded = 4, 20 | kProjectRemoved = 5, 21 | kConfigurationRemoved = 6, 22 | kReloadTree = 7, 23 | } 24 | 25 | declare class ProjectManagerEvent { 26 | public eventId: EventId; 27 | public project: string; 28 | public configurations: string[]; 29 | 30 | constructor(args?: { eventId: EventId; project: string; configurations: string[]; }); 31 | read(input: Object): void; 32 | write(input: Object): void; 33 | } 34 | 35 | declare var EVENTMANAGER_ID: string; 36 | -------------------------------------------------------------------------------- /webviews/shared/thrift/DialogService.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { dialogs } from "./dialogs_types"; 11 | 12 | 13 | /** 14 | * This is a small service able to evaluate current state of a dialog. 15 | */ 16 | export declare class Client extends HeartbeatService.Client { 17 | input: Thrift.TJSONProtocol; 18 | output: Thrift.TJSONProtocol; 19 | seqid: number; 20 | 21 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 22 | 23 | SetValue(itemId: string, items: PropertyTreeItem): Q.Promise; 24 | 25 | SetValue(itemId: string, items: PropertyTreeItem, callback?: (data: boolean)=>void): void; 26 | 27 | GetState(itemId: string): Q.Promise; 28 | 29 | GetState(itemId: string, callback?: (data: ToolbarItemState)=>void): void; 30 | } 31 | -------------------------------------------------------------------------------- /webviews/shared/thrift/SessionSynchronizer.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { ampsync } from "./ampsync_types"; 11 | 12 | 13 | export declare class Client extends HeartbeatService.Client { 14 | input: Thrift.TJSONProtocol; 15 | output: Thrift.TJSONProtocol; 16 | seqid: number; 17 | 18 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 19 | 20 | SyncTo(who: number, destState: SessionState): Q.Promise; 21 | 22 | SyncTo(who: number, destState: SessionState, callback?: (data: SessionState)=>void): void; 23 | 24 | CurrentState(who: number): Q.Promise; 25 | 26 | CurrentState(who: number, callback?: (data: SessionState)=>void): void; 27 | 28 | AllStates(): Q.Promise; 29 | 30 | AllStates(callback?: (data: SessionState[])=>void): void; 31 | } 32 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: deploy 2 | on: [workflow_dispatch] 3 | jobs: 4 | deploy-debug: 5 | runs-on: ubuntu-latest 6 | if: ${{ github.repository == 'IARSystems/preview-vsc-debug' }} 7 | steps: 8 | - uses: actions/checkout@v3 9 | with: 10 | ref: master 11 | persist-credentials: false 12 | fetch-depth: 0 13 | - run: git remote add target https://${{ secrets.DEPLOY_PAT }}@github.com/IARSystems/iar-vsc-debug.git && git push target master:pre-release 14 | deploy-common: 15 | runs-on: ubuntu-latest 16 | if: ${{ github.repository == 'IARSystems/preview-vsc-debug' }} 17 | steps: 18 | - uses: actions/checkout@v3 19 | with: 20 | repository: IARSystems/preview-vsc-common 21 | ref: master 22 | token: ${{ secrets.DEPLOY_PAT }} 23 | persist-credentials: false 24 | fetch-depth: 0 25 | - run: git remote add target https://${{ secrets.DEPLOY_PAT }}@github.com/IARSystems/iar-vsc-common.git && git push target master:master 26 | 27 | -------------------------------------------------------------------------------- /webviews/shared/thrift/ExecutionControl.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { ampsync } from "./ampsync_types"; 10 | 11 | 12 | export declare class Client { 13 | input: Thrift.TJSONProtocol; 14 | output: Thrift.TJSONProtocol; 15 | seqid: number; 16 | 17 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 18 | 19 | Go(core: number): Q.Promise; 20 | 21 | Go(core: number, callback?: (data: void)=>void): void; 22 | 23 | Stop(core: number): Q.Promise; 24 | 25 | Stop(core: number, callback?: (data: void)=>void): void; 26 | 27 | MultiStop(): Q.Promise; 28 | 29 | MultiStop(callback?: (data: void)=>void): void; 30 | 31 | MultiGo(): Q.Promise; 32 | 33 | MultiGo(callback?: (data: void)=>void): void; 34 | 35 | SetRunAll(all: boolean): Q.Promise; 36 | 37 | SetRunAll(all: boolean, callback?: (data: void)=>void): void; 38 | } 39 | -------------------------------------------------------------------------------- /src/settingsConstants.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | 6 | /** 7 | * Hold names of all settings for this extension 8 | */ 9 | export namespace SettingsConstants { 10 | // The section all settings use (passed to vscode.workspace.getConfiguration) 11 | export const MAIN_SECTION = "iar-debug"; 12 | 13 | export const BREAKPOINT_MODE = "breakpointType"; 14 | 15 | export const LOCKSTEP_MODE_ENABLED = "enableMulticoreLockstepMode"; 16 | 17 | export const FIT_CONTENT_TO_VIEW = "fitContentToViewWidth"; 18 | 19 | export const BUILD_BEFORE_DEBUGGING = "buildBeforeDebugging"; 20 | 21 | /** 22 | * Possible values for the BUILD_BEFORE_DEBUGGING setting 23 | */ 24 | export enum BuildBeforeDebuggingValue { 25 | Disabled = "Disabled", 26 | AskOnFailure = "AskOnFailure", 27 | AbortOnFailure = "AbortOnFailure", 28 | DebugAnywayOnFailure = "DebugAnywayOnFailure", 29 | } 30 | } -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: [push, workflow_dispatch] 3 | jobs: 4 | build: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v3 8 | - uses: actions/setup-node@v3 9 | with: 10 | node-version: '16' 11 | - uses: shimataro/ssh-key-action@v2.3.1 12 | if: ${{ github.repository == 'IARSystems/preview-vsc-debug' }} 13 | with: 14 | key: ${{ secrets.SSH_KEY }} 15 | known_hosts: github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== 16 | - run: sed -i "s/git@github.com:IARSystems\/iar-vsc-common.git/IARSystems\/preview-vsc-common/" package.json 17 | if: ${{ github.repository == 'IARSystems/preview-vsc-debug' }} 18 | - run: npm install 19 | - run: npm run lint 20 | - run: npm run package 21 | -------------------------------------------------------------------------------- /webviews/shared/thrift/EventBus.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { ampsync } from "./ampsync_types"; 11 | 12 | 13 | export declare class Client extends HeartbeatService.Client { 14 | input: Thrift.TJSONProtocol; 15 | output: Thrift.TJSONProtocol; 16 | seqid: number; 17 | 18 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 19 | 20 | Fire(toBeFired: Event): Q.Promise; 21 | 22 | Fire(toBeFired: Event, callback?: (data: void)=>void): void; 23 | 24 | RegisterWithVersion(clientLocation: ServiceLocation, myId: number, ampVersion: number): Q.Promise; 25 | 26 | RegisterWithVersion(clientLocation: ServiceLocation, myId: number, ampVersion: number, callback?: (data: void)=>void): void; 27 | 28 | Register(clientLocation: ServiceLocation, myId: number): Q.Promise; 29 | 30 | Register(clientLocation: ServiceLocation, myId: number, callback?: (data: void)=>void): void; 31 | } 32 | -------------------------------------------------------------------------------- /webviews/shared/thrift/ServiceManager_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import Int64 = require('node-int64'); 7 | 8 | 9 | export declare class ServiceConfig { 10 | name: string; 11 | libraryName: string; 12 | spawnNewProcess: boolean; 13 | startupEntryPoint: string; 14 | shutdownEntryPoint: string; 15 | registerInLauncher: boolean; 16 | 17 | constructor(args?: { name: string; libraryName: string; spawnNewProcess: boolean; startupEntryPoint: string; shutdownEntryPoint: string; registerInLauncher: boolean; }); 18 | read(input: Object): void; 19 | write(input: Object): void; 20 | } 21 | 22 | export declare class LauncherConfig { 23 | useInternalRegistry: boolean; 24 | externalRegistryLocation: ServiceLocation; 25 | preferredTransports: Transport[]; 26 | 27 | constructor(args?: { useInternalRegistry: boolean; externalRegistryLocation: ServiceLocation; preferredTransports: Transport[]; }); 28 | read(input: Object): void; 29 | write(input: Object): void; 30 | } 31 | 32 | export declare var SERVICE_MANAGER_SERVICE: string; 33 | -------------------------------------------------------------------------------- /webviews/shared/rendering/toolbar/toolbarUtils.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | // Create an image entry using images from the extension. 6 | export function addLocalImage( 7 | doc: Document, 8 | imagePath: string, 9 | ): HTMLImageElement | undefined { 10 | // The special vscode image directory is stored as the "imageroot" entry in 11 | // the html structure for the listwindow. 12 | const element = doc.getElementById("imageroot"); 13 | let imageRoot = ""; 14 | if (element !== undefined) { 15 | const root = element?.getAttribute("root"); 16 | if (root !== null && root !== undefined) { 17 | imageRoot = root; 18 | } 19 | } else { 20 | console.error("Failed to load \"imageroot\""); 21 | return undefined; 22 | } 23 | 24 | // Found everything that we need => create the image block. 25 | const image = doc.createElement("img"); 26 | image.src = `${imageRoot}/toolbar/${imagePath}`; 27 | return image; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/dap/configresolution/configurationResolver.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | 6 | import { SessionConfiguration } from "iar-vsc-common/thrift/bindings/cspy_types"; 7 | import { CSpyLaunchRequestArguments } from "../cspyDebug"; 8 | 9 | 10 | /** 11 | * Resolves a {@link CSpyLaunchRequestArguments} provided by the DAP client 12 | * into a {@link SessionConfiguration} that can be used to launch a C-SPY session. 13 | * 14 | * Note that this interface (and LaunchRequestArguments) are in an early stage, 15 | * and will likely need to change (especially LaunchRequestArguments). 16 | */ 17 | export interface ConfigurationResolver { 18 | 19 | /** 20 | * Creates a valid {@link SessionConfiguration} from a {@link CSpyLaunchRequestArguments}. 21 | * May reject if no resolution is possible. 22 | * @param launchArguments The launch arguments to turn into a SessionConfiguration 23 | */ 24 | resolveLaunchArguments(launchArguments: CSpyLaunchRequestArguments): Promise; 25 | } -------------------------------------------------------------------------------- /webviews/README.md: -------------------------------------------------------------------------------- 1 | # Webviews 2 | 3 | This folder contains code for custom "Webview" based views. For a general 4 | introduction to webviews, see Microsoft's [Webview 5 | Guide](https://code.visualstudio.com/api/extension-guides/webview). 6 | 7 | Each webview contains an entry point (`index.ts`), which is compiled and bundled 8 | by webpack into a javascript file. In the VS Code extension, a webview provider 9 | then initializes the webview and creates some boilerplate HTML which loads the 10 | javascript file. 11 | 12 | ## Communication 13 | 14 | The webview provider (i.e. the extension) and the view itself run in separate 15 | contexts and cannot directly interact. Instead, they use an API provided by VS 16 | Code to send JSON objects between each other. Code in this folder can be 17 | imported by regular extension code, so it is advised to define the object types 18 | used for communication in a shared file here (see 19 | [listwindow/protocol.ts](listwindow/protocol.ts) for an example). 20 | 21 | ```mermaid 22 | graph LR 23 | A("Webview (Electron)") ---|Custom JSON protocol| B("VSC Extension (nodejs)") 24 | B ---|Debug Adapter Protocol| C(Debug Adapter) ---|Thrift| D(CSpyServer2.exe) 25 | ``` 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: For urgent matters, please contact IAR Technical Support directly. We reply to GitHub issues on a best effort basis. 4 | title: '' 5 | labels: 'bug' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | **Describe the bug:** 12 | A clear and concise description of what the bug is. 13 | 14 | **To Reproduce:** 15 | Describe the steps to reproduce the problem in as much detail as possible. 16 | 17 | **Expected behavior:** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Actual behavior:** 21 | What actually happens. 22 | 23 | **Environment:** 24 | 25 | - OS: [Windows, linux] 26 | - Embedded Workbench: [Arm, RX, RL78, AVR, RISC-V, ...] 27 | - Embedded Workbench version: 28 | - VSC Extension version: 29 | 30 | **Additional context:** 31 | Add any other context about the problem here, e.g., projects, files etc. Logs for the debugger can be obtained from the debug console and trace can activated by adding *"trace": true* to the launch configuration. 32 | -------------------------------------------------------------------------------- /tests/TestProjects/GettingStarted/Fibonacci.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 - 2016 IAR Systems AB. 3 | * 4 | * IAR Embedded Workbench tutorial. 5 | * 6 | * Fibonacci.h 7 | * 8 | * Header file for Fibonacci.c. 9 | * 10 | * See the file /doc/licenses/IARSourceLicense.txt for detailed 11 | * license information. 12 | * 13 | * $Revision: 113247 $ 14 | */ 15 | 16 | #ifndef TUTOR_H 17 | #define TUTOR_H 18 | #include "Utilities.h" 19 | #include 20 | 21 | // some global variables for testing purposes 22 | const char *str = "This is a sträng"; 23 | // for testing nested variables 24 | struct nest { 25 | union 26 | { 27 | int a; char b; 28 | } un; 29 | struct { 30 | union { 31 | int c; char d; 32 | } inner_inner; 33 | int e; 34 | } inner; 35 | }; 36 | struct nest nested_struct; 37 | struct nest nested_struct2; 38 | 39 | struct recursive { 40 | int a; 41 | struct recursive *self; 42 | }; 43 | struct recursive references_self = { 10, &references_self }; 44 | int *pointer; 45 | 46 | char buf[12]; 47 | int scan_to_me; 48 | 49 | struct anonymous_siblings { 50 | struct { 51 | int a; 52 | }; 53 | struct { 54 | int b; 55 | }; 56 | }; 57 | struct anonymous_siblings anon_siblings; 58 | 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /webviews/shared/messageService.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import { WebviewApi } from "vscode-webview"; 6 | import { ExtensionMessage, ViewMessage } from "../shared/protocol"; 7 | 8 | type MessageHandler = (msg: ExtensionMessage) => void; 9 | 10 | export class MessageService { 11 | private readonly messageHandlers: MessageHandler[] = []; 12 | 13 | constructor(private readonly api: WebviewApi) { 14 | window.addEventListener("message", ev => { 15 | if ("subject" in ev.data) { 16 | const message = ev.data as ExtensionMessage; 17 | for (const handler of this.messageHandlers) { 18 | handler(message); 19 | } 20 | } 21 | }); 22 | } 23 | 24 | addMessageHandler(handler: MessageHandler) { 25 | this.messageHandlers.push(handler); 26 | } 27 | 28 | /** Posts a message to the view provider in the extension code */ 29 | sendMessage(msg: ViewMessage) { 30 | this.api.postMessage(msg); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /webviews/shared/thrift/ServiceRegistry_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import Int64 = require('node-int64'); 7 | 8 | 9 | export declare enum Protocol { 10 | Binary = 0, 11 | Json = 1, 12 | } 13 | 14 | export declare enum Transport { 15 | Socket = 0, 16 | Pipe = 1, 17 | } 18 | 19 | export declare class ServiceLocation { 20 | host: string; 21 | port: number; 22 | protocol: Protocol; 23 | transport: Transport; 24 | 25 | constructor(args?: { host: string; port: number; protocol: Protocol; transport: Transport; }); 26 | read(input: Object): void; 27 | write(input: Object): void; 28 | } 29 | 30 | export declare class ServiceException extends Thrift.TException { 31 | message: string; 32 | serviceName: string; 33 | exceptionDescr: string; 34 | 35 | constructor(args?: { message: string; serviceName: string; exceptionDescr: string; }); 36 | read(input: Object): void; 37 | write(input: Object): void; 38 | } 39 | 40 | export declare var IAR_SERVICE_REGISTRY_ENVVAR: string; 41 | 42 | export declare var IAR_CSPY_PIPE_PREFIX: string; 43 | 44 | export declare var SERVICE_REGISTRY_SERVICE: string; 45 | -------------------------------------------------------------------------------- /images/icons/DgCoresLockstepOff_dark.svg: -------------------------------------------------------------------------------- 1 | 4 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /images/icons/DgCoresLockstepOff_light.svg: -------------------------------------------------------------------------------- 1 | 4 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /webviews/shared/thrift/SymbolicMemory.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { listwindow } from "./listwindow_types"; 11 | 12 | 13 | export declare class Client extends ListWindowBackend.Client { 14 | input: Thrift.TJSONProtocol; 15 | output: Thrift.TJSONProtocol; 16 | seqid: number; 17 | 18 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 19 | 20 | setZone(zone: string): Q.Promise; 21 | 22 | setZone(zone: string, callback?: (data: void)=>void): void; 23 | 24 | getZone(): Q.Promise; 25 | 26 | getZone(callback?: (data: string)=>void): void; 27 | 28 | getZoneList(): Q.Promise; 29 | 30 | getZoneList(callback?: (data: string[])=>void): void; 31 | 32 | nextSymbol(): Q.Promise; 33 | 34 | nextSymbol(callback?: (data: void)=>void): void; 35 | 36 | prevSymbol(): Q.Promise; 37 | 38 | prevSymbol(callback?: (data: void)=>void): void; 39 | 40 | navigate(expr: string): Q.Promise; 41 | 42 | navigate(expr: string, callback?: (data: void)=>void): void; 43 | } 44 | -------------------------------------------------------------------------------- /webviews/shared/thrift/CSpyMemory.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { memory } from "./memory_types"; 10 | 11 | 12 | export declare class Client { 13 | input: Thrift.TJSONProtocol; 14 | output: Thrift.TJSONProtocol; 15 | seqid: number; 16 | 17 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 18 | 19 | readMemory(location: Location, wordsize: number, bitsize: number, count: number): Q.Promise; 20 | 21 | readMemory(location: Location, wordsize: number, bitsize: number, count: number, callback?: (data: string)=>void): void; 22 | 23 | readMemoryBlock(location: Location, wordsize: number, bitsize: number, count: number): Q.Promise; 24 | 25 | readMemoryBlock(location: Location, wordsize: number, bitsize: number, count: number, callback?: (data: CSpyMemoryBlock)=>void): void; 26 | 27 | writeMemory(location: Location, wordsize: number, bitsize: number, count: number, buf: string): Q.Promise; 28 | 29 | writeMemory(location: Location, wordsize: number, bitsize: number, count: number, buf: string, callback?: (data: void)=>void): void; 30 | } 31 | -------------------------------------------------------------------------------- /src/dap/breakpoints/breakpointCategory.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | 6 | /** 7 | * Lists all C-SPY breakpoint categories (that we need to know about) 8 | */ 9 | export enum BreakpointCategory { 10 | // Code breakpoints 11 | EMUL_CODE = "EMUL_CODE", 12 | STD_CODE2 = "STD_CODE2", 13 | STD_TRACE_START2 = "STD_TRACE_START2", 14 | STD_TRACE_STOP2 = "STD_TRACE_STOP2", 15 | HW_CODE = "HW_CODE", 16 | EMUL_HW_CODE = "EMU_HW_CODE", //RX 17 | EMUL_SW_CODE = "EMU_SW_CODE", //RX 18 | EMUL_FLASH = "EMUL_FLASH", 19 | EMUL_TRACE_START = "EMUL_TRACE_START", 20 | EMUL_TRACE_STOP = "EMUL_TRACE_STOP", 21 | EMUL_TRACE_FILTER = "EMUL_TRACE_FILTER", 22 | TDL_EMUL_TRACE_START = "TDL_EMUL_TRACE_START", 23 | TDL_EMUL_TRACE_STOP = "TDL_EMUL_TRACE_STOP", 24 | EMU_TIMER_START = "EMU_TIMER_START", 25 | EMU_TIMER_STOP = "EMU_TIMER_STOP", 26 | // Data breakpoints 27 | STD_DATA2 = "STD_DATA2", 28 | EMUL_DATA = "EMUL_DATA", 29 | EMUL_DATA_BREAK = "EMUL_DATA_BREAK", //RX 30 | // Log breakpoints 31 | STD_LOG2 = "STD_LOG2", 32 | } 33 | -------------------------------------------------------------------------------- /webviews/shared/thrift/Stack.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { listwindow } from "./listwindow_types"; 11 | 12 | 13 | export declare class Client extends ListWindowBackend.Client { 14 | input: Thrift.TJSONProtocol; 15 | output: Thrift.TJSONProtocol; 16 | seqid: number; 17 | 18 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 19 | 20 | setStack(name: string): Q.Promise; 21 | 22 | setStack(name: string, callback?: (data: void)=>void): void; 23 | 24 | getStack(): Q.Promise; 25 | 26 | getStack(callback?: (data: string)=>void): void; 27 | 28 | getStacks(): Q.Promise; 29 | 30 | getStacks(callback?: (data: string[])=>void): void; 31 | 32 | getBarTooltip(): Q.Promise; 33 | 34 | getBarTooltip(callback?: (data: string)=>void): void; 35 | 36 | getBarInfo(): Q.Promise; 37 | 38 | getBarInfo(callback?: (data: StackBarInfo)=>void): void; 39 | 40 | getStackSettings(): Q.Promise; 41 | 42 | getStackSettings(callback?: (data: StackSettings)=>void): void; 43 | } 44 | -------------------------------------------------------------------------------- /webviews/listwindow/state.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import { WebviewApi } from "vscode-webview"; 6 | 7 | /** 8 | * State that is persisted between view restarts and VS Code restarts. 9 | * Properties are automatically persisted when set. 10 | * Must be JSON-serializable. See: 11 | * https://code.visualstudio.com/api/extension-guides/webview#persistence 12 | */ 13 | export class PersistedState { 14 | private readonly data: PersistedState.Data; 15 | 16 | constructor(private readonly vscode: WebviewApi) { 17 | this.data = vscode.getState() ?? {}; 18 | } 19 | 20 | get columnWidths(): number[] | undefined { 21 | return this.data.columnWidths; 22 | } 23 | set columnWidths(val: number[] | undefined) { 24 | this.data.columnWidths = val; 25 | this.save(); 26 | } 27 | 28 | private save() { 29 | this.vscode.setState(this.data); 30 | } 31 | } 32 | 33 | export namespace PersistedState { 34 | // The actual persisted object 35 | export interface Data { 36 | columnWidths?: number[]; 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /images/logo-transparent.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 16 | 17 | -------------------------------------------------------------------------------- /webviews/shared/thrift/crun_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import Int64 = require('node-int64'); 7 | 8 | 9 | export declare enum CRunBreakAction { 10 | kStopAndLog = 0, 11 | kLog = 1, 12 | kIgnore = 2, 13 | } 14 | 15 | export declare class CRunMessage { 16 | id: number; 17 | index: number; 18 | core: number; 19 | name: string; 20 | text: string; 21 | cycle: Int64; 22 | repeatCount: number; 23 | subMessages: CRunMessage[]; 24 | callStack: string[]; 25 | noStop: boolean; 26 | runTo: Location; 27 | userProgramCounter: Location; 28 | extraSourceRanges: SourceRange[]; 29 | pcSourceRange: SourceRange; 30 | tooltip: string; 31 | breakAction: CRunBreakAction; 32 | 33 | constructor(args?: { id: number; index: number; core: number; name: string; text: string; cycle: Int64; repeatCount: number; subMessages: CRunMessage[]; callStack: string[]; noStop: boolean; runTo: Location; userProgramCounter: Location; extraSourceRanges: SourceRange[]; pcSourceRange: SourceRange; tooltip: string; breakAction: CRunBreakAction; }); 34 | read(input: Object): void; 35 | write(input: Object): void; 36 | } 37 | 38 | export declare var CRUN_DISPLAY_SERVICE: string; 39 | 40 | export declare var CRUN_BACKEND_SERVICE: string; 41 | -------------------------------------------------------------------------------- /src/listwindows/listwindowClientFactory.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import { ThriftServiceRegistry } from "iar-vsc-common/thrift/thriftServiceRegistry"; 6 | import * as ListWindowBackend from "iar-vsc-common/thrift/bindings/ListWindowBackend"; 7 | import { 8 | AbstractListwindowClient, 9 | GenericListwindowClient, 10 | ToolbarInterface, 11 | } from "./clients/listwindowBackendClient"; 12 | import { ThriftClient } from "iar-vsc-common/thrift/thriftClient"; 13 | 14 | export type CTor = new () => U; 15 | export namespace ServiceClientFactory { 16 | export async function createServices( 17 | serviceName: string, 18 | serviceRegistry: ThriftServiceRegistry, 19 | ctor: CTor> | undefined, 20 | ): Promise<[ThriftClient, ToolbarInterface]> { 21 | const proxy = 22 | ctor !== undefined ? new ctor() : new GenericListwindowClient(); 23 | 24 | const client = await proxy.connectToBackend( 25 | serviceName, 26 | serviceRegistry, 27 | ); 28 | return [client, proxy]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /webviews/shared/thrift/logservice_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import Int64 = require('node-int64'); 7 | 8 | 9 | export declare enum LogSeverity { 10 | kDebug = -1, 11 | kUser = 0, 12 | kMinorInfo = 1, 13 | kInfo = 2, 14 | kWarning = 3, 15 | kError = 4, 16 | kAlert = 5, 17 | kSuper = 6, 18 | } 19 | 20 | export declare class SrcPos { 21 | row: number; 22 | col: number; 23 | valid: boolean; 24 | 25 | constructor(args?: { row: number; col: number; valid: boolean; }); 26 | read(input: Object): void; 27 | write(input: Object): void; 28 | } 29 | 30 | /** 31 | * An entry in a log, matches IfLogServer::Entry 32 | */ 33 | export declare class LogEntry { 34 | category: string; 35 | sender: string; 36 | text: string; 37 | severity: LogSeverity; 38 | path: string; 39 | srcPos: SrcPos; 40 | srcEndPos: SrcPos; 41 | timestamp: Int64; 42 | entryId: Int64; 43 | isSubEntry: boolean; 44 | 45 | constructor(args?: { category: string; sender: string; text: string; severity: LogSeverity; path: string; srcPos: SrcPos; srcEndPos: SrcPos; timestamp: Int64; entryId: Int64; isSubEntry: boolean; }); 46 | read(input: Object): void; 47 | write(input: Object): void; 48 | } 49 | 50 | export declare var LOGSERVICE_ID: string; 51 | -------------------------------------------------------------------------------- /webviews/shared/thrift/LogService.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { logservice } from "./logservice_types"; 11 | 12 | 13 | /** 14 | * A receiver of LogEntry:s. This is a thrift clone of the IfLogServer 15 | * interface. Registering this service and starting the ThriftLogForwarder 16 | * service in the IDE platform lets you receive everything logged by the IDE 17 | * platform. 18 | */ 19 | export declare class Client extends HeartbeatService.Client { 20 | input: Thrift.TJSONProtocol; 21 | output: Thrift.TJSONProtocol; 22 | seqid: number; 23 | 24 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 25 | 26 | addCategory(category: string): Q.Promise; 27 | 28 | addCategory(category: string, callback?: (data: void)=>void): void; 29 | 30 | removeCategory(category: string): Q.Promise; 31 | 32 | removeCategory(category: string, callback?: (data: void)=>void): void; 33 | 34 | startSession(category: string): Q.Promise; 35 | 36 | startSession(category: string, callback?: (data: void)=>void): void; 37 | 38 | postLogEntry(entry: LogEntry): Q.Promise; 39 | 40 | postLogEntry(entry: LogEntry, callback?: (data: void)=>void): void; 41 | } 42 | -------------------------------------------------------------------------------- /samples/GettingStarted/Fibonacci.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 - 2016 IAR Systems AB. 3 | * 4 | * IAR Embedded Workbench tutorial 5 | * 6 | * Fibonacci.c 7 | * 8 | * Prints the Fibonacci sequence. 9 | * 10 | * See the file /doc/licenses/IARSourceLicense.txt for detailed 11 | * license information. 12 | * 13 | * $Revision: 113247 $ 14 | */ 15 | 16 | #include 17 | #include 18 | #include "Fibonacci.h" 19 | 20 | static void NextCounter(void); 21 | static void DoForegroundProcess(void); 22 | 23 | static int_fast8_t callCount; 24 | 25 | 26 | /* Increase the 'callCount' variable by one. */ 27 | static void NextCounter(void) 28 | { 29 | callCount += 1; 30 | } 31 | 32 | /* Increase the 'callCount' variable. */ 33 | /* Get and print the associated Fibonacci number. */ 34 | static void DoForegroundProcess(void) 35 | { 36 | uint32_t fib; 37 | NextCounter(); 38 | fib = GetFib(callCount); 39 | PutFib(fib); 40 | } 41 | struct s { 42 | int a; 43 | } asdf; 44 | char myString[16] = "hello there"; 45 | 46 | /* Main program. */ 47 | /* Prints the Fibonacci sequence. */ 48 | int32_t main(void) 49 | { 50 | char buf[20]; 51 | 52 | // scanf("%d", &a); 53 | scanf("%19s", &buf); 54 | struct s *p = &asdf; 55 | callCount = p->a; 56 | 57 | InitFib(); 58 | 59 | while (callCount < MAX_FIB) 60 | { 61 | DoForegroundProcess(); 62 | } 63 | myString[14] = 'g'; 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /webviews/shared/thrift/CRunDisplay.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { crun } from "./crun_types"; 10 | 11 | 12 | /** 13 | * Service for presenting C-RUN messages to the user. 14 | */ 15 | export declare class Client { 16 | input: Thrift.TJSONProtocol; 17 | output: Thrift.TJSONProtocol; 18 | seqid: number; 19 | 20 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 21 | 22 | itemAdded(message: CRunMessage, partnerNamespace: string): Q.Promise; 23 | 24 | itemAdded(message: CRunMessage, partnerNamespace: string, callback?: (data: void)=>void): void; 25 | 26 | itemUpdated(message: CRunMessage, partnerNamespace: string): Q.Promise; 27 | 28 | itemUpdated(message: CRunMessage, partnerNamespace: string, callback?: (data: void)=>void): void; 29 | 30 | itemRemoved(index: number, partnerNamespace: string): Q.Promise; 31 | 32 | itemRemoved(index: number, partnerNamespace: string, callback?: (data: void)=>void): void; 33 | 34 | updateAll(partnerNamespace: string): Q.Promise; 35 | 36 | updateAll(partnerNamespace: string, callback?: (data: void)=>void): void; 37 | 38 | filtersChanged(partnerNamespace: string): Q.Promise; 39 | 40 | filtersChanged(partnerNamespace: string, callback?: (data: void)=>void): void; 41 | } 42 | -------------------------------------------------------------------------------- /src/dap/breakpoints/descriptors/locOnlyDescriptor.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import { BreakpointDescriptor } from "./breakpointDescriptor"; 5 | import { DescriptorReader } from "./descriptorReader"; 6 | import { DescriptorWriter } from "./descriptorWriter"; 7 | 8 | /** 9 | * A descriptor carrying enablement state, category id, and a ULE 10 | */ 11 | export class LocOnlyDescriptor extends BreakpointDescriptor { 12 | public ule: string; 13 | 14 | /** 15 | * Typescript doesn't support multiple constructors, so we have to fuse them together like this. 16 | * constructor(reader: DescriptorReader) 17 | * Constructs a new descriptor by deserializing from the given reader. 18 | * constructor([categoryId: string, ule: string]) 19 | * Creates a new descriptor from scratch using the given category id and ule. 20 | */ 21 | constructor(arg: DescriptorReader | [string, string]) { 22 | if (arg instanceof DescriptorReader) { 23 | super(arg); 24 | this.ule = arg.readString(); 25 | } else { 26 | const [categoryId, ule] = arg; 27 | super(categoryId); 28 | this.ule = ule; 29 | } 30 | } 31 | 32 | override serialize(writer: DescriptorWriter) { 33 | super.serialize(writer); 34 | writer.writeString(this.ule); 35 | } 36 | } -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es2021", 5 | "outDir": "out", 6 | "lib": [ 7 | "es2021", 8 | "DOM" 9 | ], 10 | "rootDir": ".", 11 | "sourceMap": true, 12 | "allowJs": true, 13 | "allowSyntheticDefaultImports": true, 14 | /* Strict Type-Checking Option */ 15 | "strict": true, /* enable all strict type-checking options */ 16 | /* Additional Checks */ 17 | "noUnusedLocals": true, /* Report errors on unused locals. */ 18 | "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 19 | "noUnusedParameters": true, /* Report errors on unused parameters. */ 20 | "alwaysStrict": true, /* Ensure that all files emit "use strict" */ 21 | "strictBindCallApply": true, /* Enable type checks for call/bind/apply */ 22 | "strictFunctionTypes": true, /* Stricter type checks for function parameters */ 23 | "noImplicitOverride": true, /* Force use of 'override' keyword */ 24 | "noPropertyAccessFromIndexSignature": true, /* Report errors when accessing nonexistent fields */ 25 | "noUncheckedIndexedAccess": true, /* Add 'undefined' to the type returned from indexed accesses */ 26 | "isolatedModules": true, /* Recommended when using bundlers */ 27 | }, 28 | "exclude": [ 29 | "out/**/*", 30 | "node_modules", 31 | ".vscode-test" 32 | ] 33 | } -------------------------------------------------------------------------------- /webviews/shared/thrift/PartnerRegistry.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { ampsync } from "./ampsync_types"; 11 | 12 | 13 | export declare class Client extends HeartbeatService.Client { 14 | input: Thrift.TJSONProtocol; 15 | output: Thrift.TJSONProtocol; 16 | seqid: number; 17 | 18 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 19 | 20 | GetAllPartners(): Q.Promise; 21 | 22 | GetAllPartners(callback?: (data: PartnerInformation[])=>void): void; 23 | 24 | GetPartnerInfo(who: number): Q.Promise; 25 | 26 | GetPartnerInfo(who: number, callback?: (data: PartnerInformation)=>void): void; 27 | 28 | AcknowledgePartnerIsAlive(myId: number): Q.Promise; 29 | 30 | AcknowledgePartnerIsAlive(myId: number, callback?: (data: void)=>void): void; 31 | 32 | IsPartnerAlive(who: number): Q.Promise; 33 | 34 | IsPartnerAlive(who: number, callback?: (data: boolean)=>void): void; 35 | 36 | SetPartnerInfo(information: PartnerInformation): Q.Promise; 37 | 38 | SetPartnerInfo(information: PartnerInformation, callback?: (data: void)=>void): void; 39 | 40 | SetAllPartners(allPartners: PartnerInformation[]): Q.Promise; 41 | 42 | SetAllPartners(allPartners: PartnerInformation[], callback?: (data: void)=>void): void; 43 | } 44 | -------------------------------------------------------------------------------- /webviews/shared/thrift/DebuggerStarter.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { ampsync } from "./ampsync_types"; 11 | 12 | 13 | export declare class Client extends HeartbeatService.Client { 14 | input: Thrift.TJSONProtocol; 15 | output: Thrift.TJSONProtocol; 16 | seqid: number; 17 | 18 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 19 | 20 | Configure(stageDir: string, defaultTool: Tools): Q.Promise; 21 | 22 | Configure(stageDir: string, defaultTool: Tools, callback?: (data: void)=>void): void; 23 | 24 | StartServiceRegistry(): Q.Promise; 25 | 26 | StartServiceRegistry(callback?: (data: ServiceLocation)=>void): void; 27 | 28 | StartDebuggers(parentServiceRegistryLoc: ServiceLocation, sharedServiceRegistryLoc: ServiceLocation): Q.Promise; 29 | 30 | StartDebuggers(parentServiceRegistryLoc: ServiceLocation, sharedServiceRegistryLoc: ServiceLocation, callback?: (data: ServiceLocation[])=>void): void; 31 | 32 | TerminateDebuggers(): Q.Promise; 33 | 34 | TerminateDebuggers(callback?: (data: void)=>void): void; 35 | 36 | GetPartnerNamespace(partnerId: number, sharedServiceRegistryLoc: ServiceLocation): Q.Promise; 37 | 38 | GetPartnerNamespace(partnerId: number, sharedServiceRegistryLoc: ServiceLocation, callback?: (data: string)=>void): void; 39 | } 40 | -------------------------------------------------------------------------------- /webviews/shared/thrift/TimelineBackend.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { timeline } from "./timeline_types"; 11 | 12 | 13 | /** 14 | * Service for retrieving Timeline data from the backend 15 | */ 16 | export declare class Client extends HeartbeatService.Client { 17 | input: Thrift.TJSONProtocol; 18 | output: Thrift.TJSONProtocol; 19 | seqid: number; 20 | 21 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 22 | 23 | getChannels(): Q.Promise; 24 | 25 | getChannels(callback?: (data: TimelineChannelInfo[])=>void): void; 26 | 27 | getCPUClock(): Q.Promise; 28 | 29 | getCPUClock(callback?: (data: Int64)=>void): void; 30 | 31 | readData(id: string, startTime: Int64, endTime: Int64): Q.Promise; 32 | 33 | readData(id: string, startTime: Int64, endTime: Int64, callback?: (data: string)=>void): void; 34 | 35 | readOverflows(id: string, startTime: Int64, endTime: Int64): Q.Promise; 36 | 37 | readOverflows(id: string, startTime: Int64, endTime: Int64, callback?: (data: string)=>void): void; 38 | 39 | enable(id: string, enabled: boolean): Q.Promise; 40 | 41 | enable(id: string, enabled: boolean, callback?: (data: void)=>void): void; 42 | 43 | isEnabled(id: string): Q.Promise; 44 | 45 | isEnabled(id: string, callback?: (data: boolean)=>void): void; 46 | } 47 | -------------------------------------------------------------------------------- /samples/GettingStarted/Utilities.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 - 2016 IAR Systems AB. 3 | * 4 | * IAR Embedded Workbench tutorial 5 | * 6 | * Utilities.c 7 | * 8 | * Contains utility functions used in Fibonacci.c. 9 | * 10 | * See the file /doc/licenses/IARSourceLicense.txt for detailed 11 | * license information. 12 | * 13 | * $Revision: 113247 $ 14 | */ 15 | 16 | #include 17 | #include 18 | #include "Utilities.h" 19 | 20 | static uint32_t Fib[MAX_FIB]; 21 | 22 | /* Initializes MAX_FIB Fibonacci numbers. */ 23 | void InitFib(void) 24 | { 25 | int_fast8_t i; 26 | Fib[0] = Fib[1] = 1u; 27 | 28 | for (i = 2; i < MAX_FIB; i++) 29 | { 30 | Fib[i] = GetFib(i) + GetFib(i-1); 31 | } 32 | } 33 | 34 | /* Returns the Fibonacci number 'n'. */ 35 | uint32_t GetFib(int_fast8_t n) 36 | { 37 | uint32_t retval; 38 | if ((n > 0) && (n <= MAX_FIB)) 39 | { 40 | retval = Fib[n-1]; 41 | } 42 | else 43 | { 44 | retval = 0u; 45 | } 46 | return retval; 47 | } 48 | 49 | /* Sends a number between 0 and 65535 to stdout. */ 50 | void PutFib(uint32_t out) 51 | { 52 | uint32_t dec = 10u, temp; 53 | 54 | if (out >= 10000u) /* Value too large. */ 55 | { 56 | putchar('#'); /* Print a '#'. */ 57 | } 58 | else 59 | { 60 | putchar('\n'); 61 | while (dec <= out) 62 | { 63 | dec *= 10u; 64 | } 65 | 66 | while ((dec /= 10u) >= 10u) 67 | { 68 | temp = out / dec; 69 | putchar('0' + (char)temp); 70 | out -= temp * dec; 71 | } 72 | 73 | putchar('0' + (char)out); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /tests/TestProjects/ConfigTests/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "extensionHost", 6 | "request": "launch", 7 | "name": "Extension", 8 | "preLaunchTask": "npm", 9 | "runtimeExecutable": "${execPath}", 10 | "args": [ 11 | "--extensionDevelopmentPath=${workspaceFolder}", 12 | "${workspaceFolder}/samples/GettingStarted" 13 | ], 14 | "outFiles": [ "${workspaceFolder}/out/**/*.js" ] 15 | }, 16 | { 17 | "name": "Run Debugger Tests", 18 | "type": "extensionHost", 19 | "request": "launch", 20 | "runtimeExecutable": "${execPath}", 21 | "args": [ 22 | "--extensionDevelopmentPath=${workspaceFolder}", 23 | "--extensionTestsPath=${workspaceFolder}/out/tests/suites/dbg/index" 24 | ], 25 | "outFiles": [ "${workspaceFolder}/out/**/*.js" ], 26 | "preLaunchTask": "npm: compile", 27 | "presentation": { 28 | "group": "Tests", 29 | } 30 | }, 31 | { 32 | "name": "Run Configuration Tests", 33 | "type": "extensionHost", 34 | "request": "launch", 35 | "runtimeExecutable": "${execPath}", 36 | "args": [ 37 | "--extensionDevelopmentPath=${workspaceFolder}", 38 | "--extensionTestsPath=${workspaceFolder}/out/tests/suites/config/index", 39 | "${workspaceFolder}/src/tests/TestProjects/ConfigTests" 40 | ], 41 | "outFiles": [ "${workspaceFolder}/out/**/*.js" ], 42 | "preLaunchTask": "npm: compile", 43 | "presentation": { 44 | "group": "Tests", 45 | } 46 | }, 47 | ], 48 | "compounds": [ 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /tests/TestProjects/GettingStarted/Utilities.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 - 2016 IAR Systems AB. 3 | * 4 | * IAR Embedded Workbench tutorial 5 | * 6 | * Utilities.c 7 | * 8 | * Contains utility functions used in Fibonacci.c. 9 | * 10 | * See the file /doc/licenses/IARSourceLicense.txt for detailed 11 | * license information. 12 | * 13 | * $Revision: 113247 $ 14 | */ 15 | 16 | #include 17 | #include 18 | #include "Utilities.h" 19 | 20 | static uint32_t Fib[MAX_FIB]; 21 | 22 | /* Initializes MAX_FIB Fibonacci numbers. */ 23 | void InitFib(void) 24 | { 25 | int_fast8_t i; 26 | Fib[0] = Fib[1] = 1u; 27 | 28 | for (i = 2; i < MAX_FIB; i++) 29 | { 30 | Fib[i] = GetFib(i) + GetFib(i-1); 31 | } 32 | } 33 | 34 | /* Returns the Fibonacci number 'n'. */ 35 | uint32_t GetFib(int_fast8_t n) 36 | { 37 | uint32_t retval; 38 | if ((n > 0) && (n <= MAX_FIB)) 39 | { 40 | retval = Fib[n-1]; 41 | } 42 | else 43 | { 44 | retval = 0u; 45 | } 46 | return retval; 47 | } 48 | 49 | /* Sends a number between 0 and 65535 to stdout. */ 50 | void PutFib(uint32_t out) 51 | { 52 | uint32_t dec = 10u, temp; 53 | 54 | if (out >= 10000u) /* Value too large. */ 55 | { 56 | putchar('#'); /* Print a '#'. */ 57 | } 58 | else 59 | { 60 | putchar('\n'); 61 | while (dec <= out) 62 | { 63 | dec *= 10u; 64 | } 65 | 66 | while ((dec /= 10u) >= 10u) 67 | { 68 | temp = out / dec; 69 | putchar('0' + (char)temp); 70 | out -= temp * dec; 71 | } 72 | 73 | putchar('0' + (char)out); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /webviews/shared/thrift/Disassembly.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { disassembly } from "./disassembly_types"; 11 | 12 | 13 | /** 14 | * The Disassembly service retrieves assembler instructions for a specific memory range 15 | */ 16 | export declare class Client extends HeartbeatService.Client { 17 | input: Thrift.TJSONProtocol; 18 | output: Thrift.TJSONProtocol; 19 | seqid: number; 20 | 21 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 22 | 23 | /** 24 | * Retrieve a list of disassembled instructions for a specific memory range. 25 | */ 26 | disassembleRange(_from: Location, _to: Location, context: ContextRef): Q.Promise; 27 | 28 | /** 29 | * Retrieve a list of disassembled instructions for a specific memory range. 30 | */ 31 | disassembleRange(_from: Location, _to: Location, context: ContextRef, callback?: (data: DisassembledLocation[])=>void): void; 32 | 33 | /** 34 | * This method is currently not implemented and will fail if called. 35 | */ 36 | disassembleLines(_from: Location, numLines: number, context: ContextRef): Q.Promise; 37 | 38 | /** 39 | * This method is currently not implemented and will fail if called. 40 | */ 41 | disassembleLines(_from: Location, numLines: number, context: ContextRef, callback?: (data: DisassembledLocation[])=>void): void; 42 | } 43 | -------------------------------------------------------------------------------- /src/dap/breakpoints/exceptionBreakpoint.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import { DebugProtocol } from "@vscode/debugprotocol"; 6 | import * as Debugger from "iar-vsc-common/thrift/bindings/Debugger"; 7 | 8 | /** 9 | * Controls if/when to break on c++ exceptions 10 | */ 11 | export namespace ExceptionBreakpoints { 12 | // Exported for testing only 13 | export enum ExceptionFilters { 14 | BreakOnThrow = "breakOnThrow", 15 | BreakOnUncaughtException = "uncaughtException", 16 | } 17 | 18 | export function getExceptionFilters(): DebugProtocol.ExceptionBreakpointsFilter[] { 19 | return [ 20 | { 21 | filter: ExceptionFilters.BreakOnThrow, 22 | label: "Break on Throw", 23 | }, 24 | { 25 | filter: ExceptionFilters.BreakOnUncaughtException, 26 | label: "Break on Uncaught Exception", 27 | } 28 | ]; 29 | } 30 | 31 | export async function setEnabledExceptionFilters(filters: string[], dbg: Debugger.Client) { 32 | if (!await dbg.supportsExceptions()) { 33 | return; 34 | } 35 | 36 | const doBreakOnThrow = filters.includes(ExceptionFilters.BreakOnThrow); 37 | await dbg.setBreakOnThrow(doBreakOnThrow); 38 | 39 | const doBreakOnUncaught = filters.includes(ExceptionFilters.BreakOnUncaughtException); 40 | await dbg.setBreakOnUncaughtException(doBreakOnUncaught); 41 | } 42 | } -------------------------------------------------------------------------------- /webviews/test/listwindow/tooltip.test.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | /* eslint-disable @typescript-eslint/no-non-null-assertion */ 5 | 6 | import * as Assert from "assert"; 7 | import { queries } from "@testing-library/dom"; 8 | import { TestUtils } from "./utils"; 9 | import { setupTestEnvironment } from "./testEnvironment"; 10 | 11 | suite("Listwindow tooltips", () => { 12 | test("Shows and hides tooltips", async() => { 13 | const { api, dom, user } = await setupTestEnvironment(); 14 | 15 | const renderParams = TestUtils.generateRenderParameters(1); 16 | await TestUtils.render(api, renderParams); 17 | 18 | const cell = renderParams.rows[0]!.cells[0]!; 19 | const cellElem = queries.getByText( 20 | dom.window.document.documentElement, 21 | cell.text, 22 | ); 23 | 24 | user.hover(cellElem); 25 | const msg = await api.waitForMessage("getTooltip", 2000); 26 | Assert.strictEqual(msg.col, 0); 27 | Assert.strictEqual(msg.row.value, "0"); 28 | const tooltipText = "hello tooltip"; 29 | api.postMessage({ 30 | subject: "tooltipReply", 31 | text: tooltipText, 32 | }); 33 | 34 | const tooltip = await queries.findByText( 35 | dom.window.document.documentElement, 36 | tooltipText, 37 | ); 38 | 39 | await user.unhover(cellElem); 40 | Assert.strictEqual(tooltip.isConnected, false); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /webviews/shared/thrift/CRunBackend.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { crun } from "./crun_types"; 10 | 11 | 12 | /** 13 | * Service for controlling filters and actions. 14 | */ 15 | export declare class Client { 16 | input: Thrift.TJSONProtocol; 17 | output: Thrift.TJSONProtocol; 18 | seqid: number; 19 | 20 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 21 | 22 | loadFilters(filename: string): Q.Promise; 23 | 24 | loadFilters(filename: string, callback?: (data: void)=>void): void; 25 | 26 | saveFilters(filename: string): Q.Promise; 27 | 28 | saveFilters(filename: string, callback?: (data: void)=>void): void; 29 | 30 | addRuleOnMessage(messageName: string): Q.Promise; 31 | 32 | addRuleOnMessage(messageName: string, callback?: (data: void)=>void): void; 33 | 34 | addRuleOnMessageFile(messageName: string, file: string): Q.Promise; 35 | 36 | addRuleOnMessageFile(messageName: string, file: string, callback?: (data: void)=>void): void; 37 | 38 | addRuleOnMessageRange(messageName: string, range: SourceRange): Q.Promise; 39 | 40 | addRuleOnMessageRange(messageName: string, range: SourceRange, callback?: (data: void)=>void): void; 41 | 42 | setDefaultAction(action: CRunBreakAction): Q.Promise; 43 | 44 | setDefaultAction(action: CRunBreakAction, callback?: (data: void)=>void): void; 45 | 46 | getDefaultAction(): Q.Promise; 47 | 48 | getDefaultAction(callback?: (data: CRunBreakAction)=>void): void; 49 | } 50 | -------------------------------------------------------------------------------- /src/debugSessionTracker.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import * as vscode from "vscode"; 5 | import { logger } from "iar-vsc-common/logger"; 6 | 7 | /** 8 | * The VSCode api has no way of getting all running sessions, only the 'active' one. 9 | * This class listens for session start/stop events and keeps a record of all running sessions. 10 | */ 11 | export class DebugSessionTracker { 12 | private readonly sessions: vscode.DebugSession[] = []; 13 | 14 | constructor(context: vscode.ExtensionContext) { 15 | context.subscriptions.push(vscode.debug.onDidStartDebugSession(session => { 16 | logger.debug(`Session Tracker: Started '${session.name}'`); 17 | if (session.type === "cspy") { 18 | this.sessions.push(session); 19 | } 20 | })); 21 | context.subscriptions.push(vscode.debug.onDidTerminateDebugSession(session => { 22 | logger.debug(`Session Tracker: Terminated '${session.name}'`); 23 | 24 | if (this.sessions.includes(session)) { 25 | this.sessions.splice(this.sessions.indexOf(session), 1); 26 | } 27 | })); 28 | // If we were initialized after a session was starting, we won't see it in onDidStartDebugSession 29 | if (vscode.debug.activeDebugSession && vscode.debug.activeDebugSession.type === "cspy") { 30 | this.sessions.push(vscode.debug.activeDebugSession); 31 | } 32 | } 33 | 34 | get runningSessions(): vscode.DebugSession[] { 35 | return this.sessions; 36 | } 37 | } -------------------------------------------------------------------------------- /webviews/shared/thrift/CodeCoverage.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { codecoverage } from "./codecoverage_types"; 11 | 12 | 13 | export declare class Client extends HeartbeatService.Client { 14 | input: Thrift.TJSONProtocol; 15 | output: Thrift.TJSONProtocol; 16 | seqid: number; 17 | 18 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 19 | 20 | getSessionId(): Q.Promise; 21 | 22 | getSessionId(callback?: (data: Int64)=>void): void; 23 | 24 | enable(enable: boolean): Q.Promise; 25 | 26 | enable(enable: boolean, callback?: (data: boolean)=>void): void; 27 | 28 | isEnabled(): Q.Promise; 29 | 30 | isEnabled(callback?: (data: boolean)=>void): void; 31 | 32 | hasMetaDataSupport(): Q.Promise; 33 | 34 | hasMetaDataSupport(callback?: (data: boolean)=>void): void; 35 | 36 | clearCachedData(): Q.Promise; 37 | 38 | clearCachedData(callback?: (data: void)=>void): void; 39 | 40 | isInitialized(): Q.Promise; 41 | 42 | isInitialized(callback?: (data: boolean)=>void): void; 43 | 44 | initializeMetaData(): Q.Promise; 45 | 46 | initializeMetaData(callback?: (data: void)=>void): void; 47 | 48 | reinitMetaData(): Q.Promise; 49 | 50 | reinitMetaData(callback?: (data: boolean)=>void): void; 51 | 52 | refreshMetaData(): Q.Promise; 53 | 54 | refreshMetaData(callback?: (data: void)=>void): void; 55 | 56 | getXMLData(): Q.Promise; 57 | 58 | getXMLData(callback?: (data: string)=>void): void; 59 | } 60 | -------------------------------------------------------------------------------- /webviews/shared/thrift/CoresRegistry.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { ampsync } from "./ampsync_types"; 11 | 12 | 13 | export declare class Client extends HeartbeatService.Client { 14 | input: Thrift.TJSONProtocol; 15 | output: Thrift.TJSONProtocol; 16 | seqid: number; 17 | 18 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 19 | 20 | NumberOfCores(): Q.Promise; 21 | 22 | NumberOfCores(callback?: (data: number)=>void): void; 23 | 24 | AllCores(): Q.Promise; 25 | 26 | AllCores(callback?: (data: CoreInfo[])=>void): void; 27 | 28 | GetInfo(coreNumber: number): Q.Promise; 29 | 30 | GetInfo(coreNumber: number, callback?: (data: CoreInfo)=>void): void; 31 | 32 | SetInfo(updated: CoreInfo): Q.Promise; 33 | 34 | SetInfo(updated: CoreInfo, callback?: (data: void)=>void): void; 35 | 36 | SetInfoPartial(updated: number, props: { [k: string]: string; }): Q.Promise; 37 | 38 | SetInfoPartial(updated: number, props: { [k: string]: string; }, callback?: (data: void)=>void): void; 39 | 40 | PartnerCores(partner: number): Q.Promise; 41 | 42 | PartnerCores(partner: number, callback?: (data: CoreRange)=>void): void; 43 | 44 | SetNumberOfCores(partner: number, numberOfCores: number): Q.Promise; 45 | 46 | SetNumberOfCores(partner: number, numberOfCores: number, callback?: (data: CoreRange)=>void): void; 47 | 48 | ResetAfterDebugSession(): Q.Promise; 49 | 50 | ResetAfterDebugSession(callback?: (data: void)=>void): void; 51 | } 52 | -------------------------------------------------------------------------------- /src/dap/breakpoints/descriptors/breakpointDescriptor.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import { DescriptorReader } from "./descriptorReader"; 5 | import { DescriptorWriter } from "./descriptorWriter"; 6 | 7 | /** 8 | * Describes a generic breakpoint descriptor from C-SPY, of any type. 9 | * Right now only supports deserializing, there is no need (yet) for us to serialize these. 10 | */ 11 | export class BreakpointDescriptor { 12 | public enabled = true; 13 | public categoryId: string; 14 | 15 | /** 16 | * Typescript doesn't support multiple constructors, so we have to fuse them together like this. 17 | * constructor(reader: DescriptorReader) 18 | * Constructs a new descriptor by deserializing from the given reader. 19 | * constructor(categoryId: string) 20 | * Creates a new descriptor from scratch using the given category. It is enabled by default. 21 | */ 22 | constructor(arg: DescriptorReader | string) { 23 | if (arg instanceof DescriptorReader) { 24 | const reader = arg; 25 | this.enabled = reader.readBoolean(); 26 | this.categoryId = reader.readString(); 27 | } else { 28 | this.categoryId = arg; 29 | } 30 | } 31 | 32 | /** 33 | * Gets this descriptor in string form. 34 | * Deriving classes must override this method and write their own properties to the writer 35 | * (*after* calling super.serialize). 36 | */ 37 | serialize(writer: DescriptorWriter) { 38 | writer.writeBool(this.enabled); 39 | writer.writeString(this.categoryId); 40 | } 41 | } -------------------------------------------------------------------------------- /src/dap/breakpoints/descriptors/tdlEmulTraceBreakpointDescriptor.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import { DescriptorReader } from "./descriptorReader"; 5 | import { DescriptorWriter } from "./descriptorWriter"; 6 | import { EmulDataBreakpointDescriptor } from "./emulDataBreakpointDescriptor"; 7 | 8 | export enum TdlEmulTraceBreakpointAccessType { 9 | ReadWrite = 0, 10 | Read, 11 | Write, 12 | Fetch, 13 | } 14 | 15 | /** 16 | * Breakpoint descriptor for TDL_EMUL_TRACE_. These are identical 17 | * to EMUL_DATA, except that they allow a 'fetch' access type. 18 | */ 19 | export class TdlEmulTraceDescriptor extends EmulDataBreakpointDescriptor { 20 | 21 | /** 22 | * Typescript doesn't support multiple constructors, so we have to fuse them together like this. 23 | * constructor(reader: DescriptorReader) 24 | * Constructs a new descriptor by deserializing from the given reader. 25 | * constructor([categoryId: string, ule: string, access: TdlEmulTraceBreakpointAccessType]) 26 | * Creates a new descriptor from scratch using the given category id, ule and access type. Other attributes 27 | * will be given their default values. 28 | */ 29 | constructor(arg: DescriptorReader | [string, string, TdlEmulTraceBreakpointAccessType]) { 30 | if (arg instanceof DescriptorReader) { 31 | const reader = arg; 32 | super(reader); 33 | } else { 34 | const [categoryId, ule, access] = arg; 35 | super([categoryId, ule, access]); 36 | } 37 | } 38 | 39 | override serialize(writer: DescriptorWriter) { 40 | super.serialize(writer); 41 | } 42 | } -------------------------------------------------------------------------------- /src/dap/breakpoints/descriptors/dataLocEtcDescriptor.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import { AccessType } from "./accessType"; 5 | import { DescriptorReader } from "./descriptorReader"; 6 | import { DescriptorWriter } from "./descriptorWriter"; 7 | import { LocEtcDescriptor } from "./locEtcDescriptor"; 8 | 9 | /** 10 | * Breakpoint descriptor for data breakpoints (e.g. STD_DATA2). 11 | */ 12 | export class DataLocEtcDescriptor extends LocEtcDescriptor { 13 | /** 14 | * The access type to break on (e.g. read/write/readWrite) 15 | */ 16 | private readonly access: AccessType; 17 | 18 | /** 19 | * Typescript doesn't support multiple constructors, so we have to fuse them together like this. 20 | * constructor(reader: DescriptorReader) 21 | * Constructs a new descriptor by deserializing from the given reader. 22 | * constructor([categoryId: string, ule: string, access: AccessType]) 23 | * Creates a new descriptor from scratch using the given category id, ule and access type. Other attributes 24 | * will be given their default values. 25 | */ 26 | constructor(arg: DescriptorReader | [string, string, AccessType]) { 27 | if (arg instanceof DescriptorReader) { 28 | const reader = arg; 29 | super(reader); 30 | this.access = reader.readInteger(); 31 | } else { 32 | const [categoryId, ule, access] = arg; 33 | super([categoryId, ule]); 34 | this.access = access; 35 | } 36 | } 37 | 38 | override serialize(writer: DescriptorWriter) { 39 | super.serialize(writer); 40 | writer.writeInteger(this.access); 41 | } 42 | } -------------------------------------------------------------------------------- /webviews/listwindow/rendering/styles/sharedStyles.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | 6 | import { css } from "@emotion/css"; 7 | import { Alignment } from "../../../shared/thrift/listwindow_types"; 8 | 9 | /** 10 | * Classes and styles that are shared across components. 11 | */ 12 | export namespace SharedStyles { 13 | /** An element over which a dragged element is being hovered */ 14 | export const dropTarget = css({ 15 | background: "var(--vscode-list-dropBackground) !important", 16 | color: "inherit !important", 17 | }); 18 | 19 | /** 20 | * Get the css class corresponding to the given {@link Alignment}. 21 | */ 22 | export function alignmentToStyle(alignment: Alignment): string { 23 | switch (alignment) { 24 | case Alignment.kLeft: 25 | return ALIGNMENT_LEFT; 26 | case Alignment.kRight: 27 | return ALIGNMENT_RIGHT; 28 | case Alignment.kCenter: 29 | return ALIGNMENT_CENTER; 30 | } 31 | } 32 | const ALIGNMENT_LEFT = css({ 33 | textAlign: "left", 34 | justifySelf: "left", 35 | }); 36 | const ALIGNMENT_RIGHT = css({ 37 | textAlign: "right", 38 | justifySelf: "right", 39 | }); 40 | const ALIGNMENT_CENTER = css({ 41 | textAlign: "center", 42 | justifySelf: "center", 43 | }); 44 | 45 | // "z-index" values used by various elements. By defining them in one place, 46 | // it's easier to get an overview of how the elements stack. 47 | export enum ZIndices { 48 | Toolbar = 2, 49 | Tooltip = 3, 50 | ContextMenu = 3, 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/listwindows/README.md: -------------------------------------------------------------------------------- 1 | # Listwindow Architecture 2 | 3 | The code in this folder sits between the webview code (see `webviews/listwindow`) 4 | and the listwindow backends in CSpyServer, similar to the `ListwindowProxy` concepts 5 | in the IDE and Eclipse. It is responsible for connecting to the backend whenever 6 | a debug session starts and fetching data from it, as well as instantiating the 7 | listwindow webviews and sending render parameters to them: 8 | 9 | ```mermaid 10 | graph LR 11 | A("Webview (Electron)") 12 | B("VSC Extension (nodejs)") 13 | C(CSpyServer2.exe) 14 | A -->|User Interaction| B -->|User Interaction\nFetching Data| C 15 | C -->|Thrift Notifications| B -->|Render Parameters| A 16 | ``` 17 | 18 | Note that the debug adapter is not involved here. It is simpler and more 19 | future-proof to have the extension speak thrift to CSpyServer directly. The only 20 | communication with the debug adapter will be at the start of a session; since 21 | the debug adapter owns the CSpyServer instance, we need to ask it where the 22 | service registry is located. 23 | 24 | Also note that VS Code can have multiple debug sessions running at the same 25 | time, but we will only have one instance of each listwindow webview. In this 26 | case, we maintain an active connection to each backend, but make sure to only 27 | render data from and send user interactions to the backend for the session that 28 | VS Code considers the "active" one: 29 | 30 | ```mermaid 31 | graph RL 32 | A("Webview (Electron)") 33 | B("VSC Extension (nodejs)") 34 | subgraph Sessions 35 | D(CSpyServer2.exe) 36 | E(CSpyServer2.exe) 37 | F(CSpyServer2.exe) 38 | end 39 | A -->|User Interaction| B -->|User Interaction\nFetching Data| D 40 | D & E & F -->|Notifications| B -->|Render Parameters| A 41 | style E stroke-width:0px 42 | style F stroke-width:0px 43 | ``` 44 | -------------------------------------------------------------------------------- /src/dap/breakpoints/descriptors/emuTimerBreakpointDescriptor.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import { DescriptorReader } from "./descriptorReader"; 5 | import { DescriptorWriter } from "./descriptorWriter"; 6 | import { LocOnlyDescriptor } from "./locOnlyDescriptor"; 7 | 8 | /** 9 | * A descriptor for EMU_TIMER_ used by rh850 emulators 10 | */ 11 | export class EmuTimerBreakpointDescriptor extends LocOnlyDescriptor { 12 | private readonly timerNo: number; 13 | private readonly typeStart: boolean; 14 | 15 | /** 16 | * Typescript doesn't support multiple constructors, so we have to fuse them together like this. 17 | * constructor(reader: DescriptorReader) 18 | * Constructs a new descriptor by deserializing from the given reader. 19 | * constructor([categoryId: string, ule: string, timerNo: number]) 20 | * Creates a new descriptor from scratch using the given category id and ule. Other attributes 21 | * will be given their default values. 22 | */ 23 | constructor(arg: DescriptorReader | [string, string, number]) { 24 | if (arg instanceof DescriptorReader) { 25 | const reader = arg; 26 | super(reader); 27 | this.timerNo = reader.readInteger(); 28 | this.typeStart = reader.readBoolean(); 29 | } else { 30 | const [categoryId, ule, timerNo] = arg; 31 | super([categoryId, ule]); 32 | this.timerNo = timerNo; 33 | this.typeStart = false; 34 | } 35 | } 36 | 37 | override serialize(writer: DescriptorWriter) { 38 | super.serialize(writer); 39 | writer.writeInteger(this.timerNo); 40 | writer.writeBool(this.typeStart); 41 | } 42 | } -------------------------------------------------------------------------------- /src/dap/breakpoints/descriptors/emulCodeBreakpointDescriptor.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import { DescriptorReader } from "./descriptorReader"; 5 | import { DescriptorWriter } from "./descriptorWriter"; 6 | import { LocEtcDescriptor } from "./locEtcDescriptor"; 7 | 8 | /** 9 | * Breakpoint descriptor for EMUL_CODE breakpoints, used e.g. by i-jet and j-link. 10 | * The same as STD_CODE2, but adds an additional type property. 11 | */ 12 | export class EmulCodeBreakpointDescriptor extends LocEtcDescriptor { 13 | /** 14 | * The type specifies e.g. if this is a hardware or software breakpoint. 15 | * The exact values used and their meanings is driver-dependent. 16 | */ 17 | public type: number; 18 | 19 | /** 20 | * Typescript doesn't support multiple constructors, so we have to fuse them together like this. 21 | * constructor(reader: DescriptorReader) 22 | * Constructs a new descriptor by deserializing from the given reader. 23 | * constructor([categoryId: string, ule: string, type: number]) 24 | * Creates a new descriptor from scratch using the given category id, ule and type. Other attributes 25 | * will be given their default values. 26 | */ 27 | constructor(arg: DescriptorReader | [string, string, number]) { 28 | if (arg instanceof DescriptorReader) { 29 | const reader = arg; 30 | super(reader); 31 | this.type = reader.readInteger(); 32 | } else { 33 | const [categoryId, ule, type] = arg; 34 | super([categoryId, ule]); 35 | this.type = type; 36 | } 37 | } 38 | 39 | override serialize(writer: DescriptorWriter) { 40 | super.serialize(writer); 41 | writer.writeInteger(this.type); 42 | } 43 | } -------------------------------------------------------------------------------- /webviews/shared/thrift/TimelineFrontend.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { timeline } from "./timeline_types"; 10 | 11 | 12 | /** 13 | * Listener service for timeline notifications, hosted by the frontend. As we only run a single frontend per session, we must include the partnerId in the communication. 14 | */ 15 | export declare class Client { 16 | input: Thrift.TJSONProtocol; 17 | output: Thrift.TJSONProtocol; 18 | seqid: number; 19 | 20 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 21 | 22 | dataAvailable(note: DbuTimelineDataAvailableNotification, partnerNamespace: string): Q.Promise; 23 | 24 | dataAvailable(note: DbuTimelineDataAvailableNotification, partnerNamespace: string, callback?: (data: void)=>void): void; 25 | 26 | channelAvailable(note: DbuTimelineChannelAvailableNotification, partnerNamespace: string): Q.Promise; 27 | 28 | channelAvailable(note: DbuTimelineChannelAvailableNotification, partnerNamespace: string, callback?: (data: void)=>void): void; 29 | 30 | channelRemoved(note: DbuTimelineChannelRemovedNotification, partnerNamespace: string): Q.Promise; 31 | 32 | channelRemoved(note: DbuTimelineChannelRemovedNotification, partnerNamespace: string, callback?: (data: void)=>void): void; 33 | 34 | cpuClockChanged(note: DbuTimelineCpuClockChangedNotification, partnerNamespace: string): Q.Promise; 35 | 36 | cpuClockChanged(note: DbuTimelineCpuClockChangedNotification, partnerNamespace: string, callback?: (data: void)=>void): void; 37 | 38 | enablementChanged(note: DbuTimelineEnablementChangedNotification, partnerNamespace: string): Q.Promise; 39 | 40 | enablementChanged(note: DbuTimelineEnablementChangedNotification, partnerNamespace: string, callback?: (data: void)=>void): void; 41 | } 42 | -------------------------------------------------------------------------------- /src/contextChangedHandler.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import * as vscode from "vscode"; 6 | import { CustomEvent } from "./dap/customRequest"; 7 | 8 | /** 9 | * Handles the custom event "contextChanged" from the debug adapter, by moving 10 | * the text editor to the new context location. 11 | */ 12 | export namespace ContextChangedHandler { 13 | 14 | export function initialize() { 15 | vscode.debug.onDidReceiveDebugSessionCustomEvent(async ev => { 16 | if (ev.event === CustomEvent.Names.CONTEXT_CHANGED) { 17 | const body = ev.body as CustomEvent.ContextChangedData; 18 | 19 | const editor = await vscode.window.showTextDocument( 20 | vscode.Uri.file(body.file.path), 21 | ); 22 | 23 | // VS Code uses 1-based line and column numbers for DAP 24 | // communication, but 0-based for its own API. 25 | const startLine = body.startLine - 1; 26 | const startColumn = body.startColumn - 1; 27 | const endLine = body.endLine - 1; 28 | const endColumn = body.endColumn - 1; 29 | 30 | editor.revealRange( 31 | new vscode.Range( 32 | startLine, 33 | startColumn, 34 | endLine, 35 | endColumn, 36 | ), 37 | vscode.TextEditorRevealType.InCenterIfOutsideViewport, 38 | ); 39 | editor.selection = new vscode.Selection( 40 | new vscode.Position(startLine, startColumn), 41 | new vscode.Position(endLine, endColumn), 42 | ); 43 | } 44 | }); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /webviews/shared/thrift/Breakpoints.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { breakpoints } from "./breakpoints_types"; 11 | 12 | 13 | export declare class Client extends HeartbeatService.Client { 14 | input: Thrift.TJSONProtocol; 15 | output: Thrift.TJSONProtocol; 16 | seqid: number; 17 | 18 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 19 | 20 | getBreakpoints(): Q.Promise; 21 | 22 | getBreakpoints(callback?: (data: Breakpoint[])=>void): void; 23 | 24 | getBreakpoint(id: number): Q.Promise; 25 | 26 | getBreakpoint(id: number, callback?: (data: Breakpoint)=>void): void; 27 | 28 | setBreakpointFromDescriptor(descriptor: string): Q.Promise; 29 | 30 | setBreakpointFromDescriptor(descriptor: string, callback?: (data: Breakpoint)=>void): void; 31 | 32 | setBreakpointOnUle(ule: string, accessType: AccessType): Q.Promise; 33 | 34 | setBreakpointOnUle(ule: string, accessType: AccessType, callback?: (data: Breakpoint)=>void): void; 35 | 36 | setBreakpointOnUleWithCategory(ule: string, accessType: AccessType, categoryId: string): Q.Promise; 37 | 38 | setBreakpointOnUleWithCategory(ule: string, accessType: AccessType, categoryId: string, callback?: (data: Breakpoint)=>void): void; 39 | 40 | enableBreakpoint(id: number, enable: boolean): Q.Promise; 41 | 42 | enableBreakpoint(id: number, enable: boolean, callback?: (data: boolean)=>void): void; 43 | 44 | removeBreakpoint(id: number): Q.Promise; 45 | 46 | removeBreakpoint(id: number, callback?: (data: boolean)=>void): void; 47 | 48 | getRecentlyHitBreakpoints(): Q.Promise; 49 | 50 | getRecentlyHitBreakpoints(callback?: (data: Breakpoint[])=>void): void; 51 | } 52 | -------------------------------------------------------------------------------- /src/dap/breakpoints/descriptors/descriptorWriter.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import { DescriptorConstants } from "./descriptorReader"; 5 | 6 | 7 | /** 8 | * Based on the eclipse DescriptorReader class. 9 | * Serializes breakpoint attributes into a string. 10 | */ 11 | export class DescriptorWriter { 12 | private output = ""; 13 | 14 | constructor() { 15 | this.output += DescriptorConstants.DESCRIPTOR_HEADER; 16 | } 17 | 18 | writeInteger(int: number) { 19 | this.output += DescriptorConstants.SEPARATOR_CHAR; 20 | this.output += int.toString(); 21 | } 22 | 23 | writeBool(bool: boolean) { 24 | this.writeInteger(bool ? 1 : 0); 25 | } 26 | 27 | writeString(str: string) { 28 | 29 | // The percent sign is used as escape 30 | str = str.replace(/%/g, "%%"); 31 | 32 | // Double quotes and other special characters 33 | str = str.replace(/\cG/g, "%a");// "\a", bell 34 | str = str.replace(/[\b]/g, "%b"); 35 | str = str.replace(/\f/g, "%f"); 36 | str = str.replace(/\n/g, "%n"); 37 | str = str.replace(/\r/g, "%r"); 38 | str = str.replace(/\t/g, "%t"); 39 | str = str.replace(/\v/g, "%v");// "\v", vertical tab 40 | str = str.replace(/"/g, "%\""); 41 | 42 | // A percent at the end produces an extra space. This is to avoid 43 | // "escaping" the closing quote of the string as a special char. 44 | if (str.charAt(str.length - 1) === "%") 45 | str += " "; 46 | 47 | this.output += DescriptorConstants.SEPARATOR_CHAR; 48 | this.output += DescriptorConstants.STRING_DELIMITER; 49 | this.output += str; 50 | this.output += DescriptorConstants.STRING_DELIMITER; 51 | } 52 | 53 | get result() { 54 | return this.output; 55 | } 56 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Reporting issues 4 | 5 | For urgent matters with the extension, or if you have issues with the underlying IAR Embedded Workbench product, report this via the IAR Systems technical support channel at [IAR Technical Support](https://www.iar.com/knowledge/support/request-technical-support/). 6 | For other matters isolated to this extension, file a [New issue](https://github.com/IARSystems/iar-vsc-debug/issues/new/choose) using the provided template. We will reply on a "best effort basis". 7 | 8 | Your bug report should include: 9 | 10 | * A short description of the bug 11 | * Instructions for how to reproduce the bug 12 | * Any relevant logs or error messages. Logging can be enabled for a debug session by adding the following to your `launch.json` configuration: 13 | 14 | ```json 15 | "trace": true, 16 | ``` 17 | 18 | Some additional logs can be found in the **Output** panel in VS Code, by selecting `IAR C-SPY Debug` in the dropdown in the top right. 19 | 20 | ## Feature requests 21 | 22 | To request a new feature, please first check if there is already a GitHub issue describing the feature you would like. 23 | If there is, please comment on and/or upvote that issue. Otherwise, you can create a new issue describing the feature 24 | you would like to have and why you want it. 25 | 26 | ## Contributing pull requests 27 | 28 | We welcome pull requests from users to this repository, such as documentation changes, bugfixes or new features. 29 | If the changes you want to make are large, please create an issue describing the changes *before* you start developing, 30 | so that we can discuss the best way to implement the changes. 31 | 32 | ### Getting started 33 | 34 | To build and run the extension from source on your computer, first clone this repository. 35 | 36 | Install the dependencies: 37 | 38 | ```sh 39 | npm install 40 | ``` 41 | 42 | Then, open this repository in VS Code, and install the recommended extensions. 43 | Start the extension by running the debug configuration `Extension` from the **Run and Debug** view. 44 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Int64 } from "thrift"; 6 | import { 7 | Serializable, 8 | SerializedBigInt, 9 | } from "../webviews/shared/protocol"; 10 | import { PropertyTreeItem } from "iar-vsc-common/thrift/bindings/shared_types"; 11 | 12 | /** 13 | * Converts an Int64 to a bigint. 14 | */ 15 | export function toBigInt(value: Int64): bigint { 16 | const big = BigInt(`0x${value.toOctetString()}`); 17 | // Int64s are signed, so if the most significant bit is set, we should 18 | // count that bit as negative instead. 19 | if (value.buffer[0] === undefined) { 20 | return big; 21 | } 22 | if ((value.buffer[0] & (1 << 7)) === 0) { 23 | return big; 24 | } 25 | return big - 2n * (1n << 63n); 26 | } 27 | 28 | /** 29 | * Converts a bigint to an Int64. 30 | */ 31 | export function toInt64(value: string | SerializedBigInt | bigint): Int64 { 32 | if (typeof value === "string") { 33 | value = BigInt(value); 34 | } else if (typeof value !== "bigint") { 35 | value = BigInt(value.value); 36 | } 37 | 38 | // The string-based Int64 constructor is broken for negative numbers (it 39 | // encodes them as signed 32-bit ints), so convert negative numbers to their 40 | // unsigned 64-bit equivalent first. 41 | if (value < 0n) { 42 | value += 2n * (1n << 63n); 43 | } 44 | 45 | return new Int64(value.toString(16)); 46 | } 47 | 48 | /** 49 | * Convert a serialized tree to a real property tree 50 | */ 51 | export function unpackTree( 52 | treeDescription: Serializable, 53 | ): PropertyTreeItem { 54 | const item = new PropertyTreeItem(); 55 | 56 | item.key = treeDescription.key; 57 | item.value = treeDescription.value; 58 | item.children = treeDescription.children.map( 59 | (element: Serializable) => { 60 | return unpackTree(element); 61 | }, 62 | ); 63 | 64 | return item; 65 | } -------------------------------------------------------------------------------- /src/listwindows/testListwindow.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import * as vscode from "vscode"; 6 | import { ViewMessage, RenderParameters } from "../../webviews/shared/protocol"; 7 | import { ListwindowViewProvider } from "./listwindowViewProvider"; 8 | 9 | /** 10 | * Provides a listwindow webview for running tests. It allows rendering your own 11 | * rendering parameters and then dumping the resulting HTML. 12 | */ 13 | export class TestListwindow implements vscode.Disposable { 14 | private static readonly VIEW_ID = "iar-test-listwindow"; 15 | 16 | private readonly view: ListwindowViewProvider; 17 | 18 | private onHTMLDump: ((html: string) => void) | undefined = undefined; 19 | 20 | /** 21 | * Creates a new view and registers it. 22 | */ 23 | constructor(extensionUri: vscode.Uri) { 24 | this.view = new ListwindowViewProvider( 25 | extensionUri, 26 | TestListwindow.VIEW_ID, 27 | ); 28 | this.view.setEnabled(true); 29 | this.view.onMessageReceived = (msg) => this.handleMessageFromView(msg); 30 | } 31 | 32 | dispose() { 33 | this.view.dispose(); 34 | } 35 | 36 | /** 37 | * Force focus to this view. 38 | */ 39 | async focus() { 40 | await this.view.focus(); 41 | } 42 | 43 | async render(params: RenderParameters) { 44 | await this.view.postMessageToView({ 45 | subject: "render", 46 | params, 47 | }); 48 | } 49 | 50 | dumpHTML(): Promise { 51 | return new Promise(res => { 52 | this.onHTMLDump = res; 53 | this.view.postMessageToView({ 54 | subject: "dumpHTML", 55 | }); 56 | }); 57 | } 58 | 59 | private handleMessageFromView(msg: ViewMessage) { 60 | switch (msg.subject) { 61 | case "HTMLDump": 62 | this.onHTMLDump?.(msg.html); 63 | break; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /webviews/shared/rendering/toolbar/toolbarConstants.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | export namespace Tags { 6 | export const kKeyIndexBase = "ITEM"; 7 | export const kKeyItemKind = "KIND"; 8 | export const kKeyItemStr = "TEXT"; 9 | export const kKeyItemStr2 = "TEXT2"; 10 | export const kKeyItemId = "ID"; 11 | export const kKeyItemStringList = "STRINGLIST"; 12 | export const kKeyItemBool = "BOOL"; 13 | export const kValTrue = "TRUE"; 14 | export const kValFalse = "FALSE"; 15 | export const kValSpacingLess = "LESS"; 16 | export const kValSpacingMore = "MORE"; 17 | export const kValProgressSmall = "SMALL"; 18 | export const kValProgressMedium = "MEDIUM"; 19 | export const kValProgressLarge = "LARGE"; 20 | } 21 | 22 | export enum ToolbarItemType { 23 | kKindUnknown = "UNKNOWN", 24 | kKindTextButton = "TEXTBUTTON", 25 | kKindIconButton = "ICONBUTTON", 26 | kKindTextCheck = "TEXTCHECK", 27 | kKindIconCheck = "ICONCHECK", 28 | kKindEditText = "EDITTEXT", 29 | kKindEditTextDyn = "EDITTEXTDYN", 30 | kKindDisplayText = "DISPLAYTEXT", 31 | kKindDisplayTextDyn = "DISPLAYTEXTDYN", 32 | kKindTextMenu = "TEXTMENU", 33 | kKindIconMenu = "ICONMENU", 34 | kKindSelectMenu = "SELECTMENU", 35 | kKindSelectMenuDyn = "SELECTMENUDYN", 36 | kKindProgressBar = "PROGRESSBAR", 37 | kKindProgressBarDyn = "PROGRESSBARDYN", 38 | kKindSpacing = "SPACING", 39 | kKindStackProgressBar = "STACKPROGRESSBAR", 40 | kKindStackProgressBarDyn = "STACKPROGRESSBARDYN", 41 | kKindCommandButton = "COMMANDBUTTON", 42 | kKindSeparator = "SEPARATOR", 43 | } 44 | 45 | 46 | export interface TreeData { 47 | key: string; 48 | value: string; 49 | children: TreeData[]; 50 | } 51 | 52 | export interface ToolbarItem { 53 | itemKey: string; 54 | id: string; 55 | type: ToolbarItemType; 56 | text: string; 57 | text2: string; 58 | bool: boolean; 59 | stringList: string[]; 60 | } 61 | -------------------------------------------------------------------------------- /src/dap/thrift/cspyServerLauncher.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import * as Path from "path"; 6 | import { logger } from "@vscode/debugadapter"; 7 | import { LogLevel } from "@vscode/debugadapter/lib/logger"; 8 | import { IarOsUtils } from "iar-vsc-common/osUtils"; 9 | import { DEBUGGER_SERVICE } from "iar-vsc-common/thrift/bindings/cspy_types"; 10 | import { ProcessMonitor, ThriftServiceRegistryProcess } from "iar-vsc-common/thrift/thriftServiceRegistryProcess"; 11 | import { ThriftServiceRegistry } from "iar-vsc-common/thrift/thriftServiceRegistry"; 12 | import * as Debugger from "iar-vsc-common/thrift/bindings/Debugger"; 13 | 14 | export namespace CSpyServerLauncher { 15 | 16 | /** 17 | * Starts CSpyServer using the given workbench, and returns a {@link ThriftServiceRegistryProcess} which can be used to 18 | * communicate with the CSpyServer process. 19 | */ 20 | export function fromWorkbench(workbenchPath: string, numCores: number): Promise { 21 | const cspyServerPath = Path.join(workbenchPath, "common/bin/CSpyServer2" + IarOsUtils.executableExtension()); 22 | const args = ["-standalone", "-sockets"]; 23 | if (numCores > 1) { 24 | args.push(`--multicore_nr_of_cores=${numCores}`); 25 | } 26 | const processMonitor: ProcessMonitor = { 27 | stdout: data => logger.verbose(data), 28 | stderr: data => logger.error(data), 29 | exit: code => logger.log(`CSpyServer exited with code ${code}`, code === 0 ? LogLevel.Verbose : LogLevel.Error), 30 | }; 31 | const stopCspyService = async function(registry: ThriftServiceRegistry) { 32 | const dbgr = await registry.findService(DEBUGGER_SERVICE, Debugger); 33 | await dbgr.service.exit(); 34 | dbgr.close(); 35 | }; 36 | return ThriftServiceRegistryProcess.launch(cspyServerPath, args, stopCspyService, DEBUGGER_SERVICE, processMonitor); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/TestProjects/GettingStarted/Fibonacci.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996 - 2016 IAR Systems AB. 3 | * 4 | * IAR Embedded Workbench tutorial 5 | * 6 | * Fibonacci.c 7 | * 8 | * Prints the Fibonacci sequence. 9 | * 10 | * See the file /doc/licenses/IARSourceLicense.txt for detailed 11 | * license information. 12 | * 13 | * $Revision: 113247 $ 14 | */ 15 | 16 | #include 17 | #include "Fibonacci.h" 18 | 19 | static void NextCounter(void); 20 | static void DoForegroundProcess(void); 21 | 22 | static int_fast8_t callCount = -1; 23 | 24 | 25 | /* Increase the 'callCount' variable by one. */ 26 | static void NextCounter(void) 27 | { 28 | callCount += 1; 29 | } 30 | 31 | /* Increase the 'callCount' variable. */ 32 | /* Get and print the associated Fibonacci number. */ 33 | static void DoForegroundProcess(void) 34 | { 35 | volatile uint32_t fib = 0; // volatile so it isn't placed in a register 36 | NextCounter(); 37 | fib = GetFib(callCount); 38 | PutFib(fib); 39 | } 40 | 41 | /* Main program. */ 42 | /* Prints the Fibonacci sequence. */ 43 | int32_t main(void) 44 | { 45 | callCount = 0; 46 | 47 | InitFib(); 48 | 49 | while (callCount < MAX_FIB) 50 | { 51 | DoForegroundProcess(); 52 | } 53 | long test = (long) str; // prevent str from being optimized away 54 | nested_struct.un.a = 42; // prevent nested_struct from being optimized away 55 | nested_struct2.un.a = 0; // prevent nested_struct2 from being optimized away 56 | references_self.a = 42; // prevent references_self from being optimized away 57 | anon_siblings.a = 42; // prevent anon_siblings from being optimized away 58 | pointer = (int*)0x1337; 59 | scanf("%d", &scan_to_me); 60 | scanf("%11s", &buf); 61 | return 0; 62 | } 63 | 64 | // multicore stuff used by the zynq 7020 cstartup file 65 | #ifdef ZYNQ7020 66 | #pragma section = ".semaphore" 67 | volatile int global_semaphore = 0x1000; 68 | #pragma swi_number=0x42 69 | __swi __arm int getcoreid(); 70 | #include 71 | __arm void getcoreid_imp(unsigned number, unsigned *reg) 72 | { 73 | 74 | { 75 | reg[0] = __MRC( 15, 0, 0, 0, 5) & 0x3; 76 | } 77 | } 78 | void INT_Handler() 79 | { 80 | } 81 | #endif 82 | -------------------------------------------------------------------------------- /src/dap/timelineFrontendHandler.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import * as Q from "q"; 6 | import ttypes = require("iar-vsc-common/thrift/bindings/timeline_types"); 7 | import DbuTimelineDataAvailableNotification = ttypes.DbuTimelineDataAvailableNotification 8 | import DbuTimelineChannelAvailableNotification = ttypes.DbuTimelineChannelAvailableNotification 9 | import DbuTimelineChannelRemovedNotification = ttypes.DbuTimelineChannelRemovedNotification 10 | import DbuTimelineCpuClockChangedNotification = ttypes.DbuTimelineCpuClockChangedNotification 11 | import DbuTimelineEnablementChangedNotification = ttypes.DbuTimelineEnablementChangedNotification 12 | import * as TimelineFrontend from "iar-vsc-common/thrift/bindings/TimelineFrontend"; 13 | import { ThriftServiceHandler } from "iar-vsc-common/thrift/thriftUtils"; 14 | 15 | /** 16 | * A mock implementation of the timeline window frontend service, which simply discards any messages received. 17 | * This is needed because some versions of cspyserver become extremely slow to set up sessions when no timeline 18 | * frontend is available (see VSC-309). 19 | */ 20 | export class TimelineFrontendHandler implements ThriftServiceHandler { 21 | dataAvailable(_note: DbuTimelineDataAvailableNotification, _partnerNamespace: string): Q.Promise { 22 | return Q.resolve(); 23 | } 24 | 25 | channelAvailable(_note: DbuTimelineChannelAvailableNotification, _partnerNamespace: string): Q.Promise { 26 | return Q.resolve(); 27 | } 28 | 29 | channelRemoved(_note: DbuTimelineChannelRemovedNotification, _partnerNamespace: string): Q.Promise { 30 | return Q.resolve(); 31 | } 32 | 33 | cpuClockChanged(_note: DbuTimelineCpuClockChangedNotification, _partnerNamespace: string): Q.Promise { 34 | return Q.resolve(); 35 | } 36 | 37 | enablementChanged(_note: DbuTimelineEnablementChangedNotification, _partnerNamespace: string): Q.Promise { 38 | return Q.resolve(); 39 | } 40 | } -------------------------------------------------------------------------------- /webviews/shared/thrift/memory_types.js: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | if (typeof Int64 === 'undefined' && typeof require === 'function') { 7 | var Int64 = require('node-int64'); 8 | } 9 | 10 | 11 | var ttypes = module.exports = {}; 12 | var CSpyMemoryBlock = module.exports.CSpyMemoryBlock = function(args) { 13 | this.data = null; 14 | this.status = null; 15 | if (args) { 16 | if (args.data !== undefined && args.data !== null) { 17 | this.data = args.data; 18 | } 19 | if (args.status !== undefined && args.status !== null) { 20 | this.status = args.status; 21 | } 22 | } 23 | }; 24 | CSpyMemoryBlock.prototype = {}; 25 | CSpyMemoryBlock.prototype.read = function(input) { 26 | input.readStructBegin(); 27 | while (true) { 28 | var ret = input.readFieldBegin(); 29 | var ftype = ret.ftype; 30 | var fid = ret.fid; 31 | if (ftype == Thrift.Type.STOP) { 32 | break; 33 | } 34 | switch (fid) { 35 | case 1: 36 | if (ftype == Thrift.Type.STRING) { 37 | this.data = input.readBinary().value; 38 | } else { 39 | input.skip(ftype); 40 | } 41 | break; 42 | case 2: 43 | if (ftype == Thrift.Type.STRING) { 44 | this.status = input.readBinary().value; 45 | } else { 46 | input.skip(ftype); 47 | } 48 | break; 49 | default: 50 | input.skip(ftype); 51 | } 52 | input.readFieldEnd(); 53 | } 54 | input.readStructEnd(); 55 | return; 56 | }; 57 | 58 | CSpyMemoryBlock.prototype.write = function(output) { 59 | output.writeStructBegin('CSpyMemoryBlock'); 60 | if (this.data !== null && this.data !== undefined) { 61 | output.writeFieldBegin('data', Thrift.Type.STRING, 1); 62 | output.writeBinary(this.data); 63 | output.writeFieldEnd(); 64 | } 65 | if (this.status !== null && this.status !== undefined) { 66 | output.writeFieldBegin('status', Thrift.Type.STRING, 2); 67 | output.writeBinary(this.status); 68 | output.writeFieldEnd(); 69 | } 70 | output.writeFieldStop(); 71 | output.writeStructEnd(); 72 | return; 73 | }; 74 | 75 | -------------------------------------------------------------------------------- /src/listwindows/clients/registersLegacyClient.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import { ThriftServiceRegistry } from "iar-vsc-common/thrift/thriftServiceRegistry"; 6 | import { 7 | LegacyListwindowClient, 8 | LegacyToolbarItem, 9 | } from "./listwindowBackendClient"; 10 | import { ThriftClient } from "iar-vsc-common/thrift/thriftClient"; 11 | import { ToolbarItemType } from "../../../webviews/shared/rendering/toolbar/toolbarConstants"; 12 | import { PropertyTreeItem } from "iar-vsc-common/thrift/bindings/shared_types"; 13 | import * as Q from "q"; 14 | import * as ListWindowBackend from "iar-vsc-common/thrift/bindings/ListWindowBackend"; 15 | import * as Watch from "iar-vsc-common/thrift/bindings/Watch"; 16 | 17 | /** 18 | * Legacy client for registers. 19 | */ 20 | export class RegisterClient extends LegacyListwindowClient { 21 | public connectToBackend( 22 | serviceName: string, 23 | serviceRegistry: ThriftServiceRegistry, 24 | ): Promise> { 25 | return this.doConnect(serviceName, serviceRegistry, Watch.Client); 26 | } 27 | 28 | private readonly def: LegacyToolbarItem[] = [ 29 | { 30 | id: "edit", 31 | type: ToolbarItemType.kKindEditText, 32 | text: "Find register:", 33 | bool: true, 34 | itemKey: "", 35 | stringList: [], 36 | text2: "", 37 | tooltip: "", 38 | callback: tree => { 39 | return this.onFind(tree); 40 | }, 41 | }, 42 | ]; 43 | 44 | getDescription(): Q.Promise { 45 | return Q.resolve(this.def); 46 | } 47 | 48 | public onFind(tree: PropertyTreeItem): Q.Promise { 49 | const register = tree.children[1]?.value as string; 50 | return this.withClient(c => { 51 | return c.service. 52 | add(register.replace(" ", "")). 53 | then(() => Q.resolve(true)); 54 | }, false); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /webviews/shared/thrift/DebugEventListener.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { cspy } from "./cspy_types"; 10 | 11 | 12 | /** 13 | * Interface for receiving information about events in the debugger. 14 | */ 15 | export declare class Client { 16 | input: Thrift.TJSONProtocol; 17 | output: Thrift.TJSONProtocol; 18 | seqid: number; 19 | 20 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 21 | 22 | /** 23 | * Called whenever a debug event happens. See DkNotifySubscriber#Notify. 24 | */ 25 | postDebugEvent(event: DebugEvent): Q.Promise; 26 | 27 | /** 28 | * Called whenever a debug event happens. See DkNotifySubscriber#Notify. 29 | */ 30 | postDebugEvent(event: DebugEvent, callback?: (data: void)=>void): void; 31 | 32 | /** 33 | * This one should not be oneway, since we need to make sure that the 34 | * client has actually recevied the message before proceeding. This will 35 | * otherwise prevent e.g. fatal error messages from being seen. 36 | */ 37 | postLogEvent(event: LogEvent): Q.Promise; 38 | 39 | /** 40 | * This one should not be oneway, since we need to make sure that the 41 | * client has actually recevied the message before proceeding. This will 42 | * otherwise prevent e.g. fatal error messages from being seen. 43 | */ 44 | postLogEvent(event: LogEvent, callback?: (data: void)=>void): void; 45 | 46 | /** 47 | * Triggered on kDkInspectionContextChanged. 48 | */ 49 | postInspectionContextChangedEvent(event: InspectionContextChangedEvent): Q.Promise; 50 | 51 | /** 52 | * Triggered on kDkInspectionContextChanged. 53 | */ 54 | postInspectionContextChangedEvent(event: InspectionContextChangedEvent, callback?: (data: void)=>void): void; 55 | 56 | /** 57 | * Triggered on kDkBaseContextChanged. 58 | */ 59 | postBaseContextChangedEvent(event: BaseContextChangedEvent): Q.Promise; 60 | 61 | /** 62 | * Triggered on kDkBaseContextChanged. 63 | */ 64 | postBaseContextChangedEvent(event: BaseContextChangedEvent, callback?: (data: void)=>void): void; 65 | } 66 | -------------------------------------------------------------------------------- /tests/runTests.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import * as path from "path"; 5 | import { runTestsIn} from "iar-vsc-common/testutils/testRunner"; 6 | import { TestConfiguration } from "./suites/testConfiguration"; 7 | 8 | async function main() { 9 | const envs = getEnvs(); 10 | 11 | const testConfigurationName = envs["test-configuration"]; 12 | if (testConfigurationName) { 13 | envs[TestConfiguration.ENV_KEY_NAME] = testConfigurationName; 14 | if (TestConfiguration.TEST_CONFIGURATIONS[testConfigurationName]) { 15 | TestConfiguration.setParameters(TestConfiguration.TEST_CONFIGURATIONS[testConfigurationName]!); 16 | } 17 | } 18 | const label = envs["label"]; 19 | const suite = envs["suite"]; 20 | if (suite === "configuration") { 21 | await runTestsIn(path.resolve(__dirname), "../../", "./suites/config/index", envs, 22 | "../../tests/TestProjects/ConfigTests", label); 23 | } else if (suite === "debugger") { 24 | await runTestsIn(path.resolve(__dirname), "../../", "./suites/dbg/index", envs, 25 | undefined, label); 26 | } else if (suite === "listwindow") { 27 | await runTestsIn(path.resolve(__dirname), "../../", "./suites/listwindow/index", envs, 28 | undefined, label); 29 | } 30 | 31 | } 32 | 33 | /** 34 | * Construct a key:string based on the supplied options from the commandline. 35 | * @returns 36 | */ 37 | function getEnvs(): Record { 38 | const envs: Record = {}; 39 | for (const opt of process.argv.slice(2)) { 40 | if (opt.startsWith("--")) { 41 | const separatorIdx = opt.indexOf("="); 42 | if (separatorIdx === -1) { 43 | const optName = opt.substring(2); 44 | envs[optName] = "true"; 45 | } else { 46 | const optName = opt.substring(2, separatorIdx); 47 | const val = opt.substring(separatorIdx + 1); 48 | envs[optName] = val; 49 | } 50 | } 51 | } 52 | return envs; 53 | } 54 | 55 | main(); 56 | -------------------------------------------------------------------------------- /webviews/shared/thrift/CSpyServiceRegistry.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { ServiceRegistry } from "./ServiceRegistry_types"; 10 | 11 | 12 | export declare class Client { 13 | input: Thrift.TJSONProtocol; 14 | output: Thrift.TJSONProtocol; 15 | seqid: number; 16 | 17 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 18 | 19 | waitForService(serviceName: string, timeout: number): Q.Promise; 20 | 21 | waitForService(serviceName: string, timeout: number, callback?: (data: ServiceLocation)=>void): void; 22 | 23 | registerService(serviceName: string, location: ServiceLocation): Q.Promise; 24 | 25 | registerService(serviceName: string, location: ServiceLocation, callback?: (data: void)=>void): void; 26 | 27 | deregisterService(serviceName: string): Q.Promise; 28 | 29 | deregisterService(serviceName: string, callback?: (data: void)=>void): void; 30 | 31 | addServiceListener(filterRegex: string, serviceListenerId: string): Q.Promise; 32 | 33 | addServiceListener(filterRegex: string, serviceListenerId: string, callback?: (data: void)=>void): void; 34 | 35 | removeServiceListener(serviceListenerId: string): Q.Promise; 36 | 37 | removeServiceListener(serviceListenerId: string, callback?: (data: void)=>void): void; 38 | 39 | getServices(): Q.Promise<{ [k: string]: ServiceLocation; }>; 40 | 41 | getServices(callback?: (data: { [k: string]: ServiceLocation; })=>void): void; 42 | 43 | isAlive(): Q.Promise; 44 | 45 | isAlive(callback?: (data: void)=>void): void; 46 | 47 | getSupportedTransports(): Q.Promise; 48 | 49 | getSupportedTransports(callback?: (data: Transport[])=>void): void; 50 | 51 | createNamespace(name: string): Q.Promise; 52 | 53 | createNamespace(name: string, callback?: (data: ServiceLocation)=>void): void; 54 | 55 | removeNamespace(name: string): Q.Promise; 56 | 57 | removeNamespace(name: string, callback?: (data: void)=>void): void; 58 | 59 | getNamespaces(): Q.Promise; 60 | 61 | getNamespaces(callback?: (data: string[])=>void): void; 62 | } 63 | -------------------------------------------------------------------------------- /webviews/shared/thrift/themes_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import Int64 = require('node-int64'); 7 | 8 | 9 | export declare enum ThriftDisplayElement { 10 | kWindowBg = 0, 11 | kText = 1, 12 | kDistinctText = 2, 13 | kSelectedText = 3, 14 | kSelectedBackground = 4, 15 | kInactiveSelectionText = 5, 16 | kInactiveSelectionBackground = 6, 17 | kValueChangedText = 7, 18 | kDisabledText = 8, 19 | kCurrentPc = 9, 20 | kCurrentPcStatementOnly = 10, 21 | kAlternativePc = 11, 22 | kBreakpoint = 12, 23 | kSignalGreen = 13, 24 | kSignalYellow = 14, 25 | kSignalRed = 15, 26 | kSideMargin = 16, 27 | kHighlightedBackground = 17, 28 | kHighlightedText = 18, 29 | kBtnFace = 19, 30 | kBtnShadow = 20, 31 | k3DDkShadow = 21, 32 | kTabBg = 22, 33 | kBtnText = 23, 34 | kBtnHighlight = 24, 35 | kGrayText = 25, 36 | kCaptionText = 26, 37 | kActiveCaptionBackground = 27, 38 | kInactiveCaptionBackground = 28, 39 | kActiveCaptionBackgroundGradient = 29, 40 | kInactiveCaptionBackgroundGradient = 30, 41 | kInactiveCaptionText = 31, 42 | kHotLinkNormalText = 32, 43 | kBarFace = 33, 44 | kBarShadow = 34, 45 | kBarHighlight = 35, 46 | kToolbarGradientDark = 36, 47 | kToolbarGradientLight = 37, 48 | kHighlightGradientLight = 38, 49 | kHighlightGradientDark = 39, 50 | kPressedToolbarBtnBg = 40, 51 | kTooltipText = 41, 52 | kTooltipBg = 42, 53 | kScrollbarBg = 43, 54 | kScrollbarFg = 44, 55 | kScrollbarHighlight = 45, 56 | kScrollbarDrag = 46, 57 | kMdiClientBg = 47, 58 | kWatchFamilyBg = 48, 59 | kStackFamilyBg = 49, 60 | kDisasmFamilyBg = 50, 61 | kMemoryFamilyBg = 51, 62 | kBreakpointFamilyBg = 52, 63 | kTraceFamilyBg = 53, 64 | kProfilerFamilyBg = 54, 65 | kInterruptFamilyBg = 55, 66 | kStateFamilyBg = 56, 67 | kDataLogFamilyBg = 57, 68 | kPowerLogFamilyBg = 58, 69 | kEventLogFamilyBg = 59, 70 | kRegisterFamilyBg = 60, 71 | kGrid = 61, 72 | kNumDisplayElements = 62, 73 | } 74 | 75 | export declare class ColorSchema { 76 | R: number; 77 | G: number; 78 | B: number; 79 | 80 | constructor(args?: { R: number; G: number; B: number; }); 81 | read(input: Object): void; 82 | write(input: Object): void; 83 | } 84 | -------------------------------------------------------------------------------- /webviews/shared/utils.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import { Serializable } from "./protocol"; 6 | import Int64 from "node-int64"; 7 | 8 | /** 9 | * A helper decorator which registers a class as a custom HTML element 10 | * @param name The HTML element name to register the class as 11 | */ 12 | export function customElement( 13 | name: string, 14 | options: ElementDefinitionOptions | undefined = undefined, 15 | ) { 16 | return (constructor: CustomElementConstructor) => { 17 | customElements.define(name, constructor, options); 18 | }; 19 | } 20 | 21 | /** 22 | * Converts an int64 we've been sent from the extension into a bigint (which is 23 | * more practical to use for comparisons and such). 24 | */ 25 | export function toBigInt(int64: Serializable): bigint { 26 | // This is pretty hacky, type safety be gone! 27 | if ("data" in int64.buffer && Array.isArray(int64.buffer.data)) { 28 | let str = "0x"; 29 | for (const num of int64.buffer.data) { 30 | let byteStr = num.toString(16); 31 | if (byteStr.length === 1) { 32 | byteStr = "0" + byteStr; 33 | } 34 | str += byteStr; 35 | } 36 | const big = BigInt(str); 37 | // Int64s are signed, so if the most significant bit is set, we should 38 | // count that bit as negative instead. 39 | if (int64.buffer.data[0] === undefined) { 40 | return big; 41 | } 42 | if ((int64.buffer.data[0] & (1 << 7)) === 0) { 43 | return big; 44 | } 45 | return big - BigInt(2) * (BigInt(1) << BigInt(63)); 46 | } 47 | throw new Error("Got an invalid Int64"); 48 | } 49 | 50 | /** 51 | * Converts an int64 we've been sent from the extension into a Number. Throws if 52 | * the number is too large to be represented as a Number. 53 | */ 54 | export function toNumber(int64: Serializable): number { 55 | const big = toBigInt(int64); 56 | if (big > Number.MAX_SAFE_INTEGER || big < Number.MIN_SAFE_INTEGER) { 57 | throw new Error(`The number ${big} is too large to be represented as a Number`); 58 | } 59 | return Number(big); 60 | } -------------------------------------------------------------------------------- /webviews/listwindow/rendering/cell/cellBorders.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import { css } from "@emotion/css"; 6 | import { customElement } from "../../../shared/utils"; 7 | 8 | export enum CellBorderVariables { 9 | Style = "--cell-border-style", 10 | // If unset, these default to 'Style' 11 | StyleTop = "--cell-border-style-top", 12 | StyleRight = "--cell-border-style-right", 13 | StyleBottom = "--cell-border-style-bottom", 14 | StyleLeft = "--cell-border-style-left", 15 | 16 | ColorTop = "--cell-border-color-top", 17 | ColorRight = "--cell-border-color-right", 18 | ColorBottom = "--cell-border-color-bottom", 19 | ColorLeft = "--cell-border-color-left", 20 | } 21 | 22 | /** 23 | * Places borders on the inside of its parent element without affecting the size 24 | * of the element. Like CSS outline with a negative outline-offset, but the and 25 | * style color of each side can be controlled individually by setting the 26 | * variables above. 27 | */ 28 | @customElement("listwindow-cell-borders") 29 | export class CellBordersElement extends HTMLElement { 30 | connectedCallback() { 31 | this.classList.add(Styles.self); 32 | } 33 | } 34 | 35 | namespace Styles { 36 | export const self = css({ 37 | pointerEvents: "none", 38 | position: "absolute", 39 | inset: 0, 40 | borderWidth: "1px", 41 | borderTopColor: `var(${CellBorderVariables.ColorTop}, rgba(0, 0, 0, 0))`, 42 | borderRightColor: `var(${CellBorderVariables.ColorRight}, rgba(0, 0, 0, 0))`, 43 | borderBottomColor: `var(${CellBorderVariables.ColorBottom}, rgba(0, 0, 0, 0))`, 44 | borderLeftColor: `var(${CellBorderVariables.ColorLeft}, rgba(0, 0, 0, 0))`, 45 | borderTopStyle: `var(${CellBorderVariables.StyleTop}, var(${CellBorderVariables.Style}, none))`, 46 | borderRightStyle: `var(${CellBorderVariables.StyleRight}, var(${CellBorderVariables.Style}, none))`, 47 | borderBottomStyle: `var(${CellBorderVariables.StyleBottom}, var(${CellBorderVariables.Style}, none))`, 48 | borderLeftStyle: `var(${CellBorderVariables.StyleLeft}, var(${CellBorderVariables.Style}, none))`, 49 | }); 50 | } -------------------------------------------------------------------------------- /webviews/shared/thrift/OptionsService.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { OptionsService } from "./OptionsService_types"; 10 | 11 | 12 | export declare class Client { 13 | input: Thrift.TJSONProtocol; 14 | output: Thrift.TJSONProtocol; 15 | seqid: number; 16 | 17 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 18 | 19 | CreateSession(request: CreateSessionRequest): Q.Promise; 20 | 21 | CreateSession(request: CreateSessionRequest, callback?: (data: CreateSessionResponse)=>void): void; 22 | 23 | CreateSessionWithData(request: CreateSessionWithDataRequest): Q.Promise; 24 | 25 | CreateSessionWithData(request: CreateSessionWithDataRequest, callback?: (data: CreateSessionResponse)=>void): void; 26 | 27 | UpdateOptionValue(request: UpdateOptionValueRequest): Q.Promise; 28 | 29 | UpdateOptionValue(request: UpdateOptionValueRequest, callback?: (data: UpdateOptionValueResponse)=>void): void; 30 | 31 | DestroySession(destroySessionRequest: DestroySessionRequest): Q.Promise; 32 | 33 | DestroySession(destroySessionRequest: DestroySessionRequest, callback?: (data: DestroySessionResponse)=>void): void; 34 | 35 | GetCategoryTree(getCategoryTreeRequest: GetCategoryTreeRequest): Q.Promise; 36 | 37 | GetCategoryTree(getCategoryTreeRequest: GetCategoryTreeRequest, callback?: (data: GetCategoryTreeResponse)=>void): void; 38 | 39 | GetOptionTree(getOptionTreeRequest: GetOptionTreeRequest): Q.Promise; 40 | 41 | GetOptionTree(getOptionTreeRequest: GetOptionTreeRequest, callback?: (data: GetOptionTreeResponse)=>void): void; 42 | 43 | VerifyOptionState(verifyOptionStateRequest: VerifyOptionStateRequest): Q.Promise; 44 | 45 | VerifyOptionState(verifyOptionStateRequest: VerifyOptionStateRequest, callback?: (data: VerifyOptionStateResponse)=>void): void; 46 | 47 | CommitOptionState(commitOptionStateRequest: CommitOptionStateRequest): Q.Promise; 48 | 49 | CommitOptionState(commitOptionStateRequest: CommitOptionStateRequest, callback?: (data: CommitOptionStateResponse)=>void): void; 50 | } 51 | -------------------------------------------------------------------------------- /src/dap/multicoreProtocolExtension.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import { CommandRegistry } from "./commandRegistry"; 6 | import { CustomRequest } from "./customRequest"; 7 | 8 | interface ExecutionRequestArguments { 9 | singleThread?: boolean; 10 | } 11 | interface ExecutionRequestResponse { 12 | body?: { 13 | allThreadsContinued?: boolean; 14 | }; 15 | } 16 | 17 | /** 18 | * Provides a custom DAP request to enable or disable "lockstep mode" for a multicore session, i.e. whether the cores 19 | * all start/step/stop together when the user performs such an actions. This is already supported by DAP on a 20 | * per-request basis by setting the singleThread flag to true or false in the request (indicating whether the request 21 | * affects only a single thread or all of them). However, VS Code doesn't support this flag yet, so this is a 22 | * workaround. It only controls the behaviour of requsts that are missing the singleThread flag; any requests that 23 | * explicitly specify it still behave according to the specification. 24 | * 25 | * To use this class, any execution requests should pass their arguments and response through 26 | * {@link MulticoreProtocolExtension.massageExecutionRequest} before handling them, to let this class modify the request 27 | * as needed. 28 | */ 29 | export class MulticoreProtocolExtension { 30 | private multicoreLockstepModeEnabled = false; 31 | 32 | constructor(lockstepModeEnabled: boolean, requestRegistry: CommandRegistry) { 33 | this.multicoreLockstepModeEnabled = lockstepModeEnabled; 34 | 35 | requestRegistry.registerCommandWithTypeCheck(CustomRequest.Names.SET_LOCKSTEP_MODE_ENABLED, CustomRequest.isSetLockstepModeArgs, 36 | lockstepEnabled => this.multicoreLockstepModeEnabled = lockstepEnabled.enabled); 37 | } 38 | 39 | massageExecutionRequest(args: ExecutionRequestArguments, response: ExecutionRequestResponse) { 40 | if (args.singleThread === undefined) { 41 | args.singleThread = !this.multicoreLockstepModeEnabled; 42 | } 43 | if (response.body === undefined) response.body = {}; 44 | response.body.allThreadsContinued = !args.singleThread; 45 | } 46 | } -------------------------------------------------------------------------------- /webviews/shared/events.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import { 6 | CellEditRequestedEvent, 7 | CellHoveredEvent, 8 | CellRightClickedEvent, 9 | } from "../listwindow/rendering/cell/cell"; 10 | import { ContextMenuItemClickEvent } from "../listwindow/rendering/contextMenuService"; 11 | import { ColumnsResizedEvent } from "../listwindow/rendering/header/header"; 12 | import { 13 | ResizeHandleDragBeginEvent, 14 | ResizeHandleDragEndEvent, 15 | ResizeHandleMovedEvent, 16 | } from "../listwindow/rendering/header/resizeHandle"; 17 | import { 18 | ToolbarItemEvent, 19 | ToolbarItemHoveredEvent, 20 | } from "./rendering/toolbar/toolbarItem"; 21 | 22 | /** 23 | * Defines custom DOM events ({@link CustomEvent})s available in the view, each 24 | * with a name and the type of the event's `detail` field. 25 | */ 26 | interface CustomEventTypeMap { 27 | "resize-handle-drag-begin": ResizeHandleDragBeginEvent.Detail; 28 | "resize-handle-drag-end": ResizeHandleDragEndEvent.Detail; 29 | "resize-handle-moved": ResizeHandleMovedEvent.Detail; 30 | "columns-resized": ColumnsResizedEvent.Detail; 31 | "cell-hovered": CellHoveredEvent.Detail; 32 | "cell-edit-requested": CellEditRequestedEvent.Detail; 33 | "cell-edit-submitted": string, 34 | "cell-right-clicked": CellRightClickedEvent.Detail; 35 | "context-menu-item-clicked": ContextMenuItemClickEvent.Detail; 36 | "toolbar-item-interaction": ToolbarItemEvent.Detail; 37 | "toolbar-item-hovered": ToolbarItemHoveredEvent.Detail; 38 | } 39 | 40 | type CustomEventMap = { 41 | [EventName in keyof CustomEventTypeMap]: CustomEvent; 42 | }; 43 | 44 | declare global { 45 | // Extending GlobalEventHandlersEventMap makes the event types available 46 | // in HTMLElement.addListener calls. 47 | interface GlobalEventHandlersEventMap extends CustomEventMap {} 48 | } 49 | 50 | /** 51 | * Typesafe helper for creating a custom event of one of the types declared 52 | * above. 53 | */ 54 | export const createCustomEvent = ( 55 | type: T, 56 | eventInitDict: CustomEventInit, 57 | ) => new CustomEvent(type, eventInitDict); 58 | -------------------------------------------------------------------------------- /webviews/shared/thrift/LibSupportService2.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | 7 | import Int64 = require('node-int64'); 8 | 9 | import { libsupport } from "./libsupport_types"; 10 | 11 | 12 | /** 13 | * This service redirects the I/O streams of the program being 14 | * debugged by C-SPY towards the environment hosting C-SPY itself. 15 | */ 16 | export declare class Client { 17 | input: Thrift.TJSONProtocol; 18 | output: Thrift.TJSONProtocol; 19 | seqid: number; 20 | 21 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 22 | 23 | /** 24 | * Request input from the terminal I/O console. 25 | */ 26 | requestInputBinary(len: number): Q.Promise; 27 | 28 | /** 29 | * Request input from the terminal I/O console. 30 | */ 31 | requestInputBinary(len: number, callback?: (data: string)=>void): void; 32 | 33 | /** 34 | * @deprecated, use requestInputBinary instead 35 | */ 36 | requestInput(len: number): Q.Promise; 37 | 38 | /** 39 | * @deprecated, use requestInputBinary instead 40 | */ 41 | requestInput(len: number, callback?: (data: string)=>void): void; 42 | 43 | /** 44 | * Handle output from the target program. 45 | */ 46 | printOutputBinary(data: string): Q.Promise; 47 | 48 | /** 49 | * Handle output from the target program. 50 | */ 51 | printOutputBinary(data: string, callback?: (data: void)=>void): void; 52 | 53 | /** 54 | * @deprecated, use printOutputBinary instead 55 | */ 56 | printOutput(data: string): Q.Promise; 57 | 58 | /** 59 | * @deprecated, use printOutputBinary instead 60 | */ 61 | printOutput(data: string, callback?: (data: void)=>void): void; 62 | 63 | /** 64 | * The target program has exited. 65 | */ 66 | exit(code: number): Q.Promise; 67 | 68 | /** 69 | * The target program has exited. 70 | */ 71 | exit(code: number, callback?: (data: void)=>void): void; 72 | 73 | /** 74 | * The target program has aborted (i.e. called abort()). 75 | */ 76 | reportAssert(file: string, line: string, message: string): Q.Promise; 77 | 78 | /** 79 | * The target program has aborted (i.e. called abort()). 80 | */ 81 | reportAssert(file: string, line: string, message: string, callback?: (data: void)=>void): void; 82 | } 83 | -------------------------------------------------------------------------------- /webviews/shared/thrift/CMSISAgent2.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { cmsisagent } from "./cmsisagent_types"; 11 | 12 | 13 | export declare class Client extends HeartbeatService.Client { 14 | input: Thrift.TJSONProtocol; 15 | output: Thrift.TJSONProtocol; 16 | seqid: number; 17 | 18 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 19 | 20 | loadProject(ewpfile: string, rteConfigFile: string): Q.Promise; 21 | 22 | loadProject(ewpfile: string, rteConfigFile: string, callback?: (data: void)=>void): void; 23 | 24 | createNewProject(ewpfile: string, outputType: OutputType): Q.Promise; 25 | 26 | createNewProject(ewpfile: string, outputType: OutputType, callback?: (data: void)=>void): void; 27 | 28 | shutdown(): Q.Promise; 29 | 30 | shutdown(callback?: (data: void)=>void): void; 31 | 32 | activate(project: string): Q.Promise; 33 | 34 | activate(project: string, callback?: (data: void)=>void): void; 35 | 36 | getComponentInfo(rte: string): Q.Promise; 37 | 38 | getComponentInfo(rte: string, callback?: (data: ComponentInfo[])=>void): void; 39 | 40 | getValidationStatus(rte: string): Q.Promise; 41 | 42 | getValidationStatus(rte: string, callback?: (data: ValidationStatus[])=>void): void; 43 | 44 | getApis(rte: string): Q.Promise; 45 | 46 | getApis(rte: string, callback?: (data: Api[])=>void): void; 47 | 48 | getDeviceInfo(rte: string): Q.Promise; 49 | 50 | getDeviceInfo(rte: string, callback?: (data: DeviceInfo)=>void): void; 51 | 52 | getPathToPack(packId: string): Q.Promise; 53 | 54 | getPathToPack(packId: string, callback?: (data: string)=>void): void; 55 | 56 | getPackIdFromPath(fileInPack: string): Q.Promise; 57 | 58 | getPackIdFromPath(fileInPack: string, callback?: (data: FileInPack)=>void): void; 59 | 60 | getRteFiles(projectName: string): Q.Promise; 61 | 62 | getRteFiles(projectName: string, callback?: (data: RteFile[])=>void): void; 63 | 64 | openDeviceDialog(projectName: string): Q.Promise; 65 | 66 | openDeviceDialog(projectName: string, callback?: (data: void)=>void): void; 67 | } 68 | -------------------------------------------------------------------------------- /webviews/shared/thrift/frontend_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import Int64 = require('node-int64'); 7 | 8 | 9 | /** 10 | * Which icon to display in the message box 11 | */ 12 | export declare enum MsgIcon { 13 | kMsgIconInfo = 0, 14 | kMsgIconQuestion = 1, 15 | kMsgIconExclaim = 2, 16 | kMsgIconStop = 3, 17 | } 18 | 19 | /** 20 | * What set of buttons to use in the message box 21 | */ 22 | export declare enum MsgKind { 23 | kMsgOk = 0, 24 | kMsgOkCancel = 1, 25 | kMsgYesNo = 2, 26 | kMsgYesNoCancel = 3, 27 | } 28 | 29 | /** 30 | * Which button was used to dismiss the message box 31 | */ 32 | export declare enum MsgResult { 33 | kMsgResOk = 0, 34 | kMsgResCancel = 1, 35 | kMsgResYes = 2, 36 | kMsgResNo = 3, 37 | } 38 | 39 | /** 40 | * The type of dialog to open 41 | */ 42 | export declare enum FileDialogType { 43 | kOpen = 0, 44 | kSaveAs = 1, 45 | } 46 | 47 | /** 48 | * The set of allowed return types. kExistingFiles 49 | * allows returning multiple file 50 | */ 51 | export declare enum FileDialogReturnType { 52 | kAny = 0, 53 | kExistingFile = 1, 54 | kDirectory = 2, 55 | kExistingFiles = 3, 56 | } 57 | 58 | /** 59 | * The set of allowed options which the backend is expecting. 60 | */ 61 | export declare enum FileDialogOptions { 62 | kNoOverwritePrompt = 0, 63 | kFileMustExist = 1, 64 | kPathMustExist = 2, 65 | kAllowReturningReadOnlyFile = 3, 66 | } 67 | 68 | export declare enum GenericDialogReturnType { 69 | kOk = 0, 70 | kCancel = 1, 71 | kUnknown = 2, 72 | } 73 | 74 | /** 75 | * Small helper struct for filters. The display name is 76 | * the readable name of the filter and the files allowed 77 | * are listed in the filtering vector. 78 | */ 79 | export declare class FileDialogFilter { 80 | displayName: string; 81 | filtering: string[]; 82 | 83 | constructor(args?: { displayName: string; filtering: string[]; }); 84 | read(input: Object): void; 85 | write(input: Object): void; 86 | } 87 | 88 | export declare class GenericDialogResults { 89 | type: GenericDialogReturnType; 90 | items: PropertyTreeItem; 91 | 92 | constructor(args?: { type: GenericDialogReturnType; items: PropertyTreeItem; }); 93 | read(input: Object): void; 94 | write(input: Object): void; 95 | } 96 | 97 | export declare var FRONTEND_SERVICE: string; 98 | -------------------------------------------------------------------------------- /webviews/shared/thrift/timeline_types.d.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.14.0) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | import Int64 = require('node-int64'); 7 | 8 | 9 | /** 10 | * Sent to notify of new data being available in all the channels whose id matches the 'channelId' regexp 11 | */ 12 | export declare class DbuTimelineDataAvailableNotification { 13 | channelId: string; 14 | startCycles: Int64; 15 | endCycles: Int64; 16 | dummy: boolean; 17 | 18 | constructor(args?: { channelId: string; startCycles: Int64; endCycles: Int64; dummy: boolean; }); 19 | read(input: Object): void; 20 | write(input: Object): void; 21 | } 22 | 23 | /** 24 | * Sent to notify of a new data channel being available 25 | */ 26 | export declare class DbuTimelineChannelAvailableNotification { 27 | id: string; 28 | formatDescriptor: string; 29 | 30 | constructor(args?: { id: string; formatDescriptor: string; }); 31 | read(input: Object): void; 32 | write(input: Object): void; 33 | } 34 | 35 | /** 36 | * Sent to notify of a data channel having been removed 37 | */ 38 | export declare class DbuTimelineChannelRemovedNotification { 39 | id: string; 40 | 41 | constructor(args?: { id: string; }); 42 | read(input: Object): void; 43 | write(input: Object): void; 44 | } 45 | 46 | /** 47 | * Sent to notify that the CPU frequency has changed 48 | */ 49 | export declare class DbuTimelineCpuClockChangedNotification { 50 | cyclesPerSecond: Int64; 51 | 52 | constructor(args?: { cyclesPerSecond: Int64; }); 53 | read(input: Object): void; 54 | write(input: Object): void; 55 | } 56 | 57 | /** 58 | * Sent to notify that the enablement state of all the channels matching the provided id regexp has changed 59 | */ 60 | export declare class DbuTimelineEnablementChangedNotification { 61 | channelId: string; 62 | enabled: boolean; 63 | 64 | constructor(args?: { channelId: string; enabled: boolean; }); 65 | read(input: Object): void; 66 | write(input: Object): void; 67 | } 68 | 69 | export declare class TimelineChannelInfo { 70 | id: string; 71 | formatDescriptor: string; 72 | 73 | constructor(args?: { id: string; formatDescriptor: string; }); 74 | read(input: Object): void; 75 | write(input: Object): void; 76 | } 77 | 78 | export declare var TIMELINE_FRONTEND_SERVICE: string; 79 | 80 | export declare var TIMELINE_BACKEND_SERVICE: string; 81 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | root: true, 3 | parser: "@typescript-eslint/parser", 4 | overrides: [ 5 | { 6 | files: ["*.ts"], 7 | parserOptions: { 8 | project: ["./src/tsconfig.json"], 9 | tsconfigRootDir: __dirname 10 | } 11 | } 12 | ], 13 | plugins: [ 14 | "@typescript-eslint", 15 | "deprecation" 16 | ], 17 | extends: [ 18 | "eslint:recommended", 19 | "plugin:@typescript-eslint/eslint-recommended", 20 | "plugin:@typescript-eslint/recommended" 21 | ], 22 | env: { 23 | node: true 24 | }, 25 | ignorePatterns: [".eslintrc.js"], 26 | rules: { 27 | "@typescript-eslint/no-unused-vars": [ 28 | "error", 29 | { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" } // Same as in tsconfig. Allow such vars if they start with an underscore. 30 | ], 31 | "require-await": "error", // Helps catch missing awaits 32 | "strict": "error", // Disallows use of e.g. reserved keywords 33 | "prefer-promise-reject-errors": "error", // Throwing real Errors helps traceability 34 | "@typescript-eslint/no-namespace": "off", 35 | "@typescript-eslint/prefer-readonly": "error", 36 | "@typescript-eslint/consistent-type-definitions": "error", // Prefer 'interface' over 'type' 37 | "@typescript-eslint/no-empty-interface": "off", 38 | "no-empty": "off", // Empty catch blocks can be useful 39 | "no-inner-declarations": "off", // Seems to break when using TS namespaces 40 | "eqeqeq": "error", // == can be obscure/unintuitive, so use === 41 | "deprecation/deprecation": "warn", 42 | "no-constant-condition": "off", 43 | // CODE FORMATTING ================= 44 | "semi": "warn", 45 | "camelcase": "warn", 46 | "indent": ["warn", 4, { SwitchCase: 1 }], 47 | "space-before-blocks": "warn", 48 | "keyword-spacing": "warn", 49 | "space-before-function-paren": ["warn", "never"], 50 | "dot-location": "warn", 51 | "quotes": ["warn", "double", {"allowTemplateLiterals": true}], // Disallows single quote strings 52 | "comma-spacing": "warn", 53 | "brace-style": "warn", 54 | "@typescript-eslint/type-annotation-spacing": "warn", 55 | "no-trailing-spaces": "warn" 56 | } 57 | } 58 | module.exports = config; -------------------------------------------------------------------------------- /webviews/test/listwindow/scrollbar.test.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | /* eslint-disable @typescript-eslint/no-non-null-assertion */ 5 | 6 | import * as Assert from "assert"; 7 | import { TestUtils } from "./utils"; 8 | import { setupTestEnvironment } from "./testEnvironment"; 9 | 10 | suite("Scrollbar", () => { 11 | // We have no way of getting the 'dataTransfer' from a dragged cell, so for 12 | // now we only test external drops 13 | 14 | test("Is hidden when entire content fits in window", async() => { 15 | const { api, dom } = await setupTestEnvironment(); 16 | 17 | const renderParams = TestUtils.generateRenderParameters(1); 18 | await TestUtils.render(api, renderParams); 19 | 20 | const scrollbar: HTMLElement | null = dom.window.document.querySelector( 21 | "listwindow-scrollbar", 22 | ); 23 | if (scrollbar) { 24 | Assert.strictEqual(scrollbar.style.display, "none"); 25 | } 26 | }); 27 | 28 | test("Is shown when content does not fit in window", async() => { 29 | const { api, dom } = await setupTestEnvironment(); 30 | 31 | const renderParams = TestUtils.generateRenderParameters(1); 32 | renderParams.scrollInfo.fractionBefore = 0.5; 33 | renderParams.scrollInfo.fractionInWin = 0.5; 34 | await TestUtils.render(api, renderParams); 35 | 36 | const scrollbar: HTMLElement | null = dom.window.document.querySelector( 37 | "listwindow-scrollbar", 38 | ); 39 | Assert(scrollbar); 40 | Assert.notStrictEqual(scrollbar.style.display, "none"); 41 | }); 42 | 43 | test("Sends events on click", async() => { 44 | const { api, dom, user } = await setupTestEnvironment(); 45 | 46 | const renderParams = TestUtils.generateRenderParameters(1); 47 | renderParams.scrollInfo.fractionBefore = 0.5; 48 | renderParams.scrollInfo.fractionInWin = 0.5; 49 | await TestUtils.render(api, renderParams); 50 | 51 | const scrollbar: HTMLElement | null = dom.window.document.querySelector( 52 | "listwindow-scrollbar", 53 | ); 54 | Assert(scrollbar); 55 | Assert.notStrictEqual(scrollbar.style.display, "none"); 56 | 57 | user.click(scrollbar); 58 | await api.waitForMessage("absoluteScrolled"); 59 | }); 60 | }); 61 | -------------------------------------------------------------------------------- /webviews/test/listwindow/dragging.test.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | /* eslint-disable @typescript-eslint/no-non-null-assertion */ 5 | 6 | import * as Assert from "assert"; 7 | import { TestUtils } from "./utils"; 8 | import { setupTestEnvironment } from "./testEnvironment"; 9 | import { fireEvent, queries } from "@testing-library/dom"; 10 | 11 | suite("Listwindow drag & drop", () => { 12 | // We have no way of getting the 'dataTransfer' from a dragged cell, so for 13 | // now we only test external drops 14 | 15 | test("Handles external drop on cells", async() => { 16 | const { api, dom } = await setupTestEnvironment(); 17 | 18 | const renderParams = TestUtils.generateRenderParameters(1); 19 | await TestUtils.render(api, renderParams); 20 | 21 | const cell = renderParams.rows[0]!.cells[0]!; 22 | const cellElem = queries.getByText( 23 | dom.window.document.documentElement, 24 | cell.text, 25 | ); 26 | 27 | const msgPromise = api.waitForMessage("externalDrop"); 28 | const dropText = "Hello drop"; 29 | fireEvent.drop(cellElem, { 30 | dataTransfer: { 31 | getData: (type: string) => 32 | type === "text/plain" ? dropText : "", 33 | }, 34 | }); 35 | const msg = await msgPromise; 36 | Assert.strictEqual(msg.col, 0); 37 | Assert.strictEqual(msg.row.value, "0"); 38 | Assert.strictEqual(msg.droppedText, dropText); 39 | }); 40 | 41 | test("Handles external drop outside cells", async() => { 42 | const { api, dom } = await setupTestEnvironment(); 43 | 44 | const renderParams = TestUtils.generateRenderParameters(1); 45 | await TestUtils.render(api, renderParams); 46 | 47 | const gridElem = dom.window.document.querySelector("#app")!.children[0]!; 48 | 49 | const msgPromise = api.waitForMessage("externalDrop"); 50 | const dropText = "Hello drop"; 51 | fireEvent.drop(gridElem, { 52 | dataTransfer: { 53 | getData: (type: string) => 54 | type === "text/plain" ? dropText : "", 55 | }, 56 | }); 57 | const msg = await msgPromise; 58 | Assert.strictEqual(msg.col, -1); 59 | Assert.strictEqual(msg.row.value, "-1"); 60 | Assert.strictEqual(msg.droppedText, dropText); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | "use strict"; 3 | 4 | const path = require("path"); 5 | const webpack = require("webpack"); 6 | 7 | /**@type {webpack.Configuration}*/ 8 | const extensionConfig = { 9 | name: "extension", 10 | target: "node", 11 | entry: "./src/extension.ts", 12 | output: { 13 | path: path.resolve(__dirname, "out/src"), 14 | filename: "extension.js", 15 | libraryTarget: "commonjs2", 16 | devtoolModuleFilenameTemplate: "../../[resource-path]" 17 | }, 18 | devtool: "source-map", 19 | externals: { 20 | vscode: "commonjs vscode" 21 | }, 22 | resolve: { 23 | mainFields: ["browser", "module", "main"], 24 | extensions: [".ts", ".js"], 25 | alias: { 26 | // provides alternate implementation for node module and source files 27 | }, 28 | fallback: { 29 | } 30 | }, 31 | module: { 32 | rules: [ 33 | { 34 | test: /\.ts$/, 35 | exclude: /node_modules/, 36 | use: [ 37 | { 38 | loader: "ts-loader", 39 | options: { 40 | configFile: path.resolve(__dirname, "src/tsconfig.json") 41 | } 42 | } 43 | ] 44 | }, 45 | ] 46 | } 47 | }; 48 | 49 | // Add an entry for each webview here. '"X": "./A/B.ts"' will bundle './A/B.ts' 50 | // and generate 'out/webviews/X.js' 51 | const webviewEntries = { 52 | listwindow: "./webviews/listwindow/index.ts", 53 | form: "./webviews/form/index.ts", 54 | }; 55 | 56 | /**@type {webpack.Configuration}*/ 57 | const webviewConfig = { 58 | name: "webviews", 59 | target: "web", 60 | entry: webviewEntries, 61 | experiments: { 62 | outputModule: true 63 | }, 64 | output: { 65 | path: path.resolve(__dirname, "out/webviews/"), 66 | filename: "[name].js", 67 | libraryTarget: "module", 68 | publicPath: '#{root}/dist/', 69 | }, 70 | devtool: "source-map", 71 | resolve: { 72 | extensions: [".ts", ".js"], 73 | alias: { 74 | // provides alternate implementation for node module and source files 75 | }, 76 | fallback: { 77 | } 78 | }, 79 | module: { 80 | rules: [ 81 | { 82 | test: /\.ts$/, 83 | exclude: /node_modules/, 84 | use: [ 85 | { 86 | loader: "ts-loader", 87 | options: { 88 | configFile: path.resolve(__dirname, "webviews/tsconfig.json") 89 | } 90 | } 91 | ] 92 | } 93 | ] 94 | }, 95 | plugins: [] 96 | }; 97 | 98 | module.exports = [extensionConfig, webviewConfig]; -------------------------------------------------------------------------------- /src/dap/breakpoints/descriptors/locEtcDescriptor.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import { DescriptorReader } from "./descriptorReader"; 5 | import { DescriptorWriter } from "./descriptorWriter"; 6 | import { LocOnlyDescriptor } from "./locOnlyDescriptor"; 7 | 8 | /** 9 | * A descriptor corresponding to DbuStandardBpDescriptors.cpp, 10 | * adding e.g. conditions and skip count. 11 | */ 12 | export class LocEtcDescriptor extends LocOnlyDescriptor { 13 | // Keeping these private until we actually support them 14 | private readonly isThreadSpecific: boolean; 15 | private readonly threadId: number; 16 | private readonly stopWhenTrue: boolean; 17 | public condition: string; 18 | public skipCount: number; 19 | private readonly action: string; 20 | 21 | /** 22 | * Typescript doesn't support multiple constructors, so we have to fuse them together like this. 23 | * constructor(reader: DescriptorReader) 24 | * Constructs a new descriptor by deserializing from the given reader. 25 | * constructor([categoryId: string, ule: string]) 26 | * Creates a new descriptor from scratch using the given category id and ule. Other attributes 27 | * will be given their default values. 28 | */ 29 | constructor(arg: DescriptorReader | [string, string]) { 30 | if (arg instanceof DescriptorReader) { 31 | const reader = arg; 32 | super(reader); 33 | this.isThreadSpecific = reader.readBoolean(); 34 | this.threadId = reader.readInteger(); 35 | this.stopWhenTrue = reader.readBoolean(); 36 | this.condition = reader.readString(); 37 | this.skipCount = reader.readInteger(); 38 | this.action = reader.readString(); 39 | } else { 40 | super(arg); 41 | this.isThreadSpecific = false; 42 | this.threadId = 0; 43 | this.stopWhenTrue = true; 44 | this.condition = ""; 45 | this.skipCount = 0; 46 | this.action = ""; 47 | } 48 | } 49 | 50 | override serialize(writer: DescriptorWriter) { 51 | super.serialize(writer); 52 | writer.writeBool(this.isThreadSpecific); 53 | writer.writeInteger(this.threadId); 54 | writer.writeBool(this.stopWhenTrue); 55 | writer.writeString(this.condition); 56 | writer.writeInteger(this.skipCount); 57 | writer.writeString(this.action); 58 | } 59 | } -------------------------------------------------------------------------------- /src/dap/configresolution/launchArgumentConfigurationResolver.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | 6 | import { CSpyLaunchRequestArguments } from "../cspyDebug"; 7 | import { BaseConfigurationResolver, PartialSessionConfiguration } from "./baseConfigurationResolver"; 8 | import { IarOsUtils } from "iar-vsc-common/osUtils"; 9 | import { CSpyDriver } from "../breakpoints/cspyDriver"; 10 | 11 | /** 12 | * Attempts to create a C-SPY configuration by looking at `.xcl` 13 | * files in the settings directory of a project, which contain the 14 | * C-SPY command line arguments last used by the EW. 15 | */ 16 | export class LaunchArgumentConfigurationResolver extends BaseConfigurationResolver { 17 | 18 | resolveLaunchArgumentsPartial(args: CSpyLaunchRequestArguments): Promise { 19 | if (!args.driver) { 20 | return Promise.reject(new Error("No driver lib specified")); 21 | } 22 | 23 | // The libraries for msp430 lack the msp prefix... 24 | const target = args.target === "msp430" ? "430" : args.target; 25 | 26 | const plugins = args.plugins ?? []; 27 | // eslint-disable-next-line deprecation/deprecation 28 | const macros = args.setupMacros ?? args.macros ?? []; 29 | 30 | const driver = CSpyDriver.driverFromName(args.driver, target, args.driverOptions); 31 | const driverFile = driver.libraryBaseNames. 32 | map(baseName => IarOsUtils.resolveTargetLibrary(args.workbenchPath, target, baseName)). 33 | find(driverFile => driverFile !== undefined); 34 | if (driverFile === undefined) { 35 | throw new Error(`Could not find driver file(s) '${driver.libraryBaseNames.join(",")}' for '${args.workbenchPath}'.`); 36 | } 37 | const proc = IarOsUtils.resolveTargetLibrary(args.workbenchPath, target, "proc"); 38 | if (proc === undefined) { 39 | throw new Error(`Could not find library 'proc' for '${args.workbenchPath}'.`); 40 | } 41 | 42 | const config: PartialSessionConfiguration = { 43 | attachToTarget: false, 44 | driverFile, 45 | processorName: proc, 46 | type: "simulator", 47 | options: (args.driverOptions? args.driverOptions : []), 48 | plugins: plugins, 49 | setupMacros: macros, 50 | target: target 51 | }; 52 | 53 | return Promise.resolve(config); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/dap/breakpoints/descriptors/emulDataBreakpointDescriptor.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import { AccessType } from "./accessType"; 5 | import { DescriptorReader } from "./descriptorReader"; 6 | import { DescriptorWriter } from "./descriptorWriter"; 7 | import { LocOnlyDescriptor } from "./locOnlyDescriptor"; 8 | 9 | /** 10 | * Breakpoint descriptor for EMUL_DATA breakpoints, used e.g. by i-jet and j-link. 11 | */ 12 | export class EmulDataBreakpointDescriptor extends LocOnlyDescriptor { 13 | /** 14 | * The access type to break on (e.g. read/write/readWrite) 15 | */ 16 | private readonly access: AccessType; 17 | private readonly useExtendedRange: boolean; 18 | private readonly useMatchData: boolean; 19 | private readonly dataValue: number; 20 | private readonly dataMask: number; 21 | 22 | /** 23 | * Typescript doesn't support multiple constructors, so we have to fuse them together like this. 24 | * constructor(reader: DescriptorReader) 25 | * Constructs a new descriptor by deserializing from the given reader. 26 | * constructor([categoryId: string, ule: string, type: AccessType]) 27 | * Creates a new descriptor from scratch using the given category id, ule and access type. Other attributes 28 | * will be given their default values. 29 | */ 30 | constructor(arg: DescriptorReader | [string, string, AccessType | number]) { 31 | if (arg instanceof DescriptorReader) { 32 | const reader = arg; 33 | super(reader); 34 | this.access = reader.readInteger(); 35 | this.useExtendedRange = reader.readBoolean(); 36 | this.useMatchData = reader.readBoolean(); 37 | this.dataValue = reader.readInteger(); 38 | this.dataMask = reader.readInteger(); 39 | } else { 40 | const [categoryId, ule, accessType] = arg; 41 | super([categoryId, ule]); 42 | this.access = accessType; 43 | this.useExtendedRange = false; 44 | this.useMatchData = false; 45 | this.dataValue = 0; 46 | this.dataMask = 0; 47 | } 48 | } 49 | 50 | override serialize(writer: DescriptorWriter) { 51 | super.serialize(writer); 52 | writer.writeInteger(this.access); 53 | writer.writeBool(this.useExtendedRange); 54 | writer.writeBool(this.useMatchData); 55 | writer.writeInteger(this.dataValue); 56 | writer.writeInteger(this.dataMask); 57 | } 58 | } -------------------------------------------------------------------------------- /src/dap/breakpoints/descriptors/logDescriptor.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import { DescriptorReader } from "./descriptorReader"; 5 | import { DescriptorWriter } from "./descriptorWriter"; 6 | import { LocOnlyDescriptor } from "./locOnlyDescriptor"; 7 | 8 | /** 9 | * Breakpoint descriptor for log breakpoints (e.g. STD_LOG2). 10 | */ 11 | export class LogDescriptor extends LocOnlyDescriptor { 12 | public readonly condition: string; 13 | private readonly triggerWhenTrue: boolean; 14 | private readonly message: string; 15 | private readonly msgIsArgList: boolean; 16 | private readonly threadSpecific: boolean; 17 | private readonly threadId: number; 18 | 19 | 20 | /** 21 | * Typescript doesn't support multiple constructors, so we have to fuse them together like this. 22 | * constructor(reader: DescriptorReader) 23 | * Constructs a new descriptor by deserializing from the given reader. 24 | * constructor([categoryId: string, ule: string, message: string]) 25 | * Creates a new descriptor from scratch using the given category id, ule and message. Other attributes 26 | * will be given their default values. 27 | */ 28 | constructor(arg: DescriptorReader | [string, string, string]) { 29 | if (arg instanceof DescriptorReader) { 30 | const reader = arg; 31 | super(reader); 32 | this.condition = reader.readString(); 33 | this.triggerWhenTrue = reader.readBoolean(); 34 | this.message = reader.readString(); 35 | this.msgIsArgList = reader.readBoolean(); 36 | this.threadSpecific = reader.readBoolean(); 37 | this.threadId = reader.readInteger(); 38 | } else { 39 | const [categoryId, ule, message] = arg; 40 | super([categoryId, ule]); 41 | this.condition = ""; 42 | this.triggerWhenTrue = true, 43 | this.message = message; 44 | this.msgIsArgList = true; 45 | this.threadSpecific = false; 46 | this.threadId = 0; 47 | } 48 | } 49 | 50 | override serialize(writer: DescriptorWriter) { 51 | super.serialize(writer); 52 | writer.writeString(this.condition); 53 | writer.writeBool(this.triggerWhenTrue); 54 | writer.writeString(this.message); 55 | writer.writeBool(this.msgIsArgList); 56 | writer.writeBool(this.threadSpecific); 57 | writer.writeInteger(this.threadId); 58 | } 59 | } -------------------------------------------------------------------------------- /webviews/shared/thrift/Gatekeeper.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | // 3 | // Autogenerated by Thrift Compiler (0.14.0) 4 | // 5 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 6 | // 7 | 8 | import Int64 = require('node-int64'); 9 | 10 | import { ampsync } from "./ampsync_types"; 11 | 12 | 13 | export declare class Client extends HeartbeatService.Client { 14 | input: Thrift.TJSONProtocol; 15 | output: Thrift.TJSONProtocol; 16 | seqid: number; 17 | 18 | constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol); 19 | 20 | SetRunAllCores(all: boolean): Q.Promise; 21 | 22 | SetRunAllCores(all: boolean, callback?: (data: void)=>void): void; 23 | 24 | SetStartOneStartsAll(on: boolean): Q.Promise; 25 | 26 | SetStartOneStartsAll(on: boolean, callback?: (data: void)=>void): void; 27 | 28 | SetSoftCTI(on: boolean): Q.Promise; 29 | 30 | SetSoftCTI(on: boolean, callback?: (data: void)=>void): void; 31 | 32 | BeforeLowLevelGo(core: number, multi: boolean): Q.Promise; 33 | 34 | BeforeLowLevelGo(core: number, multi: boolean, callback?: (data: LowLevelAction)=>void): void; 35 | 36 | StartedCPU(core: number): Q.Promise; 37 | 38 | StartedCPU(core: number, callback?: (data: void)=>void): void; 39 | 40 | CPUStoped(core: number): Q.Promise; 41 | 42 | CPUStoped(core: number, callback?: (data: void)=>void): void; 43 | 44 | IsTargetStopped(): Q.Promise; 45 | 46 | IsTargetStopped(callback?: (data: boolean)=>void): void; 47 | 48 | AfterLowLevelGo(core: number, code: CoreLowLevelResult): Q.Promise; 49 | 50 | AfterLowLevelGo(core: number, code: CoreLowLevelResult, callback?: (data: WhatNext)=>void): void; 51 | 52 | Reset(): Q.Promise; 53 | 54 | Reset(callback?: (data: void)=>void): void; 55 | 56 | StopAll(): Q.Promise; 57 | 58 | StopAll(callback?: (data: void)=>void): void; 59 | 60 | SpontaneousCoreStatusChange(core: number, status: CoreStatus): Q.Promise; 61 | 62 | SpontaneousCoreStatusChange(core: number, status: CoreStatus, callback?: (data: void)=>void): void; 63 | 64 | GetCoreStatus(core: number): Q.Promise; 65 | 66 | GetCoreStatus(core: number, callback?: (data: CoreStatus)=>void): void; 67 | 68 | IsItOkToStopCore(core: number): Q.Promise; 69 | 70 | IsItOkToStopCore(core: number, callback?: (data: boolean)=>void): void; 71 | 72 | SetCPUStatusPolling(on: boolean): Q.Promise; 73 | 74 | SetCPUStatusPolling(on: boolean, callback?: (data: void)=>void): void; 75 | 76 | AckCPUStatusPolling(coreCount: number): Q.Promise; 77 | 78 | AckCPUStatusPolling(coreCount: number, callback?: (data: void)=>void): void; 79 | } 80 | -------------------------------------------------------------------------------- /tests/suites/dbg/debugSession.test.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import * as vscode from "vscode"; 5 | import { TestUtils } from "../testUtils"; 6 | import { TestConfiguration } from "../testConfiguration"; 7 | 8 | 9 | /** 10 | * Tests against a full debug session started from vs code. 11 | * Testing this way is a bit clumsy, since there are limits to what information we can 12 | * probe for from the vs code api. For example, after stepping or running, we can't know 13 | * when the debugger has stopped again, we instead just have to wait. 14 | * 15 | * An improvement would be to have the debug adapter support multiple clients at the 16 | * same time. Then we could have vs code connect to it, and also have a DebugClient 17 | * instance to use for e.g. waiting for events. However, the debug adapter currently only 18 | * supports having one client at a time. 19 | */ 20 | suite("New tests", () =>{ 21 | 22 | let dbgConfig: vscode.DebugConfiguration; 23 | 24 | let activeSession: vscode.DebugSession; 25 | 26 | vscode.debug.onDidStartDebugSession((session)=>{ 27 | activeSession = session; 28 | }); 29 | 30 | suiteSetup(async() => { 31 | dbgConfig = await TestUtils.doSetup(); 32 | }); 33 | 34 | setup(async function() { 35 | console.log("\n==========================================================" + this.currentTest!.title + "==========================================================\n"); 36 | await vscode.debug.startDebugging(undefined, dbgConfig); 37 | await TestUtils.wait(4000); 38 | 39 | }); 40 | 41 | teardown(async()=>{ 42 | await vscode.debug.stopDebugging(activeSession); 43 | await TestUtils.wait(2000); 44 | }); 45 | 46 | test("Test launch", async()=>{ 47 | const startLine = TestConfiguration.getConfiguration().stopsAfterMain ? 45 : 43; 48 | const column = TestConfiguration.getConfiguration().stopsAfterMain ? 3 : 1; 49 | await TestUtils.assertCurrentLineIs(activeSession, "", startLine, column); 50 | }); 51 | 52 | 53 | test("Test step", async()=>{ 54 | const startLine = TestConfiguration.getConfiguration().stopsAfterMain ? 45 : 43; 55 | const column = TestConfiguration.getConfiguration().stopsAfterMain ? 3 : 1; 56 | await TestUtils.assertCurrentLineIs(activeSession, "", startLine, column); 57 | await activeSession.customRequest("next", {granularity: ""}); 58 | await TestUtils.wait(1000); 59 | await TestUtils.assertCurrentLineIs(activeSession, "", startLine + 2, 3); 60 | }); 61 | 62 | }); -------------------------------------------------------------------------------- /src/listwindows/clients/quickwatchLegacyClient.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import { ThriftServiceRegistry } from "iar-vsc-common/thrift/thriftServiceRegistry"; 6 | import { 7 | LegacyListwindowClient, 8 | LegacyToolbarItem, 9 | } from "./listwindowBackendClient"; 10 | import { ThriftClient } from "iar-vsc-common/thrift/thriftClient"; 11 | import { ToolbarItemType } from "../../../webviews/shared/rendering/toolbar/toolbarConstants"; 12 | import { PropertyTreeItem } from "iar-vsc-common/thrift/bindings/shared_types"; 13 | import * as Q from "q"; 14 | import * as ListWindowBackend from "iar-vsc-common/thrift/bindings/ListWindowBackend"; 15 | import * as QuickWatch from "iar-vsc-common/thrift/bindings/QuickWatch"; 16 | 17 | /** 18 | * Quickwatch client 19 | */ 20 | export class QuickWatchClient extends LegacyListwindowClient { 21 | public connectToBackend( 22 | serviceName: string, 23 | serviceRegistry: ThriftServiceRegistry, 24 | ): Promise> { 25 | return this.doConnect(serviceName, serviceRegistry, QuickWatch.Client); 26 | } 27 | 28 | private readonly def: LegacyToolbarItem[] = [ 29 | { 30 | id: "reload", 31 | type: ToolbarItemType.kKindIconButton, 32 | text: "IDI_DBG_QWATCH_RECALCULATE", 33 | bool: true, 34 | itemKey: "", 35 | stringList: [], 36 | text2: "", 37 | tooltip: "", 38 | callback: tree => { 39 | return this.onEval(tree); 40 | }, 41 | }, 42 | { 43 | id: "edit", 44 | type: ToolbarItemType.kKindEditTextDyn, 45 | text: "", 46 | bool: true, 47 | itemKey: "", 48 | stringList: [], 49 | text2: "", 50 | tooltip: "", 51 | callback: tree => { 52 | return this.onEdit(tree); 53 | }, 54 | }, 55 | ]; 56 | 57 | getDescription(): Q.Promise { 58 | return Q.resolve(this.def); 59 | } 60 | 61 | private latestEval = ""; 62 | public onEdit(tree: PropertyTreeItem): Q.Promise { 63 | this.latestEval = tree.children[1]?.value as string; 64 | return this.onEval(tree); 65 | } 66 | 67 | public onEval(_tree: PropertyTreeItem): Q.Promise { 68 | return this.withClient(c => { 69 | return c.service. 70 | evaluate(this.latestEval). 71 | then(() => Q.resolve(true)); 72 | }, false); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/listwindows/clients/stackLegacyClient.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | import { ThriftServiceRegistry } from "iar-vsc-common/thrift/thriftServiceRegistry"; 6 | import { 7 | LegacyListwindowClient, 8 | LegacyToolbarItem, 9 | } from "./listwindowBackendClient"; 10 | import { ThriftClient } from "iar-vsc-common/thrift/thriftClient"; 11 | import { ToolbarItemType } from "../../../webviews/shared/rendering/toolbar/toolbarConstants"; 12 | import * as Q from "q"; 13 | import * as ListWindowBackend from "iar-vsc-common/thrift/bindings/ListWindowBackend"; 14 | import * as Stack from "iar-vsc-common/thrift/bindings/Stack"; 15 | import { PropertyTreeItem } from "iar-vsc-common/thrift/bindings/shared_types"; 16 | 17 | /** 18 | * Stack client 19 | */ 20 | export class StackClient extends LegacyListwindowClient { 21 | public connectToBackend( 22 | serviceName: string, 23 | serviceRegistry: ThriftServiceRegistry, 24 | ): Promise> { 25 | return this.doConnect(serviceName, serviceRegistry, Stack.Client); 26 | } 27 | 28 | private async getItems(): Promise { 29 | let stacks: string[] = []; 30 | if (this.client) { 31 | stacks = await this.client.service.getStacks(); 32 | } 33 | return [ 34 | { 35 | id: "memorySelection", 36 | type: ToolbarItemType.kKindSelectMenuDyn, 37 | text: "Stack:", 38 | bool: true, 39 | itemKey: "", 40 | stringList: stacks, 41 | text2: "", 42 | callback: tree => { 43 | return this.setStack(tree); 44 | }, 45 | }, 46 | { 47 | id: "previousButton", 48 | type: ToolbarItemType.kKindProgressBar, 49 | text: "", 50 | bool: true, 51 | itemKey: "", 52 | stringList: [], 53 | text2: "", 54 | tooltip: "Current stack usage", 55 | }, 56 | ]; 57 | } 58 | 59 | private setStack(tree: PropertyTreeItem) { 60 | const stack = tree.children[1]?.value as string; 61 | return this.withClient(c => { 62 | return c.service.setStack(stack).then(() => Q.resolve(true)); 63 | }, false); 64 | } 65 | 66 | getDescription(): Q.Promise { 67 | return Q.resolve().then(async() => { 68 | const items = await this.getItems(); 69 | return Q.resolve(items); 70 | }); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/dap/commandRegistry.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | 6 | /** 7 | * Allows registering text-based commands which can be run by a user (e.g. via the debug console). 8 | * @typeParam Arg the type of argument passed to each command 9 | * @typeParam Ret the return value of each command (promisified) 10 | */ 11 | export class CommandRegistry { 12 | private readonly commands: Command[] = []; 13 | 14 | /** 15 | * Registers a new command 16 | */ 17 | registerCommand(name: string, action: CommandCallback) { 18 | this.commands.push(new Command(name, action)); 19 | } 20 | /** 21 | * Registers a command that performs type checking of the command argument, narrowing it from the the argument type 22 | * used by the command registry. If the command is run with an argument that does not pass the type check, an error 23 | * is thrown. 24 | */ 25 | registerCommandWithTypeCheck(name: string, checkFun: (arg: Arg) => arg is NarrowedArg, action: CommandCallback) { 26 | this.commands.push(new Command(name, (arg => { 27 | if (checkFun(arg)) { 28 | return action(arg); 29 | } 30 | return Promise.reject(new Error("Invalid argument type")); 31 | }))); 32 | } 33 | 34 | /** 35 | * The name of all registered commands 36 | */ 37 | get commandNames(): string[] { 38 | return this.commands.map(command => command.name); 39 | } 40 | 41 | /** 42 | * Returns whether there is a command with the given name 43 | */ 44 | hasCommand(name: string) { 45 | return this.commands.some(command => command.name === name); 46 | } 47 | 48 | /** 49 | * Runs the command with the given name (if it exists). May return a string 50 | * to display to the user. 51 | */ 52 | runCommand(name: string, arg: Arg): Promise { 53 | const toRun = this.commands.find(command => command.name === name); 54 | if (toRun !== undefined) { 55 | return Promise.resolve(toRun.callback(arg)); 56 | } 57 | return Promise.reject(new Error("No such command")); 58 | } 59 | } 60 | 61 | /** 62 | * Function to call when a command is run. 63 | */ 64 | export type CommandCallback = (argument: Arg) => Promise | Ret; 65 | 66 | /** 67 | * A command which the user can run. Has a name (i.e. what the user types to run it) 68 | * and a function to run. 69 | */ 70 | class Command { 71 | constructor(public readonly name: string, public readonly callback: CommandCallback) {} 72 | } -------------------------------------------------------------------------------- /src/dap/debugEventListenerHandler.ts: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | import { DebugEvent, LogEvent, InspectionContextChangedEvent, BaseContextChangedEvent, DkNotifyConstant } from "iar-vsc-common/thrift/bindings/cspy_types"; 5 | import { ThriftServiceHandler } from "iar-vsc-common/thrift/thriftUtils"; 6 | import * as DebugEventListener from "iar-vsc-common/thrift/bindings/DebugEventListener"; 7 | import * as Q from "q"; 8 | 9 | type EventCallback = (event: T) => void; 10 | 11 | /** 12 | * Implements the DebugEventListener thrift service, 13 | * and provides ways for others to listen for specific events 14 | */ 15 | export class DebugEventListenerHandler implements ThriftServiceHandler { 16 | private readonly debugEventCallbacks: Map[]> = new Map(); 17 | private readonly logEventCallbacks: EventCallback[] = []; 18 | 19 | 20 | /** 21 | * Register a callback to be called when receiving debug events of the specified type. 22 | */ 23 | public observeDebugEvents(type: DkNotifyConstant, callback: EventCallback) { 24 | if (!this.debugEventCallbacks.get(type)) { 25 | this.debugEventCallbacks.set(type, []); 26 | } 27 | this.debugEventCallbacks.get(type)?.push(callback); 28 | } 29 | 30 | /** 31 | * Register a callback to be called when receiving log events. 32 | */ 33 | public observeLogEvents(callback: EventCallback) { 34 | this.logEventCallbacks.push(callback); 35 | } 36 | 37 | /// Callbacks from C-SPY 38 | 39 | /** 40 | * Called whenever a debug event happens. See DkNotifySubscriber#Notify. 41 | */ 42 | postDebugEvent(event: DebugEvent): Q.Promise { 43 | this.debugEventCallbacks.get(event.note)?.forEach((callback: EventCallback) => callback(event)); 44 | return Q.resolve(); 45 | } 46 | 47 | /** 48 | * This one should not be oneway, since we need to make sure that the 49 | * client has actually recevied the message before proceeding. This will 50 | * otherwise prevent e.g. fatal error messages from being seen. 51 | */ 52 | postLogEvent(event: LogEvent): Q.Promise { 53 | this.logEventCallbacks.forEach(callback => callback(event)); 54 | return Q.resolve(); 55 | } 56 | 57 | /** 58 | * Triggered on kDkInspectionContextChanged. 59 | */ 60 | postInspectionContextChangedEvent(_event: InspectionContextChangedEvent): Q.Promise { 61 | return Q.resolve(); 62 | } 63 | 64 | 65 | /** 66 | * Triggered on kDkBaseContextChanged. 67 | */ 68 | postBaseContextChangedEvent(_event: BaseContextChangedEvent): Q.Promise { 69 | return Q.resolve(); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /.husky/pre-commit.js: -------------------------------------------------------------------------------- 1 | /// ----------------------------- 2 | // This hook forces the source for the "iar-vsc-common" dependency to point to the public repository on IAR System's github. 3 | // During development it's practical to use other sources for this dependency (i.e. a local clone); this hook should 4 | // prevent accidental commits of such changes. 5 | // 6 | // This hook also forces all source files to have the MPLv2 license header at the start of the file. 7 | /// ----------------------------- 8 | 9 | const { spawnSync } = require("child_process"); 10 | const { readFileSync } = require("fs"); 11 | const { exit } = require("process"); 12 | var proc = require('child_process'); 13 | 14 | function runAndGetStdout(command, callback){ 15 | proc.exec(command, function(error, stdout, stderr) { 16 | callback(stdout); 17 | }); 18 | }; 19 | 20 | const MPLv2_header = `/* This Source Code Form is subject to the terms of the Mozilla Public 21 | * License, v. 2.0. If a copy of the MPL was not distributed with this 22 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */` 23 | 24 | runAndGetStdout("git diff --cached --name-only --diff-filter=ACMR", function(changedFiles) { 25 | const regex = "git@github\\.com:IARSystems/iar-vsc-common\\.git#[\\da-fA-F]{8}" 26 | if (changedFiles.includes("package.json")) { 27 | runAndGetStdout("git --no-pager show :package.json", function(package) { 28 | const source = JSON.parse(package)["dependencies"]?.["iar-vsc-common"]; 29 | if (!new RegExp(regex).test(source)) { 30 | console.log(`package.json: The source for the dependency 'iar-vsc-common' is not allowed: '${source}'.`); 31 | console.log(` It must match '${regex}'.`); 32 | console.log(" Using other values will break the build."); 33 | exit(1); 34 | } 35 | }); 36 | } 37 | 38 | if (changedFiles.includes("package-lock.json")) { 39 | runAndGetStdout("git --no-pager show :package-lock.json", function(package_lock) { 40 | const source = JSON.parse(package_lock)["packages"]?.[""]?.["dependencies"]?.["iar-vsc-common"]; 41 | if (!new RegExp(regex).test(source)) { 42 | console.log(`package-lock.json: The source for the dependency 'iar-vsc-common' is not allowed: '${source}'.`); 43 | console.log(` It must match '${regex}'.`); 44 | console.log(" Using other values will break the build."); 45 | exit(1); 46 | } 47 | }); 48 | } 49 | 50 | const filesArray = changedFiles.trim().split("\n"); 51 | // Check that all typescript files have the mpl preamble 52 | const res = filesArray.filter(file => file.endsWith(".ts") && !file.endsWith(".d.ts")).map(file => { 53 | const contents = readFileSync(file).toString().replace(/\r\n/g, "\n"); 54 | if (!contents.startsWith(MPLv2_header)) { 55 | console.log("Missing or malformed MPLv2 license header in file: " + file); 56 | return false; 57 | } 58 | return true; 59 | }); 60 | if (!res.every(v => v)) { 61 | exit(1); 62 | } 63 | }); --------------------------------------------------------------------------------