vscode-chrome-debug-core
Version:
A library for building VS Code debug adapters for targets that support the Chrome Remote Debug Protocol
277 lines (276 loc) • 15.3 kB
TypeScript
import { DebugProtocol } from 'vscode-debugprotocol';
import { ICommonRequestArgs, ILaunchRequestArgs, ISetBreakpointsArgs, ISetBreakpointsResponseBody, IStackTraceResponseBody, IAttachRequestArgs, IScopesResponseBody, IVariablesResponseBody, ISourceResponseBody, IThreadsResponseBody, IEvaluateResponseBody, ISetVariableResponseBody, IDebugAdapter, ICompletionsResponseBody, IToggleSkipFileStatusArgs, IExceptionInfoResponseBody, ISetBreakpointResult, IRestartRequestArgs, IInitializeRequestArgs, ITelemetryPropertyCollector, IGetLoadedSourcesResponseBody } from '../debugAdapterInterfaces';
import { IChromeDebugAdapterOpts, ChromeDebugSession } from './chromeDebugSession';
import { ChromeConnection } from './chromeConnection';
import { Protocol as Crdp } from 'devtools-protocol';
import { IVariableContainer } from './variables';
import { ReasonType } from './stoppedEvent';
import { InternalSourceBreakpoint } from './internalSourceBreakpoint';
import { PromiseDefer } from '../utils';
import { StepProgressEventsEmitter } from '../executionTimingsReporter';
import { BasePathTransformer } from '../transformers/basePathTransformer';
import { BaseSourceMapTransformer } from '../transformers/baseSourceMapTransformer';
/**
* Represents a reference to a source/script. `contents` is set if there are inlined sources.
* Otherwise, scriptId can be used to retrieve the contents from the runtime.
*/
export interface ISourceContainer {
/** The runtime-side scriptId of this script */
scriptId?: Crdp.Runtime.ScriptId;
/** The contents of this script, if they are inlined in the sourcemap */
contents?: string;
/** The authored path to this script (only set if the contents are inlined) */
mappedPath?: string;
}
export interface IPendingBreakpoint {
args: ISetBreakpointsArgs;
ids: number[];
requestSeq: number;
setWithPath: string;
}
export declare type VariableContext = 'variables' | 'watch' | 'repl' | 'hover';
export declare type CrdpScript = Crdp.Debugger.ScriptParsedEvent;
export declare type CrdpDomain = string;
export declare type LoadedSourceEventReason = 'new' | 'changed' | 'removed';
export interface BreakpointSetResult {
isSet: boolean;
breakpoint: DebugProtocol.Breakpoint;
}
export interface IOnPausedResult {
didPause: boolean;
}
export declare abstract class ChromeDebugAdapter implements IDebugAdapter {
static EVAL_NAME_PREFIX: string;
static EVAL_ROOT: string;
private static SCRIPTS_COMMAND;
private static THREAD_ID;
private static SET_BREAKPOINTS_TIMEOUT;
private static HITCONDITION_MATCHER;
private static ASYNC_CALL_STACK_DEPTH;
protected _session: ChromeDebugSession;
protected _domains: Map<string, Crdp.Schema.Domain>;
private _clientAttached;
private _currentPauseNotification;
private _committedBreakpointsByUrl;
private _exception;
private _setBreakpointsRequestQ;
private _expectingResumedEvent;
protected _expectingStopReason: ReasonType;
private _waitAfterStep;
private _frameHandles;
private _variableHandles;
private _breakpointIdHandles;
private _sourceHandles;
private _scriptsById;
private _scriptsByUrl;
private _pendingBreakpointsByUrl;
private _hitConditionBreakpointsById;
private _lineColTransformer;
protected _chromeConnection: ChromeConnection;
protected _sourceMapTransformer: BaseSourceMapTransformer;
protected _pathTransformer: BasePathTransformer;
protected _hasTerminated: boolean;
protected _inShutdown: boolean;
protected _attachMode: boolean;
protected _launchAttachArgs: ICommonRequestArgs;
protected _port: number;
private _blackboxedRegexes;
private _skipFileStatuses;
private _currentStep;
private _currentLogMessage;
private _nextUnboundBreakpointId;
private _pauseOnPromiseRejections;
protected _promiseRejectExceptionFilterEnabled: boolean;
private _columnBreakpointsEnabled;
private _smartStepEnabled;
private _smartStepCount;
private _earlyScripts;
private _initialSourceMapsP;
private _lastPauseState;
private _breakOnLoadHelper;
private _sourceLoadedQueue;
private _scriptIdToBreakpointsAreResolvedDefer;
private _batchTelemetryReporter;
readonly events: StepProgressEventsEmitter;
private _loadedSourcesByScriptId;
private _isVSClient;
constructor({chromeConnection, lineColTransformer, sourceMapTransformer, pathTransformer, targetFilter, enableSourceMapCaching}: IChromeDebugAdapterOpts, session: ChromeDebugSession);
readonly chrome: Crdp.ProtocolApi;
readonly scriptsById: Map<Crdp.Runtime.ScriptId, CrdpScript>;
readonly pathTransformer: BasePathTransformer;
readonly pendingBreakpointsByUrl: Map<string, IPendingBreakpoint>;
readonly committedBreakpointsByUrl: Map<string, ISetBreakpointResult[]>;
readonly sourceMapTransformer: BaseSourceMapTransformer;
/**
* Called on 'clearEverything' or on a navigation/refresh
*/
protected clearTargetContext(): void;
initialize(args: IInitializeRequestArgs): DebugProtocol.Capabilities;
configurationDone(): Promise<void>;
readonly breakOnLoadActive: boolean;
launch(args: ILaunchRequestArgs, telemetryPropertyCollector?: ITelemetryPropertyCollector): Promise<void>;
attach(args: IAttachRequestArgs): Promise<void>;
protected commonArgs(args: ICommonRequestArgs): void;
shutdown(): void;
protected terminateSession(reason: string, disconnectArgs?: DebugProtocol.DisconnectArguments, restart?: IRestartRequestArgs): Promise<void>;
/**
* Hook up all connection events
*/
protected hookConnectionEvents(): void;
private runAndMeasureProcessingTime(notificationName, procedure);
/**
* Enable clients and run connection
*/
protected runConnection(): Promise<void>[];
protected doAttach(port: number, targetUrl?: string, address?: string, timeout?: number, websocketUrl?: string, extraCRDPChannelPort?: number): Promise<void>;
private initSupportedDomains();
/**
* This event tells the client to begin sending setBP requests, etc. Some consumers need to override this
* to send it at a later time of their choosing.
*/
protected sendInitializedEvent(): Promise<void>;
doAfterProcessingSourceEvents(action: () => void): Promise<void>;
/**
* e.g. the target navigated
*/
protected onExecutionContextsCleared(): Promise<void>;
protected onPaused(notification: Crdp.Debugger.PausedEvent, expectingStopReason?: ReasonType): Promise<IOnPausedResult>;
exceptionInfo(args: DebugProtocol.ExceptionInfoArguments): Promise<IExceptionInfoResponseBody>;
private shouldSmartStep(frame);
protected onResumed(): void;
private detectColumnBreakpointSupport(scriptId);
getBreakpointsResolvedDefer(scriptId: string): PromiseDefer<void>;
protected onScriptParsed(script: Crdp.Debugger.ScriptParsedEvent): Promise<void>;
protected sendLoadedSourceEvent(script: Crdp.Debugger.ScriptParsedEvent, loadedSourceEventReason?: LoadedSourceEventReason): Promise<void>;
private resolveSkipFiles(script, mappedUrl, sources, toggling?);
private warnNoSkipFiles();
/**
* If the source has a saved skip status, return that, whether true or false.
* If not, check it against the patterns list.
*/
private shouldSkipSource(sourcePath);
/**
* Returns true if this path matches one of the static skip patterns
*/
private matchesSkipFilesPatterns(sourcePath);
/**
* Returns the current skip status for this path, which is either an authored or generated script.
*/
private getSkipStatus(sourcePath);
toggleSmartStep(): Promise<void>;
toggleSkipFileStatus(args: IToggleSkipFileStatusArgs): Promise<void>;
private isInCurrentStack(args);
private makeRegexesNotSkip(noSkipPath);
private makeRegexesSkip(skipPath);
private refreshBlackboxPatterns();
loadedSources(args: DebugProtocol.LoadedSourcesArguments): Promise<IGetLoadedSourcesResponseBody>;
resolvePendingBreakpoint(pendingBP: IPendingBreakpoint): Promise<void>;
protected onBreakpointResolved(params: Crdp.Debugger.BreakpointResolvedEvent): void;
protected onConsoleAPICalled(event: Crdp.Runtime.ConsoleAPICalledEvent): void;
private onLogEntryAdded(event);
private logObjects(objs, isError?, stackTrace?);
protected onExceptionThrown(params: Crdp.Runtime.ExceptionThrownEvent): Promise<void>;
private mapCallFrame(frame);
protected mapFormattedException(formattedException: string): Promise<string>;
/**
* For backcompat, also listen to Console.messageAdded, only if it looks like the old format.
*/
protected onMessageAdded(params: any): void;
disconnect(args: DebugProtocol.DisconnectArguments): void;
setBreakpoints(args: ISetBreakpointsArgs, _: ITelemetryPropertyCollector, requestSeq: number, ids?: number[]): Promise<ISetBreakpointsResponseBody>;
private reportBpTelemetry(args);
protected validateBreakpointsPath(args: ISetBreakpointsArgs): Promise<void>;
private generateNextUnboundBreakpointId();
private unverifiedBpResponse(args, requestSeq, targetScriptUrl, message?, bpsSet?);
private unverifiedBpResponseForBreakpoints(args, requestSeq, targetScriptUrl, breakpoints, defaultMessage?, bpsSet?);
private clearAllBreakpoints(url);
/**
* Makes the actual call to either Debugger.setBreakpoint or Debugger.setBreakpointByUrl, and returns the response.
* Responses from setBreakpointByUrl are transformed to look like the response from setBreakpoint, so they can be
* handled the same.
*/
protected addBreakpoints(url: string, breakpoints: InternalSourceBreakpoint[]): Promise<ISetBreakpointResult[]>;
private addOneBreakpointByUrl(scriptId, urlRegex, lineNumber, columnNumber, condition);
private targetBreakpointResponsesToBreakpointSetResults(url, responses, requestBps, ids?);
private addHitConditionBreakpoint(requestBp, response);
setExceptionBreakpoints(args: DebugProtocol.SetExceptionBreakpointsArguments): Promise<void>;
/**
* internal -> suppress telemetry
*/
continue(internal?: boolean): Promise<void>;
next(): Promise<void>;
stepIn(userInitiated?: boolean): Promise<void>;
stepOut(): Promise<void>;
stepBack(): Promise<void>;
reverseContinue(): Promise<void>;
pause(): Promise<void>;
stackTrace(args: DebugProtocol.StackTraceArguments): Promise<IStackTraceResponseBody>;
private asyncFrames(stackTrace);
private runtimeCFToDebuggerCF(frame);
private scriptToSource(script);
private formatStackFrameName(frame, formatArgs?);
private callFrameToStackFrame(frame);
protected getReadonlyOrigin(url: string): string;
/**
* Called when returning a stack trace, for the path for Sources that have a sourceReference, so consumers can
* tweak it, since it's only for display.
*/
protected realPathToDisplayPath(realPath: string): string;
protected displayPathToRealPath(displayPath: string): string;
/**
* Get the existing handle for this script, identified by runtime scriptId, or create a new one
*/
private getSourceReferenceForScriptId(scriptId);
scopes(args: DebugProtocol.ScopesArguments): IScopesResponseBody;
/**
* Try to lookup the index of the frame with given ID. Returns -1 for async frames and unknown frames.
*/
private lookupFrameIndex(frameId);
variables(args: DebugProtocol.VariablesArguments): Promise<IVariablesResponseBody>;
propertyDescriptorToVariable(propDesc: Crdp.Runtime.PropertyDescriptor, owningObjectId?: string, parentEvaluateName?: string): Promise<DebugProtocol.Variable>;
getVariablesForObjectId(objectId: string, evaluateName?: string, filter?: string, start?: number, count?: number): Promise<DebugProtocol.Variable[]>;
private getRuntimeProperties(params);
private internalPropertyDescriptorToVariable(propDesc, parentEvaluateName);
private getFilteredVariablesForObject(objectId, evaluateName, filter, start, count);
private getFilteredVariablesForObjectId(objectId, evaluateName, getVarsFn, filter, start, count);
source(args: DebugProtocol.SourceArguments): Promise<ISourceResponseBody>;
threads(): IThreadsResponseBody;
protected threadName(): string;
evaluate(args: DebugProtocol.EvaluateArguments): Promise<IEvaluateResponseBody>;
/**
* Handle the .scripts command, which can be used as `.scripts` to return a list of all script details,
* or `.scripts <url>` to show the contents of the given script.
*/
private handleScriptsCommand(args);
private getAllScriptsString();
private getOneScriptString(runtimeScriptPath);
/**
* Allow consumers to override just because of https://github.com/nodejs/node/issues/8426
*/
protected globalEvaluate(args: Crdp.Runtime.EvaluateRequest): Promise<Crdp.Runtime.EvaluateResponse>;
private waitThenDoEvaluate(expression, frameId?, extraArgs?);
private doEvaluate(expression, frameId?, extraArgs?);
protected evaluateOnCallFrame(expression: string, frame: Crdp.Debugger.CallFrame, extraArgs?: Partial<Crdp.Runtime.EvaluateRequest>): Promise<Crdp.Debugger.EvaluateOnCallFrameResponse | Crdp.Runtime.EvaluateResponse>;
setVariable(args: DebugProtocol.SetVariableArguments): Promise<ISetVariableResponseBody>;
setVariableValue(callFrameId: string, scopeNumber: number, variableName: string, value: string): Promise<string>;
setPropertyValue(objectId: string, propName: string, value: string): Promise<string>;
remoteObjectToVariable(name: string, object: Crdp.Runtime.RemoteObject, parentEvaluateName?: string, stringify?: boolean, context?: VariableContext): Promise<DebugProtocol.Variable>;
createFunctionVariable(name: string, object: Crdp.Runtime.RemoteObject, context: VariableContext, parentEvaluateName?: string): DebugProtocol.Variable;
createObjectVariable(name: string, object: Crdp.Runtime.RemoteObject, parentEvaluateName: string, context: VariableContext): Promise<DebugProtocol.Variable>;
protected createPropertyContainer(object: Crdp.Runtime.RemoteObject, evaluateName: string): IVariableContainer;
createPrimitiveVariable(name: string, object: Crdp.Runtime.RemoteObject, parentEvaluateName?: string, stringify?: boolean): DebugProtocol.Variable;
createPrimitiveVariableWithValue(name: string, value: string, parentEvaluateName?: string): DebugProtocol.Variable;
restartFrame(args: DebugProtocol.RestartFrameArguments): Promise<void>;
completions(args: DebugProtocol.CompletionsArguments): Promise<ICompletionsResponseBody>;
private getFlatAndUniqueCompletionItems(arrays);
private getArrayNumPropsByEval(objectId);
private getBufferNumPropsByEval(objectId);
private getArrayNumPropsByPreview(object);
private getCollectionNumPropsByEval(objectId);
private getCollectionNumPropsByPreview(object);
private getNumPropsByEval(objectId, getNumPropsFn);
private fakeUrlForSourceReference(sourceReference);
private displayNameForSourceReference(sourceReference);
private displayNameForScriptId(scriptId);
private getScriptByUrl(url);
}