Initial work on enabling strict nulls in azurecore (#20411)

This commit is contained in:
Charles Gagnon
2022-08-24 10:59:25 -07:00
committed by GitHub
parent 65aa98597d
commit a7e5acf539
12 changed files with 60 additions and 59 deletions

View File

@@ -31,7 +31,7 @@ export function registerAzureResourceCommands(appContext: AppContext, azureViewT
}
let azureAccount: AzureAccount | undefined;
if (node instanceof AzureResourceAccountTreeNode) {
azureAccount = node.account as AzureAccount;
azureAccount = node.account;
} else {
let accounts = await azdata.accounts.getAllAccounts();
accounts = accounts.filter(a => a.key.providerId.startsWith('azure'));
@@ -57,7 +57,9 @@ export function registerAzureResourceCommands(appContext: AppContext, azureViewT
azureAccount = accounts.find(acct => acct.displayInfo.displayName === pickedAccount);
}
}
if (!azureAccount) {
throw new Error('No Azure Account chosen');
}
const terminalService = appContext.getService<IAzureTerminalService>(AzureResourceServiceNames.terminalService);
const listOfTenants = azureAccount.properties.tenants.map(t => t.displayName);
@@ -176,7 +178,7 @@ export function registerAzureResourceCommands(appContext: AppContext, azureViewT
if (!node) {
return;
}
let connectionProfile: azdata.IConnectionProfile = undefined;
let connectionProfile: azdata.IConnectionProfile | undefined = undefined;
if (node instanceof TreeNode) {
const treeItem: azdata.TreeItem = await node.getTreeItem();
if (!treeItem.payload) {

View File

@@ -12,7 +12,7 @@ import { AzureResourceItemType } from './constants';
export class AzureResourceMessageTreeNode extends TreeNode {
public constructor(
public readonly message: string,
parent: TreeNode
parent: TreeNode | undefined
) {
super();
@@ -20,7 +20,7 @@ export class AzureResourceMessageTreeNode extends TreeNode {
this._id = `message_${AzureResourceMessageTreeNode._messageNum++}`;
}
public static create(message: string, parent: TreeNode): AzureResourceMessageTreeNode {
public static create(message: string, parent: TreeNode | undefined): AzureResourceMessageTreeNode {
return new AzureResourceMessageTreeNode(message, parent);
}

View File

@@ -71,7 +71,7 @@ export class AzureResourceAccountTreeNode extends AzureResourceContainerTreeNode
let token: azdata.accounts.AccountSecurityToken | undefined = undefined;
let errMsg = '';
try {
token = await azdata.accounts.getAccountSecurityToken(this.account, s.tenant, azdata.AzureResource.ResourceManagement);
token = await azdata.accounts.getAccountSecurityToken(this.account, s.tenant!, azdata.AzureResource.ResourceManagement);
} catch (err) {
errMsg = AzureResourceErrorMessageUtil.getErrorMessage(err);
}
@@ -84,7 +84,7 @@ export class AzureResourceAccountTreeNode extends AzureResourceContainerTreeNode
subscriptions = subscriptions.filter((_s, i) => hasTokenResults[i]);
let subTreeNodes = await Promise.all(subscriptions.map(async (subscription) => {
return new AzureResourceSubscriptionTreeNode(this.account, subscription, subscription.tenant, this.appContext, this.treeChangeHandler, this);
return new AzureResourceSubscriptionTreeNode(this.account, subscription, subscription.tenant!, this.appContext, this.treeChangeHandler, this);
}));
return subTreeNodes.sort((a, b) => a.subscription.name.localeCompare(b.subscription.name));
}
@@ -97,7 +97,7 @@ export class AzureResourceAccountTreeNode extends AzureResourceContainerTreeNode
}
public async getCachedSubscriptions(): Promise<azureResource.AzureResourceSubscription[]> {
return this.getCache<azureResource.AzureResourceSubscription[]>();
return this.getCache<azureResource.AzureResourceSubscription[]>() ?? [];
}
public getTreeItem(): vscode.TreeItem | Promise<vscode.TreeItem> {
@@ -155,11 +155,11 @@ export class AzureResourceAccountTreeNode extends AzureResourceContainerTreeNode
return label;
}
private _subscriptionService: IAzureResourceSubscriptionService = undefined;
private _subscriptionFilterService: IAzureResourceSubscriptionFilterService = undefined;
private _subscriptionService: IAzureResourceSubscriptionService;
private _subscriptionFilterService: IAzureResourceSubscriptionFilterService;
private _id: string = undefined;
private _label: string = undefined;
private _id: string;
private _label: string;
private _totalSubscriptionCount = 0;
private _selectedSubscriptionCount = 0;

View File

@@ -14,7 +14,7 @@ abstract class AzureResourceTreeNodeBase extends TreeNode {
public constructor(
public readonly appContext: AppContext,
public readonly treeChangeHandler: IAzureResourceTreeChangeHandler,
parent: TreeNode
parent: TreeNode | undefined
) {
super();
@@ -26,7 +26,7 @@ export abstract class AzureResourceContainerTreeNodeBase extends AzureResourceTr
public constructor(
appContext: AppContext,
treeChangeHandler: IAzureResourceTreeChangeHandler,
parent: TreeNode
parent: TreeNode | undefined
) {
super(appContext, treeChangeHandler, parent);
@@ -46,14 +46,21 @@ export abstract class AzureResourceContainerTreeNodeBase extends AzureResourceTr
}
protected updateCache<T>(cache: T): Promise<void> {
return this._cacheService.update<T>(this._cacheKey, cache);
return this._cacheService.update<T>(this._cacheKey!, cache);
}
protected getCache<T>(): T {
return this._cacheService.get<T>(this._cacheKey);
protected getCache<T>(): T | undefined {
this.ensureCacheKey();
return this._cacheService.get<T | undefined>(this._cacheKey!);
}
private ensureCacheKey(): void {
if (!this._cacheKey) {
throw new Error('A cache key must be generated first');
}
}
protected _isClearingCache = true;
private _cacheService: IAzureResourceCacheService = undefined;
private _cacheKey: string = undefined;
private _cacheService: IAzureResourceCacheService;
private _cacheKey: string | undefined = undefined;
}

View File

@@ -22,9 +22,9 @@ import { AzureAccount } from 'azurecore';
export class ConnectionDialogTreeProvider implements vscode.TreeDataProvider<TreeNode>, IAzureResourceTreeChangeHandler {
public isSystemInitialized: boolean = false;
private accounts: AzureAccount[];
private _onDidChangeTreeData = new vscode.EventEmitter<TreeNode>();
private loadingAccountsPromise: Promise<void>;
private accounts: AzureAccount[] = [];
private _onDidChangeTreeData = new vscode.EventEmitter<TreeNode | undefined>();
private loadingAccountsPromise: Promise<void> | undefined;
public constructor(private readonly appContext: AppContext) {
azdata.accounts.onDidChangeAccounts(async (e: azdata.DidChangeAccountsParams) => {
@@ -101,15 +101,15 @@ export class ConnectionDialogTreeProvider implements vscode.TreeDataProvider<Tre
this.loadingAccountsPromise = undefined;
}
public get onDidChangeTreeData(): vscode.Event<TreeNode> {
public get onDidChangeTreeData(): vscode.Event<TreeNode | undefined> {
return this._onDidChangeTreeData.event;
}
public notifyNodeChanged(node: TreeNode): void {
public notifyNodeChanged(node: TreeNode | undefined): void {
this._onDidChangeTreeData.fire(node);
}
public async refresh(node: TreeNode, isClearingCache: boolean): Promise<void> {
public async refresh(node: TreeNode | undefined, isClearingCache: boolean): Promise<void> {
if (isClearingCache) {
if ((node instanceof AzureResourceContainerTreeNodeBase)) {
node.clearCache();

View File

@@ -136,7 +136,7 @@ async function getSubscriptionInfo(account: AzureAccount, subscriptionService: I
class FlatAccountTreeNodeLoader {
private _isLoading: boolean = false;
private _nodes: TreeNode[];
private _nodes: TreeNode[] = [];
private readonly _onNewResourcesAvailable = new vscode.EventEmitter<void>();
public readonly onNewResourcesAvailable = this._onNewResourcesAvailable.event;
private readonly _onLoadingStatusChanged = new vscode.EventEmitter<void>();
@@ -183,7 +183,7 @@ class FlatAccountTreeNodeLoader {
if (subscriptions.length !== 0) {
// Filter out everything that we can't authenticate to.
subscriptions = subscriptions.filter(async s => {
const token = await azdata.accounts.getAccountSecurityToken(this._account, s.tenant, azdata.AzureResource.ResourceManagement);
const token = await azdata.accounts.getAccountSecurityToken(this._account, s.tenant!, azdata.AzureResource.ResourceManagement);
if (!token) {
console.info(`Account does not have permissions to view subscription ${JSON.stringify(s)}.`);
return false;
@@ -195,7 +195,7 @@ class FlatAccountTreeNodeLoader {
const resourceProviderIds = await this._resourceService.listResourceProviderIds();
for (const subscription of subscriptions) {
for (const providerId of resourceProviderIds) {
const resourceTypes = await this._resourceService.getRootChildren(providerId, this._account, subscription, subscription.tenant);
const resourceTypes = await this._resourceService.getRootChildren(providerId, this._account, subscription, subscription.tenant!);
for (const resourceType of resourceTypes) {
const resources = await this._resourceService.getChildren(providerId, resourceType.resourceNode, true);
if (resources.length > 0) {

View File

@@ -24,7 +24,7 @@ export class FlatAzureResourceTreeProvider implements vscode.TreeDataProvider<Tr
private _onDidChangeTreeData = new vscode.EventEmitter<TreeNode | undefined>();
private resourceLoader: ResourceLoader;
private resourceLoader: ResourceLoader | undefined;
public constructor(private readonly appContext: AppContext) {
}
@@ -124,13 +124,13 @@ class ResourceLoader {
for (const tenant of account.properties.tenants) {
for (const subscription of await this.subscriptionService.getSubscriptions(account, [tenant.id])) {
for (const providerId of await this.resourceService.listResourceProviderIds()) {
for (const group of await this.resourceService.getRootChildren(providerId, account, subscription, subscription.tenant)) {
for (const group of await this.resourceService.getRootChildren(providerId, account, subscription, subscription.tenant!)) {
const children = await this.resourceService.getChildren(providerId, group.resourceNode);
if (this.resourceGroups.has(group.resourceProviderId)) {
const groupNode = this.resourceGroups.get(group.resourceProviderId);
let groupNode: AzureResourceResourceTreeNode | undefined = this.resourceGroups.get(group.resourceProviderId);
if (groupNode) {
groupNode.pushItems(...children);
} else {
const groupNode = new AzureResourceResourceTreeNode(group, this.appContext);
groupNode = new AzureResourceResourceTreeNode(group, this.appContext);
this.resourceGroups.set(group.resourceProviderId, groupNode);
groupNode.pushItems(...children);
}
@@ -199,14 +199,14 @@ class AzureResourceResourceTreeNode extends TreeNode {
metadata: undefined,
nodePath: this.generateNodePath(),
nodeStatus: undefined,
nodeType: treeItem.contextValue,
nodeType: treeItem.contextValue || '',
nodeSubType: undefined,
iconType: treeItem.contextValue
};
}
public get nodePathValue(): string {
return this.resourceNodeWithProviderId.resourceNode.treeItem.id;
return this.resourceNodeWithProviderId.resourceNode.treeItem.id || '';
}
}

View File

@@ -87,7 +87,7 @@ export class AzureResourceSubscriptionTreeNode extends AzureResourceContainerTre
return this._id;
}
private _id: string = undefined;
private _id: string;
private static readonly noResourcesLabel = localize('azure.resource.tree.subscriptionTreeNode.noResourcesLabel', "No Resources found.");
}

View File

@@ -22,9 +22,9 @@ import { AzureAccount } from 'azurecore';
export class AzureResourceTreeProvider implements vscode.TreeDataProvider<TreeNode>, IAzureResourceTreeChangeHandler {
public isSystemInitialized: boolean = false;
private accounts: AzureAccount[];
private _onDidChangeTreeData = new vscode.EventEmitter<TreeNode>();
private loadingAccountsPromise: Promise<void>;
private accounts: AzureAccount[] = [];
private _onDidChangeTreeData = new vscode.EventEmitter<TreeNode | undefined>();
private loadingAccountsPromise: Promise<void> | undefined;
public constructor(private readonly appContext: AppContext) {
azdata.accounts.onDidChangeAccounts(async (e: azdata.DidChangeAccountsParams) => {
@@ -82,15 +82,15 @@ export class AzureResourceTreeProvider implements vscode.TreeDataProvider<TreeNo
this.loadingAccountsPromise = undefined;
}
public get onDidChangeTreeData(): vscode.Event<TreeNode> {
public get onDidChangeTreeData(): vscode.Event<TreeNode | undefined> {
return this._onDidChangeTreeData.event;
}
public notifyNodeChanged(node: TreeNode): void {
public notifyNodeChanged(node: TreeNode | undefined): void {
this._onDidChangeTreeData.fire(node);
}
public async refresh(node: TreeNode, isClearingCache: boolean): Promise<void> {
public async refresh(node: TreeNode | undefined, isClearingCache: boolean): Promise<void> {
if (isClearingCache) {
if ((node instanceof AzureResourceContainerTreeNodeBase)) {
node.clearCache();

View File

@@ -18,13 +18,13 @@ export abstract class TreeNode {
return path;
}
public findNodeByPath(path: string, expandIfNeeded: boolean = false): Promise<TreeNode> {
public findNodeByPath(path: string, expandIfNeeded: boolean = false): Promise<TreeNode | undefined> {
let condition: TreeNodePredicate = (node: TreeNode) => node.getNodeInfo().nodePath === path;
let filter: TreeNodePredicate = (node: TreeNode) => path.startsWith(node.getNodeInfo().nodePath);
return TreeNode.findNode(this, condition, filter, true);
}
public static async findNode(node: TreeNode, condition: TreeNodePredicate, filter: TreeNodePredicate, expandIfNeeded: boolean): Promise<TreeNode> {
public static async findNode(node: TreeNode, condition: TreeNodePredicate, filter: TreeNodePredicate, expandIfNeeded: boolean): Promise<TreeNode | undefined> {
if (!node) {
return undefined;
}
@@ -53,13 +53,7 @@ export abstract class TreeNode {
return undefined;
}
public get parent(): TreeNode {
return this._parent;
}
public set parent(node: TreeNode) {
this._parent = node;
}
public parent: TreeNode | undefined = undefined;
public abstract getChildren(refreshChildren: boolean): TreeNode[] | Promise<TreeNode[]>;
public abstract getTreeItem(): vscode.TreeItem | Promise<vscode.TreeItem>;
@@ -70,6 +64,4 @@ export abstract class TreeNode {
* The value to use for this node in the node path
*/
public abstract get nodePathValue(): string;
private _parent: TreeNode = undefined;
}

View File

@@ -56,7 +56,7 @@ let extensionContext: vscode.ExtensionContext;
function getAppDataPath() {
let platform = process.platform;
switch (platform) {
case 'win32': return process.env['APPDATA'] || path.join(process.env['USERPROFILE'], 'AppData', 'Roaming');
case 'win32': return process.env['APPDATA'] || path.join(process.env['USERPROFILE']!, 'AppData', 'Roaming');
case 'darwin': return path.join(os.homedir(), 'Library', 'Application Support');
case 'linux': return process.env['XDG_CONFIG_HOME'] || path.join(os.homedir(), '.config');
default: throw new Error('Platform not supported');
@@ -79,7 +79,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<azurec
let storagePath = await findOrMakeStoragePath();
if (!storagePath) {
return undefined;
throw new Error('Could not find or create storage path');
}
// TODO: Since Code Grant auth doesnt work in web mode, enabling Device code auth by default for web mode. We can remove this once we have that working in web mode.
@@ -98,7 +98,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<azurec
const connectionDialogTree = new ConnectionDialogTreeProvider(appContext);
pushDisposable(vscode.window.registerTreeDataProvider('azureResourceExplorer', azureResourceTree));
pushDisposable(vscode.window.registerTreeDataProvider('connectionDialog/azureResourceExplorer', connectionDialogTree));
pushDisposable(vscode.workspace.onDidChangeConfiguration(e => onDidChangeConfiguration(e), this));
pushDisposable(vscode.workspace.onDidChangeConfiguration(e => onDidChangeConfiguration(e)));
registerAzureResourceCommands(appContext, azureResourceTree, connectionDialogTree);
azdata.dataprotocol.registerDataGridProvider(new AzureDataGridProvider(appContext));
vscode.commands.registerCommand('azure.dataGrid.openInAzurePortal', async (item: azdata.DataGridItem) => {
@@ -280,8 +280,8 @@ async function onDidChangeConfiguration(e: vscode.ConfigurationChangeEvent): Pro
}
}
function updatePiiLoggingLevel() {
const piiLogging: boolean = vscode.workspace.getConfiguration(constants.extensionConfigSectionName).get('piiLogging');
function updatePiiLoggingLevel(): void {
const piiLogging: boolean = vscode.workspace.getConfiguration(constants.extensionConfigSectionName).get('piiLogging', false);
Logger.piiLogging = piiLogging;
}

View File

@@ -2,7 +2,7 @@
"extends": "../tsconfig.base.json",
"compilerOptions": {
"outDir": "./out",
"strict": false,
"strict": true,
"noUnusedParameters": false,
"typeRoots": [
"./node_modules/@types"