提交 d94bb19d 编写于 作者: A Alex Ross

strictPropertyInitialization in tasks and custom tree view

Part of #78168
上级 45fec012
......@@ -124,7 +124,7 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
this._dataProviders.forEach((dataProvider, treeViewId) => {
const treeView = this.getTreeView(treeViewId);
if (treeView) {
treeView.dataProvider = null;
treeView.dataProvider = undefined;
}
});
this._dataProviders.clear();
......
......@@ -161,12 +161,12 @@ export class CustomTreeView extends Disposable implements ITreeView {
private _showCollapseAllAction = false;
private focused: boolean = false;
private domNode: HTMLElement;
private treeContainer: HTMLElement;
private domNode!: HTMLElement;
private treeContainer!: HTMLElement;
private _messageValue: string | undefined;
private messageElement: HTMLDivElement;
private tree: WorkbenchAsyncDataTree<ITreeItem, ITreeItem, FuzzyScore>;
private treeLabels: ResourceLabels;
private messageElement!: HTMLDivElement;
private tree: WorkbenchAsyncDataTree<ITreeItem, ITreeItem, FuzzyScore> | undefined;
private treeLabels: ResourceLabels | undefined;
private root: ITreeItem;
private elementsToRefresh: ITreeItem[] = [];
private menus: TitleMenus;
......@@ -218,12 +218,12 @@ export class CustomTreeView extends Disposable implements ITreeView {
this.create();
}
private _dataProvider: ITreeViewDataProvider | null;
get dataProvider(): ITreeViewDataProvider | null {
private _dataProvider: ITreeViewDataProvider | undefined;
get dataProvider(): ITreeViewDataProvider | undefined {
return this._dataProvider;
}
set dataProvider(dataProvider: ITreeViewDataProvider | null) {
set dataProvider(dataProvider: ITreeViewDataProvider | undefined) {
if (dataProvider) {
this._dataProvider = new class implements ITreeViewDataProvider {
async getChildren(node: ITreeItem): Promise<ITreeItem[]> {
......@@ -238,7 +238,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
this.updateMessage();
this.refresh();
} else {
this._dataProvider = null;
this._dataProvider = undefined;
this.updateMessage();
}
}
......@@ -399,7 +399,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
if (!e.browserEvent) {
return;
}
const selection = this.tree.getSelection();
const selection = this.tree!.getSelection();
if ((selection.length === 1) && selection[0].command) {
this.commandService.executeCommand(selection[0].command.id, ...(selection[0].command.arguments || []));
}
......@@ -416,7 +416,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
event.preventDefault();
event.stopPropagation();
this.tree.setFocus([node]);
this.tree!.setFocus([node]);
const actions = treeMenus.getResourceContextActions(node);
if (!actions.length) {
return;
......@@ -436,13 +436,13 @@ export class CustomTreeView extends Disposable implements ITreeView {
onHide: (wasCancelled?: boolean) => {
if (wasCancelled) {
this.tree.domFocus();
this.tree!.domFocus();
}
},
getActionsContext: () => (<TreeViewItemHandleArg>{ $treeViewId: this.id, $treeItemHandle: node.handle }),
actionRunner: new MultipleSelectionActionRunner(() => this.tree.getSelection())
actionRunner: new MultipleSelectionActionRunner(() => this.tree!.getSelection())
});
}
......@@ -479,8 +479,8 @@ export class CustomTreeView extends Disposable implements ITreeView {
DOM.clearNode(this.messageElement);
}
private _height: number;
private _width: number;
private _height: number = 0;
private _width: number = 0;
layout(height: number, width: number) {
if (height && width) {
this._height = height;
......@@ -532,10 +532,11 @@ export class CustomTreeView extends Disposable implements ITreeView {
}
async expand(itemOrItems: ITreeItem | ITreeItem[]): Promise<void> {
if (this.tree) {
const tree = this.tree;
if (tree) {
itemOrItems = Array.isArray(itemOrItems) ? itemOrItems : [itemOrItems];
await Promise.all(itemOrItems.map(element => {
return this.tree.expand(element, false);
return tree.expand(element, false);
}));
}
return Promise.resolve(undefined);
......@@ -575,18 +576,19 @@ export class CustomTreeView extends Disposable implements ITreeView {
private refreshing: boolean = false;
private async doRefresh(elements: ITreeItem[]): Promise<void> {
if (this.tree) {
const tree = this.tree;
if (tree) {
this.refreshing = true;
const parents: Set<ITreeItem> = new Set<ITreeItem>();
elements.forEach(element => {
if (element !== this.root) {
const parent = this.tree.getParentElement(element);
const parent = tree.getParentElement(element);
parents.add(parent);
} else {
parents.add(element);
}
});
await Promise.all(Array.from(parents.values()).map(element => this.tree.updateChildren(element, true)));
await Promise.all(Array.from(parents.values()).map(element => tree.updateChildren(element, true)));
this.refreshing = false;
this.updateContentAreas();
if (this.focused) {
......@@ -772,7 +774,7 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
}
class Aligner extends Disposable {
private _tree: WorkbenchAsyncDataTree<ITreeItem, ITreeItem, FuzzyScore>;
private _tree: WorkbenchAsyncDataTree<ITreeItem, ITreeItem, FuzzyScore> | undefined;
constructor(private themeService: IWorkbenchThemeService) {
super();
......@@ -790,11 +792,15 @@ class Aligner extends Disposable {
return false;
}
const parent: ITreeItem = this._tree.getParentElement(treeItem) || this._tree.getInput();
if (this.hasIcon(parent)) {
if (this._tree) {
const parent: ITreeItem = this._tree.getParentElement(treeItem) || this._tree.getInput();
if (this.hasIcon(parent)) {
return false;
}
return !!parent.children && parent.children.every(c => c.collapsibleState === TreeItemCollapsibleState.None || !this.hasIcon(c));
} else {
return false;
}
return !!parent.children && parent.children.every(c => c.collapsibleState === TreeItemCollapsibleState.None || !this.hasIcon(c));
}
private hasIcon(node: ITreeItem): boolean {
......
......@@ -300,7 +300,7 @@ export interface IViewsService {
export interface ITreeView extends IDisposable {
dataProvider: ITreeViewDataProvider | null;
dataProvider: ITreeViewDataProvider | undefined;
showCollapseAllAction: boolean;
......
......@@ -179,10 +179,10 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
private static nextHandle: number = 0;
private _schemaVersion: JsonSchemaVersion;
private _executionEngine: ExecutionEngine;
private _workspaceFolders: IWorkspaceFolder[];
private _ignoredWorkspaceFolders: IWorkspaceFolder[];
private _schemaVersion: JsonSchemaVersion | undefined;
private _executionEngine: ExecutionEngine | undefined;
private _workspaceFolders: IWorkspaceFolder[] | undefined;
private _ignoredWorkspaceFolders: IWorkspaceFolder[] | undefined;
private _showIgnoreMessage?: boolean;
private _providers: Map<number, ITaskProvider>;
private _providerTypes: Map<number, string>;
......@@ -192,7 +192,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
protected _taskSystem?: ITaskSystem;
protected _taskSystemListener?: IDisposable;
private _recentlyUsedTasks: LinkedMap<string, string>;
private _recentlyUsedTasks: LinkedMap<string, string> | undefined;
protected _taskRunningState: IContextKey<boolean>;
......@@ -375,28 +375,28 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
if (!this._workspaceFolders) {
this.updateSetup();
}
return this._workspaceFolders;
return this._workspaceFolders!;
}
private get ignoredWorkspaceFolders(): IWorkspaceFolder[] {
if (!this._ignoredWorkspaceFolders) {
this.updateSetup();
}
return this._ignoredWorkspaceFolders;
return this._ignoredWorkspaceFolders!;
}
protected get executionEngine(): ExecutionEngine {
if (this._executionEngine === undefined) {
this.updateSetup();
}
return this._executionEngine;
return this._executionEngine!;
}
private get schemaVersion(): JsonSchemaVersion {
if (this._schemaVersion === undefined) {
this.updateSetup();
}
return this._schemaVersion;
return this._schemaVersion!;
}
private get showIgnoreMessage(): boolean {
......
......@@ -155,9 +155,10 @@ export class TerminalTaskSystem implements ITaskSystem {
private idleTaskTerminals: LinkedMap<string, string>;
private sameTaskTerminals: IStringDictionary<string>;
private taskSystemInfoResolver: TaskSystemInfoResolver;
private lastTask: VerifiedTask;
private currentTask: VerifiedTask;
private isRerun: boolean;
private lastTask: VerifiedTask | undefined;
// Should always be set in run
private currentTask!: VerifiedTask;
private isRerun: boolean = false;
private readonly _onDidStateChange: Emitter<TaskEvent>;
......@@ -485,28 +486,32 @@ export class TerminalTaskSystem implements ITaskSystem {
}
private reexecuteCommand(task: CustomTask | ContributedTask, trigger: string): Promise<ITaskSummary> {
const workspaceFolder = this.currentTask.workspaceFolder = this.lastTask.workspaceFolder;
const lastTask = this.lastTask;
if (!lastTask) {
return Promise.reject(new Error('No task previously run'));
}
const workspaceFolder = this.currentTask.workspaceFolder = lastTask.workspaceFolder;
let variables = new Set<string>();
this.collectTaskVariables(variables, task);
// Check that the task hasn't changed to include new variables
let hasAllVariables = true;
variables.forEach(value => {
if (value.substring(2, value.length - 1) in this.lastTask.getVerifiedTask().resolvedVariables) {
if (value.substring(2, value.length - 1) in lastTask.getVerifiedTask().resolvedVariables) {
hasAllVariables = false;
}
});
if (!hasAllVariables) {
return this.resolveVariablesFromSet(this.lastTask.getVerifiedTask().systemInfo, this.lastTask.getVerifiedTask().workspaceFolder, task, variables).then((resolvedVariables) => {
return this.resolveVariablesFromSet(lastTask.getVerifiedTask().systemInfo, lastTask.getVerifiedTask().workspaceFolder, task, variables).then((resolvedVariables) => {
this.currentTask.resolvedVariables = resolvedVariables;
return this.executeInTerminal(task, trigger, new VariableResolver(this.lastTask.getVerifiedTask().workspaceFolder, this.lastTask.getVerifiedTask().systemInfo, resolvedVariables.variables, this.configurationResolverService), workspaceFolder!);
return this.executeInTerminal(task, trigger, new VariableResolver(lastTask.getVerifiedTask().workspaceFolder, lastTask.getVerifiedTask().systemInfo, resolvedVariables.variables, this.configurationResolverService), workspaceFolder!);
}, reason => {
return Promise.reject(reason);
});
} else {
this.currentTask.resolvedVariables = this.lastTask.getVerifiedTask().resolvedVariables;
return this.executeInTerminal(task, trigger, new VariableResolver(this.lastTask.getVerifiedTask().workspaceFolder, this.lastTask.getVerifiedTask().systemInfo, this.lastTask.getVerifiedTask().resolvedVariables.variables, this.configurationResolverService), workspaceFolder!);
this.currentTask.resolvedVariables = lastTask.getVerifiedTask().resolvedVariables;
return this.executeInTerminal(task, trigger, new VariableResolver(lastTask.getVerifiedTask().workspaceFolder, lastTask.getVerifiedTask().systemInfo, lastTask.getVerifiedTask().resolvedVariables.variables, this.configurationResolverService), workspaceFolder!);
}
}
......@@ -923,7 +928,7 @@ export class TerminalTaskSystem implements ITaskSystem {
args = resolvedResult.args;
commandExecutable = CommandString.value(command);
this.currentTask.shellLaunchConfig = launchConfigs = this.isRerun ? this.lastTask.getVerifiedTask().shellLaunchConfig : await this.createShellLaunchConfig(task, workspaceFolder, resolver, platform, options, command, args, waitOnExit);
this.currentTask.shellLaunchConfig = launchConfigs = (this.isRerun && this.lastTask) ? this.lastTask.getVerifiedTask().shellLaunchConfig : await this.createShellLaunchConfig(task, workspaceFolder, resolver, platform, options, command, args, waitOnExit);
if (launchConfigs === undefined) {
return [undefined, undefined, new TaskError(Severity.Error, nls.localize('TerminalTaskSystem', 'Can\'t execute a shell command on an UNC drive using cmd.exe.'), TaskErrors.UnknownError)];
}
......
......@@ -44,7 +44,7 @@ export abstract class AbstractProblemCollector implements IDisposable {
private bufferLength: number;
private openModels: IStringDictionary<boolean>;
private readonly modelListeners = new DisposableStore();
private tail: Promise<void>;
private tail: Promise<void> | undefined;
// [owner] -> ApplyToKind
private applyToByOwner: Map<string, ApplyToKind>;
......@@ -344,8 +344,8 @@ export const enum ProblemHandlingStrategy {
export class StartStopProblemCollector extends AbstractProblemCollector implements IProblemMatcher {
private owners: string[];
private currentOwner: string;
private currentResource: string;
private currentOwner: string | undefined;
private currentResource: string | undefined;
constructor(problemMatchers: ProblemMatcher[], markerService: IMarkerService, modelService: IModelService, _strategy: ProblemHandlingStrategy = ProblemHandlingStrategy.Clean, fileService?: IFileService) {
super(problemMatchers, markerService, modelService, fileService);
......@@ -397,8 +397,8 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement
private _activeBackgroundMatchers: Set<string>;
// Current State
private currentOwner: string | null;
private currentResource: string | null;
private currentOwner: string | undefined;
private currentResource: string | undefined;
constructor(problemMatchers: ProblemMatcher[], markerService: IMarkerService, modelService: IModelService, fileService?: IFileService) {
super(problemMatchers, markerService, modelService, fileService);
......@@ -503,8 +503,8 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement
private resetCurrentResource(): void {
this.reportMarkersForCurrentResource();
this.currentOwner = null;
this.currentResource = null;
this.currentOwner = undefined;
this.currentResource = undefined;
}
private reportMarkersForCurrentResource(): void {
......@@ -512,4 +512,4 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement
this.deliverMarkersPerOwnerAndResource(this.currentOwner, this.currentResource);
}
}
}
\ No newline at end of file
}
......@@ -264,7 +264,7 @@ abstract class AbstractLineMatcher implements ILineMatcher {
public abstract get matchLength(): number;
protected fillProblemData(data: ProblemData | null, pattern: ProblemPattern, matches: RegExpExecArray): data is ProblemData {
protected fillProblemData(data: ProblemData | undefined, pattern: ProblemPattern, matches: RegExpExecArray): data is ProblemData {
if (data) {
this.fillProperty(data, 'file', pattern, matches, true);
this.appendProperty(data, 'message', pattern, matches, true);
......@@ -449,7 +449,7 @@ class SingleLineMatcher extends AbstractLineMatcher {
class MultiLineMatcher extends AbstractLineMatcher {
private patterns: ProblemPattern[];
private data: ProblemData | null;
private data: ProblemData | undefined;
constructor(matcher: ProblemMatcher, fileService?: IFileService) {
super(matcher, fileService);
......@@ -480,7 +480,7 @@ class MultiLineMatcher extends AbstractLineMatcher {
}
let loop = !!this.patterns[this.patterns.length - 1].loop;
if (!loop) {
this.data = null;
this.data = undefined;
}
const markerMatch = data ? this.getMarkerMatch(data) : null;
return { match: markerMatch ? markerMatch : null, continue: loop };
......@@ -491,7 +491,7 @@ class MultiLineMatcher extends AbstractLineMatcher {
Assert.ok(pattern.loop === true && this.data !== null);
let matches = pattern.regexp.exec(line);
if (!matches) {
this.data = null;
this.data = undefined;
return null;
}
let data = Objects.deepClone(this.data);
......@@ -794,7 +794,7 @@ export namespace Config {
fileLocation?: string | string[];
/**
* The name of a predefined problem pattern, the inline definintion
* The name of a predefined problem pattern, the inline definition
* of a problem pattern or an array of problem patterns to match
* problems spread over multiple lines.
*/
......
......@@ -681,7 +681,7 @@ export namespace RunOptions {
}
}
class ParseContext {
interface ParseContext {
workspaceFolder: IWorkspaceFolder;
problemReporter: IProblemReporter;
namedProblemMatchers: IStringDictionary<NamedProblemMatcher>;
......
......@@ -89,7 +89,7 @@ class TaskDefinitionRegistryImpl implements ITaskDefinitionRegistry {
private taskTypes: IStringDictionary<Tasks.TaskDefinition>;
private readyPromise: Promise<void>;
private _schema: IJSONSchema;
private _schema: IJSONSchema | undefined;
constructor() {
this.taskTypes = Object.create(null);
......
......@@ -518,7 +518,7 @@ export abstract class CommonTask {
/**
* The cached label.
*/
_label: string;
_label: string = '';
type?: string;
......@@ -614,7 +614,7 @@ export abstract class CommonTask {
export class CustomTask extends CommonTask {
type: '$customized'; // CUSTOMIZED_TASK_TYPE
type!: '$customized'; // CUSTOMIZED_TASK_TYPE
/**
* Indicated the source of the task (e.g. tasks.json or extension)
......@@ -626,7 +626,7 @@ export class CustomTask extends CommonTask {
/**
* The command configuration
*/
command: CommandConfiguration;
command: CommandConfiguration = {};
public constructor(id: string, source: WorkspaceTaskSource, label: string, type: string, command: CommandConfiguration | undefined,
hasDefinedMatchers: boolean, runOptions: RunOptions, configurationProperties: ConfigurationProperties) {
......@@ -754,8 +754,9 @@ export class ContributedTask extends CommonTask {
/**
* Indicated the source of the task (e.g. tasks.json or extension)
* Set in the super constructor
*/
_source: ExtensionTaskSource;
_source!: ExtensionTaskSource;
defines: KeyedTaskIdentifier;
......@@ -824,7 +825,7 @@ export class InMemoryTask extends CommonTask {
*/
_source: InMemoryTaskSource;
type: 'inMemory';
type!: 'inMemory';
public constructor(id: string, source: InMemoryTaskSource, label: string, type: string,
runOptions: RunOptions, configurationProperties: ConfigurationProperties) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册