mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-25 14:20:30 -04:00
Refresh master with initial release/0.24 snapshot (#332)
* Initial port of release/0.24 source code * Fix additional headers * Fix a typo in launch.json
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import uri from 'vs/base/common/uri';
|
||||
import * as paths from 'vs/base/common/paths';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as lifecycle from 'vs/base/common/lifecycle';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
@@ -19,7 +19,7 @@ import { Range, IRange } from 'vs/editor/common/core/range';
|
||||
import { ISuggestion } from 'vs/editor/common/modes';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import {
|
||||
ITreeElement, IExpression, IExpressionContainer, IProcess, IStackFrame, IExceptionBreakpoint, IBreakpoint, IFunctionBreakpoint, IModel,
|
||||
ITreeElement, IExpression, IExpressionContainer, IProcess, IStackFrame, IExceptionBreakpoint, IBreakpoint, IFunctionBreakpoint, IModel, IReplElementSource,
|
||||
IConfig, ISession, IThread, IRawModelUpdate, IScope, IRawStoppedDetails, IEnablement, IRawBreakpoint, IExceptionInfo, IReplElement, ProcessState
|
||||
} from 'vs/workbench/parts/debug/common/debug';
|
||||
import { Source } from 'vs/workbench/parts/debug/common/debugSource';
|
||||
@@ -27,28 +27,28 @@ import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/edi
|
||||
|
||||
const MAX_REPL_LENGTH = 10000;
|
||||
|
||||
export abstract class AbstractOutputElement implements IReplElement {
|
||||
export abstract class AbstractReplElement implements IReplElement {
|
||||
private static ID_COUNTER = 0;
|
||||
|
||||
constructor(private id = AbstractOutputElement.ID_COUNTER++) {
|
||||
constructor(public sourceData: IReplElementSource, private id = AbstractReplElement.ID_COUNTER++) {
|
||||
// noop
|
||||
}
|
||||
|
||||
public getId(): string {
|
||||
return `outputelement:${this.id}`;
|
||||
return `replelement:${this.id}`;
|
||||
}
|
||||
|
||||
abstract toString(): string;
|
||||
}
|
||||
|
||||
export class OutputElement extends AbstractOutputElement {
|
||||
|
||||
export class SimpleReplElement extends AbstractReplElement {
|
||||
|
||||
constructor(
|
||||
public value: string,
|
||||
public severity: severity,
|
||||
source: IReplElementSource,
|
||||
) {
|
||||
super();
|
||||
super(source);
|
||||
}
|
||||
|
||||
public toString(): string {
|
||||
@@ -56,12 +56,12 @@ export class OutputElement extends AbstractOutputElement {
|
||||
}
|
||||
}
|
||||
|
||||
export class OutputNameValueElement extends AbstractOutputElement implements IExpression {
|
||||
export class RawObjectReplElement extends AbstractReplElement implements IExpression {
|
||||
|
||||
private static MAX_CHILDREN = 1000; // upper bound of children per value
|
||||
|
||||
constructor(public name: string, public valueObj: any, public annotation?: string) {
|
||||
super();
|
||||
constructor(public name: string, public valueObj: any, source?: IReplElementSource, public annotation?: string) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
public get value(): string {
|
||||
@@ -85,11 +85,11 @@ export class OutputNameValueElement extends AbstractOutputElement implements IEx
|
||||
public getChildren(): TPromise<IExpression[]> {
|
||||
let result: IExpression[] = [];
|
||||
if (Array.isArray(this.valueObj)) {
|
||||
result = (<any[]>this.valueObj).slice(0, OutputNameValueElement.MAX_CHILDREN)
|
||||
.map((v, index) => new OutputNameValueElement(String(index), v));
|
||||
result = (<any[]>this.valueObj).slice(0, RawObjectReplElement.MAX_CHILDREN)
|
||||
.map((v, index) => new RawObjectReplElement(String(index), v));
|
||||
} else if (isObject(this.valueObj)) {
|
||||
result = Object.getOwnPropertyNames(this.valueObj).slice(0, OutputNameValueElement.MAX_CHILDREN)
|
||||
.map(key => new OutputNameValueElement(key, this.valueObj[key]));
|
||||
result = Object.getOwnPropertyNames(this.valueObj).slice(0, RawObjectReplElement.MAX_CHILDREN)
|
||||
.map(key => new RawObjectReplElement(key, this.valueObj[key]));
|
||||
}
|
||||
|
||||
return TPromise.as(result);
|
||||
@@ -184,7 +184,7 @@ export class ExpressionContainer implements IExpressionContainer {
|
||||
}
|
||||
|
||||
private fetchVariables(start: number, count: number, filter: 'indexed' | 'named'): TPromise<Variable[]> {
|
||||
return this.process.session.variables({
|
||||
return this.process.state !== ProcessState.INACTIVE ? this.process.session.variables({
|
||||
variablesReference: this.reference,
|
||||
start,
|
||||
count,
|
||||
@@ -193,7 +193,7 @@ export class ExpressionContainer implements IExpressionContainer {
|
||||
return response && response.body && response.body.variables ? distinct(response.body.variables.filter(v => !!v && v.name), v => v.name).map(
|
||||
v => new Variable(this.process, this, v.variablesReference, v.name, v.evaluateName, v.value, v.namedVariables, v.indexedVariables, v.type)
|
||||
) : [];
|
||||
}, (e: Error) => [new Variable(this.process, this, 0, null, e.message, '', 0, 0, null, false)]);
|
||||
}, (e: Error) => [new Variable(this.process, this, 0, null, e.message, '', 0, 0, null, false)]) : TPromise.as([]);
|
||||
}
|
||||
|
||||
// The adapter explicitly sents the children count of an expression only if there are lots of children which should be chunked.
|
||||
@@ -282,7 +282,7 @@ export class Variable extends ExpressionContainer implements IExpression {
|
||||
public available = true,
|
||||
startOfVariables = 0
|
||||
) {
|
||||
super(process, reference, `variable:${parent.getId()}:${name}:${reference}`, namedVariables, indexedVariables, startOfVariables);
|
||||
super(process, reference, `variable:${parent.getId()}:${name}`, namedVariables, indexedVariables, startOfVariables);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -313,6 +313,7 @@ export class Scope extends ExpressionContainer implements IScope {
|
||||
|
||||
constructor(
|
||||
stackFrame: IStackFrame,
|
||||
index: number,
|
||||
public name: string,
|
||||
reference: number,
|
||||
public expensive: boolean,
|
||||
@@ -320,7 +321,7 @@ export class Scope extends ExpressionContainer implements IScope {
|
||||
indexedVariables: number,
|
||||
public range?: IRange
|
||||
) {
|
||||
super(stackFrame.thread.process, reference, `scope:${stackFrame.getId()}:${name}:${reference}`, namedVariables, indexedVariables);
|
||||
super(stackFrame.thread.process, reference, `scope:${stackFrame.getId()}:${name}:${index}`, namedVariables, indexedVariables);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,7 +349,7 @@ export class StackFrame implements IStackFrame {
|
||||
if (!this.scopes) {
|
||||
this.scopes = this.thread.process.session.scopes({ frameId: this.frameId }).then(response => {
|
||||
return response && response.body && response.body.scopes ?
|
||||
response.body.scopes.map(rs => new Scope(this, rs.name, rs.variablesReference, rs.expensive, rs.namedVariables, rs.indexedVariables,
|
||||
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) : null)) : [];
|
||||
}, err => []);
|
||||
}
|
||||
@@ -379,18 +380,8 @@ export class StackFrame implements IStackFrame {
|
||||
}
|
||||
|
||||
public openInEditor(editorService: IWorkbenchEditorService, preserveFocus?: boolean, sideBySide?: boolean): TPromise<any> {
|
||||
|
||||
return !this.source.available ? TPromise.as(null) : editorService.openEditor({
|
||||
resource: this.source.uri,
|
||||
description: this.source.origin,
|
||||
options: {
|
||||
preserveFocus,
|
||||
selection: this.range,
|
||||
revealIfVisible: true,
|
||||
revealInCenterIfOutsideViewport: true,
|
||||
pinned: !preserveFocus && !this.source.inMemory
|
||||
}
|
||||
}, sideBySide);
|
||||
return !this.source.available ? TPromise.as(null) :
|
||||
this.source.openInEditor(editorService, this.range, preserveFocus, sideBySide);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,12 +450,7 @@ export class Thread implements IThread {
|
||||
}
|
||||
|
||||
return response.body.stackFrames.map((rsf, index) => {
|
||||
let source = new Source(rsf.source);
|
||||
if (this.process.sources.has(source.uri.toString())) {
|
||||
source = this.process.sources.get(source.uri.toString());
|
||||
} else {
|
||||
this.process.sources.set(source.uri.toString(), source);
|
||||
}
|
||||
const source = this.process.getSource(rsf.source);
|
||||
|
||||
return new StackFrame(this, rsf.id, source, rsf.name, rsf.presentationHint, new Range(
|
||||
rsf.line,
|
||||
@@ -545,7 +531,7 @@ export class Process implements IProcess {
|
||||
|
||||
public sources: Map<string, Source>;
|
||||
private threads: Map<number, Thread>;
|
||||
private inactive = true;
|
||||
public inactive = true;
|
||||
|
||||
constructor(public configuration: IConfig, private _session: ISession & ITreeElement) {
|
||||
this.threads = new Map<number, Thread>();
|
||||
@@ -558,7 +544,7 @@ export class Process implements IProcess {
|
||||
}
|
||||
|
||||
public getName(includeRoot: boolean): string {
|
||||
return includeRoot ? `${this.configuration.name} (${paths.basename(this.session.root.fsPath)})` : this.configuration.name;
|
||||
return includeRoot ? `${this.configuration.name} (${resources.basenameOrAuthority(this.session.root.uri)})` : this.configuration.name;
|
||||
}
|
||||
|
||||
public get state(): ProcessState {
|
||||
@@ -569,12 +555,23 @@ export class Process implements IProcess {
|
||||
return this.configuration.type === 'attach' ? ProcessState.ATTACH : ProcessState.LAUNCH;
|
||||
}
|
||||
|
||||
public getSource(raw: DebugProtocol.Source): Source {
|
||||
let source = new Source(raw, this.getId());
|
||||
if (this.sources.has(source.uri.toString())) {
|
||||
source = this.sources.get(source.uri.toString());
|
||||
} else {
|
||||
this.sources.set(source.uri.toString(), source);
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
public getThread(threadId: number): Thread {
|
||||
return this.threads.get(threadId);
|
||||
}
|
||||
|
||||
public getAllThreads(): IThread[] {
|
||||
const result = [];
|
||||
const result: IThread[] = [];
|
||||
this.threads.forEach(t => result.push(t));
|
||||
return result;
|
||||
}
|
||||
@@ -596,7 +593,7 @@ export class Process implements IProcess {
|
||||
if (data.stoppedDetails) {
|
||||
// Set the availability of the threads' callstacks depending on
|
||||
// whether the thread is stopped or not
|
||||
if (data.allThreadsStopped) {
|
||||
if (data.stoppedDetails.allThreadsStopped) {
|
||||
this.threads.forEach(thread => {
|
||||
thread.stoppedDetails = thread.threadId === data.threadId ? data.stoppedDetails : { reason: undefined };
|
||||
thread.stopped = true;
|
||||
@@ -613,7 +610,7 @@ export class Process implements IProcess {
|
||||
}
|
||||
|
||||
public clearThreads(removeThreads: boolean, reference: number = undefined): void {
|
||||
if (reference) {
|
||||
if (reference !== undefined && reference !== null) {
|
||||
if (this.threads.has(reference)) {
|
||||
const thread = this.threads.get(reference);
|
||||
thread.clearCallStack();
|
||||
@@ -685,6 +682,7 @@ export class Breakpoint implements IBreakpoint {
|
||||
public enabled: boolean,
|
||||
public condition: string,
|
||||
public hitCondition: string,
|
||||
public adapterData: any
|
||||
) {
|
||||
if (enabled === undefined) {
|
||||
this.enabled = true;
|
||||
@@ -865,12 +863,16 @@ export class Model implements IModel {
|
||||
this._onDidChangeBreakpoints.fire();
|
||||
}
|
||||
|
||||
public addBreakpoints(uri: uri, rawData: IRawBreakpoint[]): void {
|
||||
this.breakpoints = this.breakpoints.concat(rawData.map(rawBp =>
|
||||
new Breakpoint(uri, rawBp.lineNumber, rawBp.column, rawBp.enabled, rawBp.condition, rawBp.hitCondition)));
|
||||
public addBreakpoints(uri: uri, rawData: IRawBreakpoint[], fireEvent = true): Breakpoint[] {
|
||||
const newBreakpoints = rawData.map(rawBp => new Breakpoint(uri, rawBp.lineNumber, rawBp.column, rawBp.enabled, rawBp.condition, rawBp.hitCondition, undefined));
|
||||
this.breakpoints = this.breakpoints.concat(newBreakpoints);
|
||||
this.breakpointsActivated = true;
|
||||
this.breakpoints = distinct(this.breakpoints, bp => `${bp.uri.toString()}:${bp.lineNumber}:${bp.column}`);
|
||||
this._onDidChangeBreakpoints.fire();
|
||||
if (fireEvent) {
|
||||
this._onDidChangeBreakpoints.fire();
|
||||
}
|
||||
|
||||
return newBreakpoints;
|
||||
}
|
||||
|
||||
public removeBreakpoints(toRemove: IBreakpoint[]): void {
|
||||
@@ -889,6 +891,7 @@ export class Model implements IModel {
|
||||
bp.verified = bpData.verified;
|
||||
bp.idFromAdapter = bpData.id;
|
||||
bp.message = bpData.message;
|
||||
bp.adapterData = bpData.source ? bpData.source.adapterData : bp.adapterData;
|
||||
}
|
||||
});
|
||||
this.breakpoints = distinct(this.breakpoints, bp => `${bp.uri.toString()}:${bp.lineNumber}:${bp.column}`);
|
||||
@@ -913,7 +916,6 @@ export class Model implements IModel {
|
||||
bp.verified = false;
|
||||
}
|
||||
});
|
||||
this.exceptionBreakpoints.forEach(ebp => ebp.enabled = enable);
|
||||
this.functionBreakpoints.forEach(fbp => fbp.enabled = enable);
|
||||
|
||||
this._onDidChangeBreakpoints.fire();
|
||||
@@ -954,23 +956,23 @@ export class Model implements IModel {
|
||||
.then(() => this._onDidChangeREPLElements.fire());
|
||||
}
|
||||
|
||||
public appendToRepl(output: string | IExpression, severity: severity): void {
|
||||
if (typeof output === 'string') {
|
||||
const previousOutput = this.replElements.length && (this.replElements[this.replElements.length - 1] as OutputElement);
|
||||
public appendToRepl(data: string | IExpression, severity: severity, source?: IReplElementSource): void {
|
||||
if (typeof data === 'string') {
|
||||
const previousElement = this.replElements.length && (this.replElements[this.replElements.length - 1] as SimpleReplElement);
|
||||
|
||||
const toAdd = output.split('\n').map(line => new OutputElement(line, severity));
|
||||
if (previousOutput instanceof OutputElement && severity === previousOutput.severity && toAdd.length) {
|
||||
previousOutput.value += toAdd.shift().value;
|
||||
}
|
||||
if (previousOutput && previousOutput.value === '' && previousOutput.severity !== severity) {
|
||||
// remove potential empty lines between different output types
|
||||
const toAdd = data.split('\n').map((line, index) => new SimpleReplElement(line, severity, index === 0 ? source : undefined));
|
||||
if (previousElement && previousElement.value === '') {
|
||||
// remove potential empty lines between different repl types
|
||||
this.replElements.pop();
|
||||
} else if (previousElement instanceof SimpleReplElement && severity === previousElement.severity && toAdd.length && toAdd[0].sourceData === previousElement.sourceData) {
|
||||
previousElement.value += toAdd.shift().value;
|
||||
}
|
||||
this.addReplElements(toAdd);
|
||||
} else {
|
||||
// TODO@Isidor hack, we should introduce a new type which is an output that can fetch children like an expression
|
||||
(<any>output).severity = severity;
|
||||
this.addReplElements([output]);
|
||||
(<any>data).severity = severity;
|
||||
(<any>data).sourceData = source;
|
||||
this.addReplElements([data]);
|
||||
}
|
||||
|
||||
this._onDidChangeREPLElements.fire();
|
||||
|
||||
Reference in New Issue
Block a user