Merge from vscode fb5dc0083bfa9a0e3da7ed1f86e1ecb9836fcc8b

This commit is contained in:
ADS Merger
2020-03-13 05:35:18 +00:00
parent 7658a5df28
commit a7e56d334f
88 changed files with 1627 additions and 553 deletions

View File

@@ -118,7 +118,7 @@ registerCommands();
// register action to open viewlet
const registry = Registry.as<IWorkbenchActionRegistry>(WorkbenchActionRegistryExtensions.WorkbenchActions);
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenDebugPanelAction, OpenDebugPanelAction.ID, OpenDebugPanelAction.LABEL, openPanelKb), 'View: Debug Console', nls.localize('view', "View"));
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenDebugViewletAction, OpenDebugViewletAction.ID, OpenDebugViewletAction.LABEL, openViewletKb), 'View: Show Debug', nls.localize('view', "View"));
registry.registerWorkbenchAction(SyncActionDescriptor.create(OpenDebugViewletAction, OpenDebugViewletAction.ID, OpenDebugViewletAction.LABEL, openViewletKb), 'View: Show Run and Debug', nls.localize('view', "View"));
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DebugToolBar, LifecyclePhase.Restored);
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DebugContentProvider, LifecyclePhase.Eventually);

View File

@@ -125,7 +125,8 @@
font-style: italic;
}
.monaco-workbench .monaco-list-row .expression .error {
.monaco-workbench .monaco-list-row .expression .error,
.monaco-workbench .debug-pane .debug-variables .scope .error {
color: #e51400;
}
@@ -145,7 +146,8 @@
color: rgba(204, 204, 204, 0.6);
}
.vs-dark .monaco-workbench .monaco-list-row .expression .error {
.vs-dark .monaco-workbench .monaco-list-row .expression .error,
.vs-dark .monaco-workbench .debug-pane .debug-variables .scope .error {
color: #f48771;
}
@@ -173,7 +175,8 @@
color: #ce9178;
}
.hc-black .monaco-workbench .monaco-list-row .expression .error {
.hc-black .monaco-workbench .monaco-list-row .expression .error,
.hc-black .monaco-workbench .debug-pane .debug-variables .scope .error {
color: #f48771;
}

View File

@@ -316,6 +316,14 @@
animation-name: debugViewletValueChanged;
}
.debug-pane .debug-variables .scope .error {
font-style: italic;
text-overflow: ellipsis;
overflow: hidden;
font-family: var(--monaco-monospace-font);
font-weight: normal;
}
/* Breakpoints */
.debug-pane .monaco-list-row {

View File

@@ -9,7 +9,7 @@ import * as dom from 'vs/base/browser/dom';
import { CollapseAction } from 'vs/workbench/browser/viewlet';
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
import { IDebugService, IExpression, IScope, CONTEXT_VARIABLES_FOCUSED, IViewModel } from 'vs/workbench/contrib/debug/common/debug';
import { Variable, Scope } from 'vs/workbench/contrib/debug/common/debugModel';
import { Variable, Scope, ErrorScope } from 'vs/workbench/contrib/debug/common/debugModel';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { renderViewTree, renderVariable, IInputBoxOptions, AbstractExpressionsRenderer, IExpressionTemplateData } from 'vs/workbench/contrib/debug/browser/baseDebugView';
@@ -97,7 +97,7 @@ export class VariablesView extends ViewPane {
const treeContainer = renderViewTree(container);
this.tree = <WorkbenchAsyncDataTree<IViewModel | IExpression | IScope, IExpression | IScope, FuzzyScore>>this.instantiationService.createInstance(WorkbenchAsyncDataTree, 'VariablesView', treeContainer, new VariablesDelegate(),
[this.instantiationService.createInstance(VariablesRenderer), new ScopesRenderer()],
[this.instantiationService.createInstance(VariablesRenderer), new ScopesRenderer(), new ScopeErrorRenderer()],
new VariablesDataSource(), {
ariaLabel: nls.localize('variablesAriaTreeLabel', "Debug Variables"),
accessibilityProvider: new VariablesAccessibilityProvider(),
@@ -217,7 +217,7 @@ function isViewModel(obj: any): obj is IViewModel {
export class VariablesDataSource implements IAsyncDataSource<IViewModel, IExpression | IScope> {
hasChildren(element: IViewModel | IExpression | IScope): boolean {
if (isViewModel(element) || element instanceof Scope) {
if (isViewModel(element)) {
return true;
}
@@ -246,6 +246,10 @@ class VariablesDelegate implements IListVirtualDelegate<IExpression | IScope> {
}
getTemplateId(element: IExpression | IScope): string {
if (element instanceof ErrorScope) {
return ScopeErrorRenderer.ID;
}
if (element instanceof Scope) {
return ScopesRenderer.ID;
}
@@ -278,6 +282,33 @@ class ScopesRenderer implements ITreeRenderer<IScope, FuzzyScore, IScopeTemplate
}
}
interface IScopeErrorTemplateData {
error: HTMLElement;
}
class ScopeErrorRenderer implements ITreeRenderer<IScope, FuzzyScore, IScopeErrorTemplateData> {
static readonly ID = 'scopeError';
get templateId(): string {
return ScopeErrorRenderer.ID;
}
renderTemplate(container: HTMLElement): IScopeErrorTemplateData {
const wrapper = dom.append(container, $('.scope'));
const error = dom.append(wrapper, $('.error'));
return { error };
}
renderElement(element: ITreeNode<IScope, FuzzyScore>, index: number, templateData: IScopeErrorTemplateData): void {
templateData.error.innerText = element.element.name;
}
disposeTemplate(): void {
// noop
}
}
export class VariablesRenderer extends AbstractExpressionsRenderer {
static readonly ID = 'variable';

View File

@@ -190,9 +190,7 @@ export class WatchExpressionsView extends ViewPane {
this.debugService.getViewModel().setSelectedExpression(expression);
return Promise.resolve();
}));
if (!expression.hasChildren) {
actions.push(this.instantiationService.createInstance(CopyValueAction, CopyValueAction.ID, CopyValueAction.LABEL, expression.value, 'watch'));
}
actions.push(this.instantiationService.createInstance(CopyValueAction, CopyValueAction.ID, CopyValueAction.LABEL, expression.value, 'watch'));
actions.push(new Separator());
actions.push(new Action('debug.removeWatchExpression', nls.localize('removeWatchExpression', "Remove Expression"), undefined, true, () => {
@@ -204,9 +202,7 @@ export class WatchExpressionsView extends ViewPane {
actions.push(new AddWatchExpressionAction(AddWatchExpressionAction.ID, AddWatchExpressionAction.LABEL, this.debugService, this.keybindingService));
if (element instanceof Variable) {
const variable = element as Variable;
if (!variable.hasChildren) {
actions.push(this.instantiationService.createInstance(CopyValueAction, CopyValueAction.ID, CopyValueAction.LABEL, variable, 'watch'));
}
actions.push(this.instantiationService.createInstance(CopyValueAction, CopyValueAction.ID, CopyValueAction.LABEL, variable, 'watch'));
actions.push(new Separator());
}
actions.push(new RemoveAllWatchExpressionsAction(RemoveAllWatchExpressionsAction.ID, RemoveAllWatchExpressionsAction.LABEL, this.debugService, this.keybindingService));

View File

@@ -88,22 +88,26 @@ export class WelcomeView extends ViewPane {
const viewsRegistry = Registry.as<IViewsRegistry>(Extensions.ViewsRegistry);
viewsRegistry.registerViewWelcomeContent(WelcomeView.ID, {
content: localize('openAFileWhichCanBeDebugged', "[Open a file](command:{0}) which can be debugged or run.", isMacintosh ? OpenFileFolderAction.ID : OpenFileAction.ID),
content: localize({ key: 'openAFileWhichCanBeDebugged', comment: ['Please do not translate the word "commmand", it is part of our internal syntax which must not change'] },
"[Open a file](command:{0}) which can be debugged or run.", isMacintosh ? OpenFileFolderAction.ID : OpenFileAction.ID),
when: CONTEXT_DEBUGGER_INTERESTED_IN_ACTIVE_EDITOR.toNegated()
});
let debugKeybindingLabel = '';
viewsRegistry.registerViewWelcomeContent(WelcomeView.ID, {
content: localize('runAndDebugAction', "[Run and Debug{0}](command:{1})", debugKeybindingLabel, StartAction.ID),
content: localize({ key: 'runAndDebugAction', comment: ['Please do not translate the word "commmand", it is part of our internal syntax which must not change'] },
"[Run and Debug{0}](command:{1})", debugKeybindingLabel, StartAction.ID),
preconditions: [CONTEXT_DEBUGGER_INTERESTED_IN_ACTIVE_EDITOR]
});
viewsRegistry.registerViewWelcomeContent(WelcomeView.ID, {
content: localize('customizeRunAndDebug', "To customize Run and Debug [create a launch.json file](command:{0}).", ConfigureAction.ID),
content: localize({ key: 'customizeRunAndDebug', comment: ['Please do not translate the word "commmand", it is part of our internal syntax which must not change'] },
"To customize Run and Debug [create a launch.json file](command:{0}).", ConfigureAction.ID),
when: WorkbenchStateContext.notEqualsTo('empty')
});
viewsRegistry.registerViewWelcomeContent(WelcomeView.ID, {
content: localize('customizeRunAndDebugOpenFolder', "To customize Run and Debug, [open a folder](command:{0}) and create a launch.json file.", isMacintosh ? OpenFileFolderAction.ID : OpenFolderAction.ID),
content: localize({ key: 'customizeRunAndDebugOpenFolder', comment: ['Please do not translate the word "commmand", it is part of our internal syntax which must not change'] },
"To customize Run and Debug, [open a folder](command:{0}) and create a launch.json file.", isMacintosh ? OpenFileFolderAction.ID : OpenFolderAction.ID),
when: WorkbenchStateContext.isEqualTo('empty')
});

View File

@@ -301,6 +301,7 @@ export interface IScope extends IExpressionContainer {
readonly name: string;
readonly expensive: boolean;
readonly range?: IRange;
readonly hasChildren: boolean;
}
export interface IStackFrame extends ITreeElement {

View File

@@ -269,6 +269,21 @@ export class Scope extends ExpressionContainer implements IScope {
}
}
export class ErrorScope extends Scope {
constructor(
stackFrame: IStackFrame,
index: number,
message: string,
) {
super(stackFrame, index, message, 0, false);
}
toString(): string {
return this.name;
}
}
export class StackFrame implements IStackFrame {
private scopes: Promise<Scope[]> | undefined;
@@ -293,7 +308,7 @@ export class StackFrame implements IStackFrame {
return response && response.body && response.body.scopes ?
response.body.scopes.map((rs, index) => new Scope(this, index, rs.name, rs.variablesReference, rs.expensive, rs.namedVariables, rs.indexedVariables,
rs.line && rs.column && rs.endLine && rs.endColumn ? new Range(rs.line, rs.column, rs.endLine, rs.endColumn) : undefined)) : [];
}, err => []);
}, err => [new ErrorScope(this, 0, err.message)]);
}
return this.scopes;

View File

@@ -70,7 +70,9 @@ declare module DebugProtocol {
}
/** Cancel request; value of command field is 'cancel'.
The 'cancel' request is used by the frontend to indicate that it is no longer interested in the result produced by a specific request issued earlier.
The 'cancel' request is used by the frontend in two situations:
- to indicate that it is no longer interested in the result produced by a specific request issued earlier
- to cancel a progress indicator.
This request has a hint characteristic: a debug adapter can only be expected to make a 'best effort' in honouring this request but there are no guarantees.
The 'cancel' request may return an error if it could not cancel an operation but a frontend should refrain from presenting this error to end users.
A frontend client should only call this request if the capability 'supportsCancelRequest' is true.
@@ -85,8 +87,10 @@ declare module DebugProtocol {
/** Arguments for 'cancel' request. */
export interface CancelArguments {
/** The ID (attribute 'seq') of the request to cancel. */
/** The ID (attribute 'seq') of the request to cancel. If missing no request is cancelled. Both a 'requestId' and a 'progressId' can be specified in one request. */
requestId?: number;
/** The ID (attribute 'progressId') of the progress to cancel. If missing no progress is cancelled. Both a 'requestId' and a 'progressId' can be specified in one request. */
progressId?: string;
}
/** Response to 'cancel' request. This is just an acknowledgement, so no body field is required. */
@@ -302,6 +306,64 @@ declare module DebugProtocol {
};
}
/** Event message for 'progressStart' event type.
The event signals that a long running operation is about to start and
provides additional information for the client to set up a corresponding progress and cancellation UI.
The client is free to delay the showing of the UI in order to reduce flicker.
*/
export interface ProgressStartEvent extends Event {
// event: 'progressStart';
body: {
/** An ID that must be used in subsequent 'progressUpdate' and 'progressEnd' events to make them refer to the same progress reporting. IDs must be unique within a debug session. */
progressId: string;
/** Mandatory (short) title of the progress reporting. Shown in the UI to describe the long running operation. */
title: string;
/** The request ID that this progress report is related to. If specified a debug adapter is expected to emit
progress events for the long running request until the request has been either completed or cancelled.
If the request ID is omitted, the progress report is assumed to be related to some general activity of the debug adapter.
*/
requestId?: number;
/** If true, the request that reports progress may be canceled with a 'cancel' request.
So this property basically controls whether the client should use UX that supports cancellation.
Clients that don't support cancellation are allowed to ignore the setting.
*/
cancellable?: boolean;
/** Optional, more detailed progress message. */
message?: string;
/** Optional progress percentage to display (value range: 0 to 100). If omitted no percentage will be shown. */
percentage?: number;
};
}
/** Event message for 'progressUpdate' event type.
The event signals that the progress reporting needs to updated with a new message and/or percentage.
The client does not have to update the UI immediately, but the clients needs to keep track of the message and/or percentage values.
*/
export interface ProgressUpdateEvent extends Event {
// event: 'progressUpdate';
body: {
/** The ID that was introduced in the initial 'progressStart' event. */
progressId: string;
/** Optional, more detailed progress message. If omitted, the previous message (if any) is used. */
message?: string;
/** Optional progress percentage to display (value range: 0 to 100). If omitted no percentage will be shown. */
percentage?: number;
};
}
/** Event message for 'progressEnd' event type.
The event signals the end of the progress reporting with an optional final message.
*/
export interface ProgressEndEvent extends Event {
// event: 'progressEnd';
body: {
/** The ID that was introduced in the initial 'ProgressStartEvent'. */
progressId: string;
/** Optional, more detailed progress message. If omitted, the previous message (if any) is used. */
message?: string;
};
}
/** RunInTerminal request; value of command field is 'runInTerminal'.
This request is sent from the debug adapter to the client to run a command in a terminal. This is typically used to launch the debuggee in a terminal provided by the client.
*/
@@ -370,6 +432,8 @@ declare module DebugProtocol {
supportsRunInTerminalRequest?: boolean;
/** Client supports memory references. */
supportsMemoryReferences?: boolean;
/** Client supports progress reporting. */
supportsProgressReporting?: boolean;
}
/** Response to 'initialize' request. */
@@ -1100,6 +1164,7 @@ declare module DebugProtocol {
'watch': evaluate is run in a watch.
'repl': evaluate is run from REPL console.
'hover': evaluate is run from a data hover.
'clipboard': evaluate is run to generate the value that will be stored in the clipboard.
etc.
*/
context?: string;
@@ -1409,6 +1474,8 @@ declare module DebugProtocol {
supportsCancelRequest?: boolean;
/** The debug adapter supports the 'breakpointLocations' request. */
supportsBreakpointLocationsRequest?: boolean;
/** The debug adapter supports the 'clipboard' context value in the 'evaluate' request. */
supportsClipboardContext?: boolean;
}
/** An ExceptionBreakpointsFilter is shown in the UI as an option for configuring how exceptions are dealt with. */