import type { BSDebugDiagnostic } from '../CompileErrorProcessor'; import type { RendezvousHistory, RendezvousTracker } from '../RendezvousTracker'; import type { ChanperfData } from '../ChanperfTracker'; import type { AdapterOptions, HighLevelType, RokuAdapterEvaluateResponse } from '../interfaces'; import type { BreakpointManager } from '../managers/BreakpointManager'; import type { ProjectManager } from '../managers/ProjectManager'; import type { BreakpointsVerifiedEvent, ConstructorOptions, ProtocolVersionDetails } from '../debugProtocol/client/DebugProtocolClient'; import type { TelnetAdapter } from './TelnetAdapter'; import type { DeviceInfo } from 'roku-deploy'; import type { ExceptionBreakpoint } from '../debugProtocol/events/requests/SetExceptionBreakpointsRequest'; import type { DebugProtocol } from '@vscode/debugprotocol'; /** * A class that connects to a Roku device over telnet debugger port and provides a standardized way of interacting with it. */ export declare class DebugProtocolAdapter { private options; private projectManager; private breakpointManager; private rendezvousTracker; private deviceInfo; constructor(options: AdapterOptions & ConstructorOptions, projectManager: ProjectManager, breakpointManager: BreakpointManager, rendezvousTracker: RendezvousTracker, deviceInfo: DeviceInfo); private logger; /** * Capabilities seeded from the device-info `brightscript-debugger-version`. Used as the * source of truth for protocol capability questions before the debug protocol client has * connected and completed its handshake. */ private fallbackCapabilities; /** * The current authoritative capabilities for protocol-version-driven questions: the live * client's capabilities once it exists, otherwise the device-info-seeded fallback. */ private get capabilities(); /** * Indicates whether the adapter has successfully established a connection with the device */ connected: boolean; private compileClient; private compileErrorProcessor; private emitter; private chanperfTracker; private client; private nextFrameId; private stackFramesCache; private cache; /** * Get the version of the protocol for the Roku device we're currently connected to. */ get activeProtocolVersion(): string; /** * Subscribe to an event exactly once * @param eventName */ once(eventName: 'cannot-continue'): Promise; once(eventname: 'chanperf'): Promise; once(eventName: 'close'): Promise; once(eventName: 'app-exit'): Promise; once(eventName: 'app-ready'): Promise; once(eventName: 'diagnostics'): Promise; once(eventName: 'connected'): Promise; once(eventname: 'console-output'): Promise; once(eventname: 'protocol-version'): Promise; once(eventname: 'rendezvous'): Promise; once(eventName: 'runtime-error'): Promise; once(eventName: 'suspend'): Promise; once(eventName: 'start'): Promise; once(eventname: 'device-unresponsive'): Promise; once(eventname: 'unhandled-console-output'): Promise; /** * Subscribe to various events * @param eventName * @param handler */ on(eventName: 'breakpoints-verified', handler: (event: BreakpointsVerifiedEvent) => any): any; on(eventName: 'cannot-continue', handler: () => any): any; on(eventname: 'chanperf', handler: (output: ChanperfData) => any): any; on(eventName: 'close', handler: () => any): any; on(eventName: 'app-exit', handler: () => any): any; on(eventName: 'diagnostics', handler: (params: BSDebugDiagnostic[]) => any): any; on(eventName: 'launch-status', handler: (message: string) => any): any; on(eventName: 'connected', handler: (params: boolean) => any): any; on(eventname: 'console-output', handler: (output: string) => any): any; on(eventname: 'protocol-version', handler: (output: ProtocolVersionDetails) => any): any; on(eventName: 'runtime-error', handler: (error: BrightScriptRuntimeError) => any): any; on(eventName: 'suspend', handler: () => any): any; on(eventName: 'start', handler: () => any): any; on(eventName: 'waiting-for-debugger', handler: () => any): any; on(eventName: 'device-unresponsive', handler: (data: { lastCommand: string; }) => any): any; on(eventname: 'unhandled-console-output', handler: (output: string) => any): any; private emit; /** * Does the current client support exception breakpoints? Resolved via the live client's * capabilities when connected, otherwise the device-info-seeded fallback. */ get supportsExceptionBreakpoints(): boolean; /** * Does the current client support conditional breakpoints? Same fallback semantics as * `supportsExceptionBreakpoints`. */ get supportsConditionalBreakpoints(): boolean; /** * Does the current client support hit-count breakpoints? */ get supportsHitConditionalBreakpoints(): boolean; /** * The debugger needs to tell us when to be active (i.e. when the package was deployed) */ isActivated: boolean; /** * This will be set to true When the roku emits the [scrpt.ctx.run.enter] text, * which indicates that the app is running on the Roku */ isAppRunning: boolean; activate(): void; sendErrors(): Promise; private handleStartupIfReady; /** * Wait until the client has stopped sending messages. This is used mainly during .connect so we can ignore all old messages from the server * @param client * @param maxWaitMilliseconds */ private settleCompileClient; get isAtDebuggerPrompt(): boolean; private firstConnectDeferred; /** * Resolves when the first connection to the client is established */ onReady(): Promise; /** * Connect to the telnet session. This should be called before the channel is launched. */ connect(): Promise; createDebugProtocolClient(): Promise; private beginAppExit; /** * Determines if the current version of the debug protocol supports emitting compile error updates. */ get supportsCompileErrorReporting(): boolean; /** * Indicate if virtual variables should be auto resolved when they are encountered. */ get autoResolveVirtualVariables(): boolean; private processingTelnetOutput; processTelnetOutput(): Promise; private findWaitForDebuggerPrompt; /** * Send command to step over */ stepOver(threadId: number): Promise; stepInto(threadId: number): Promise; stepOut(threadId: number): Promise; /** * Tell the brightscript program to continue (i.e. resume program) */ continue(): Promise; /** * Tell the brightscript program to pause (fall into debug mode) */ pause(): Promise; /** * Clears the state, which means that everything will be retrieved fresh next time it is requested */ clearCache(): void; /** * Execute a command directly on the roku. Returns the output of the command * @param command * @returns the output of the command (if possible) */ evaluate(command: string, frameId?: number): Promise; getStackTrace(threadIndex?: number): Promise; getStackFrameById(frameId: number): StackFrame; private cleanUpFunctionName; /** * Get info about the specified variable. * @param expression the expression for the specified variable (i.e. `m`, `someVar.value`, `arr[1][2].three`). If empty string/undefined is specified, all local variables are retrieved instead */ private getVariablesResponse; /** * Get the variable for the specified expression. */ getVariable(expression: string, frameId: number): Promise; /** * Get the list of local variables */ getLocalVariables(frameId: number): Promise; /** * Create an EvaluateContainer for the given variable. If the variable has children, those are created and attached as well * @param variable a Variable object from the debug protocol debugger * @param name the name of this variable. For example, `alpha.beta.charlie`, this value would be `charlie`. For local vars, this is the root variable name (i.e. `alpha`) * @param parentEvaluateName the string used to derive the parent, _excluding_ this variable's name (i.e. `alpha.beta` or `alpha[0]`) */ private createEvaluateContainer; /** * Cache items by a unique key * @param expression * @param factory */ private resolve; /** * Get a list of threads. The active thread will always be first in the list. */ getThreads(): Promise; private getThreadByThreadId; removeAllListeners(): void; /** * Indicates whether this class had `.destroy()` called at least once. Mostly used for checking externally to see if * the whole debug session has been terminated or is in a bad state. */ isDestroyed: boolean; /** * Disconnect from the telnet session and unset all objects */ destroy(): Promise; /** * Promise that is resolved when the compile client socket is closed */ private compileClientClosed; private isDestroyingCompileClient; private destroyCompileClient; /** * Passes the log level down to the RendezvousTracker and ChanperfTracker * @param outputLevel the consoleOutput from the launch config */ setConsoleOutput(outputLevel: string): void; /** * Sends a call to the RendezvousTracker to clear the current rendezvous history */ clearRendezvousHistory(): void; /** * Sends a call to the ChanperfTracker to clear the current chanperf history */ clearChanperfHistory(): void; /** * The most recently requested exception breakpoint filters. Stored so we can replay them * to the debug protocol client once it connects (the session can send these before the * device has launched and the client has finished its handshake). */ private pendingExceptionBreakpointFilters; setExceptionBreakpoints(filters: ExceptionBreakpoint[]): Promise; private syncBreakpointsPromise; syncBreakpoints(): Promise; _syncBreakpoints(): Promise; isTelnetAdapter(): this is TelnetAdapter; isDebugProtocolAdapter(): this is DebugProtocolAdapter; } export interface StackFrame { frameId: number; frameIndex: number; threadIndex: number; filePath: string; lineNumber: number; functionIdentifier: string; } export declare enum EventName { suspend = "suspend" } export interface EvaluateContainer { name: string; evaluateName: string; type: string; value?: any; keyType?: KeyType; namedVariables?: number; indexedVariables?: number; highLevelType?: HighLevelType; children: EvaluateContainer[]; isCustom?: boolean; evaluateNow?: boolean; presentationHint?: DebugProtocol.VariablePresentationHint; } export declare enum KeyType { string = "String", integer = "Integer", legacy = "Legacy" } export interface Thread { isSelected: boolean; isDetached?: boolean; /** * The 1-based line number for the thread */ lineNumber: number; filePath: string; functionName: string; lineContents: string; threadId: number; osThreadId?: string; name?: string; type?: string; } interface BrightScriptRuntimeError { message: string; errorCode: string; } export {};