Skip to content

Commit 45a162e

Browse files
authored
Merge pull request #61 from DeepCodeAI/mainline_update1
Mainline updates phase 2
2 parents d82c611 + 1dc7072 commit 45a162e

11 files changed

Lines changed: 114 additions & 86 deletions

File tree

package.json

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -105,30 +105,9 @@
105105
},
106106
"views": {
107107
"deepcode": [
108-
{
109-
"id": "deepcode.views.error",
110-
"name": "DeepCode Extension",
111-
"when": "deepcode:error"
112-
},
113-
{
114-
"id": "deepcode.views.welcome",
115-
"name": "DeepCode Extension",
116-
"when": "!deepcode:error && !deepcode:loggedIn"
117-
},
118-
{
119-
"id": "deepcode.views.tc",
120-
"name": "DeepCode Extension",
121-
"when": "!deepcode:error && deepcode:loggedIn && !deepcode:uploadApproved"
122-
},
123-
{
124-
"id": "deepcode.views.empty",
125-
"name": "DeepCode Extension",
126-
"when": "!deepcode:error && deepcode:loggedIn && deepcode:uploadApproved && !deepcode:workspaceFound"
127-
},
128108
{
129109
"id": "deepcode.views.analysis",
130-
"name": "DeepCode Analysis",
131-
"when": "!deepcode:error && deepcode:loggedIn && deepcode:uploadApproved && deepcode:workspaceFound"
110+
"name": "DeepCode Analysis"
132111
},
133112
{
134113
"id": "deepcode.views.actions",
@@ -143,30 +122,34 @@
143122
},
144123
"viewsWelcome": [
145124
{
146-
"view": "deepcode.views.error",
125+
"view": "deepcode.views.analysis",
147126
"contents": "DeepCode is temporarily unavailable\nWe are automatically retrying to connect...",
148127
"when": "deepcode:error == 'transient'"
149128
},
150129
{
151-
"view": "deepcode.views.error",
130+
"view": "deepcode.views.analysis",
152131
"contents": "DeepCode has encountered a problem. Please restart the extension: \n[Restart](command:deepcode.start 'Restart DeepCode')\nIf the error persists, please check your [settings](command:deepcode.settings) and [contact us](https://www.deepcode.ai/feedback?select=2?utm_source=vsc)!",
153-
"when": "deepcode:error != 'transient'"
132+
"when": "deepcode:error == 'blocking'"
154133
},
155134
{
156-
"view": "deepcode.views.welcome",
157-
"contents": "Welcome to DeepCode for Visual Studio Code. 👋\nLet's start by connecting VS Code with DeepCode:\n[Connect VS Code with DeepCode](command:deepcode.login 'Connect with DeepCode')\n👉 DeepCode's mission is to finds bugs, fast. Connect with DeepCode to start your first analysis!"
135+
"view": "deepcode.views.analysis",
136+
"contents": "Welcome to DeepCode for Visual Studio Code. 👋\nLet's start by connecting VS Code with DeepCode:\n[Connect VS Code with DeepCode](command:deepcode.login 'Connect with DeepCode')\n👉 DeepCode's mission is to finds bugs, fast. Connect with DeepCode to start your first analysis!",
137+
"when": "!deepcode:error && !deepcode:loggedIn"
158138
},
159139
{
160-
"view": "deepcode.views.tc",
161-
"contents": "Thanks for connecting with DeepCode. ✅\n 👉 You are almost set 🤗. DeepCode is analysing the code remotely on DeepCode's servers (our [terms](https://www.deepcode.ai/tc?utm_source=vsc)). Let's confirm you know this and start the analysis.\n[Accept and start analysing](command:deepcode.approve 'Upload code to DeepCode')\nYou can always change it in the [configuration panel](command:deepcode.settings)."
140+
"view": "deepcode.views.analysis",
141+
"contents": "Thanks for connecting with DeepCode. ✅\n 👉 You are almost set 🤗. DeepCode is analysing the code remotely on DeepCode's servers (our [terms](https://www.deepcode.ai/tc?utm_source=vsc)). Let's confirm you know this and start the analysis.\n[Accept and start analysing](command:deepcode.approve 'Upload code to DeepCode')\nYou can always change it in the [configuration panel](command:deepcode.settings).",
142+
"when": "!deepcode:error && deepcode:loggedIn && !deepcode:uploadApproved"
162143
},
163144
{
164-
"view": "deepcode.views.empty",
165-
"contents": "Open a workspace or a folder in Visual Studio Code to start the analysis."
145+
"view": "deepcode.views.analysis",
146+
"contents": "Open a workspace or a folder in Visual Studio Code to start the analysis.",
147+
"when": "!deepcode:error && deepcode:loggedIn && deepcode:uploadApproved && !deepcode:workspaceFound"
166148
},
167149
{
168150
"view": "deepcode.views.analysis",
169-
"contents": "DeepCode analyzed your code and found no issue! 🎉"
151+
"contents": "DeepCode analyzed your code and found no issue! 🎉",
152+
"when": "!deepcode:error && deepcode:loggedIn && deepcode:uploadApproved && deepcode:workspaceFound"
170153
},
171154
{
172155
"view": "deepcode.views.actions",

src/deepcode/constants/views.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
export const DEEPCODE_VIEW_ERROR = "deepcode.views.error";
2-
export const DEEPCODE_VIEW_WELCOME = "deepcode.views.welcome";
3-
export const DEEPCODE_VIEW_TC = "deepcode.views.tc";
4-
export const DEEPCODE_VIEW_EMPTY = "deepcode.views.empty";
51
export const DEEPCODE_VIEW_ANALYSIS = "deepcode.views.analysis";
62
export const DEEPCODE_VIEW_SUPPORT = "deepcode.views.support";
73
export const DEEPCODE_VIEW_ACTIONS = "deepcode.views.actions";

src/deepcode/lib/modules/BaseDeepCodeModule.ts

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import DeepCodeFilesWatcher from "../watchers/DeepCodeFilesWatcher";
77
import DeepCodeWorkspaceFoldersWatcher from "../watchers/WorkspaceFoldersWatcher";
88
import DeepCodeEditorsWatcher from "../watchers/EditorsWatcher";
99
import DeepCodeSettingsWatcher from "../watchers/DeepCodeSettingsWatcher";
10+
import { PendingTask, PendingTaskInterface } from "../../utils/pendingTask";
1011
import { IDE_NAME, REFRESH_VIEW_DEBOUNCE_INTERVAL } from "../../constants/general";
1112
import { setContext } from "../../utils/vscodeCommandsUtils";
12-
import { DEEPCODE_CONTEXT } from "../../constants/views";
13+
import { DEEPCODE_VIEW_ANALYSIS } from "../../constants/views";
1314
import { errorsLogs } from '../../messages/errorsServerLogMessages';
15+
import { pendingMocks } from 'nock/types';
1416

1517
export default abstract class BaseDeepCodeModule implements DeepCode.BaseDeepCodeModuleInterface {
1618
currentWorkspacePath: string;
@@ -29,8 +31,9 @@ export default abstract class BaseDeepCodeModule implements DeepCode.BaseDeepCod
2931
refreshViewEmitter: vscode.EventEmitter<any>;
3032
analysisStatus = '';
3133
analysisProgress = 0;
32-
private progressBadgePromise: Promise<void> | undefined;
33-
private progressBadgeResolveFn: (() => void) | undefined;
34+
private initializedView: PendingTaskInterface;
35+
private progressBadge: PendingTaskInterface | undefined;
36+
private viewContext: {[key: string]: unknown};
3437

3538
// These attributes are used in tests
3639
staticToken = '';
@@ -53,6 +56,8 @@ export default abstract class BaseDeepCodeModule implements DeepCode.BaseDeepCod
5356
this.refreshViewEmitter = new vscode.EventEmitter<any>();
5457
this.analysisStatus = '';
5558
this.analysisProgress = 0;
59+
this.viewContext = {};
60+
this.initializedView = new PendingTask();
5661
}
5762

5863
get baseURL(): string {
@@ -106,41 +111,54 @@ export default abstract class BaseDeepCodeModule implements DeepCode.BaseDeepCod
106111
return !!vscode.workspace.getConfiguration('deepcode').get<boolean>('advancedMode');
107112
}
108113

109-
private getProgressBadgePromise(): Promise<void> {
110-
if (this.progressBadgePromise === undefined) {
111-
// This should not be needed, but we resolve pending Promises
112-
// before overwriting the progressBadgeResolveFn reference.
113-
if (this.progressBadgeResolveFn) this.progressBadgeResolveFn();
114-
this.progressBadgePromise = new Promise(
115-
(resolve) => {
116-
this.progressBadgeResolveFn = resolve;
117-
}
114+
async setContext(key: string, value: unknown): Promise<void> {
115+
console.log("DeepCode context", key, value);
116+
this.viewContext[key] = value;
117+
await setContext(key, value);
118+
this.refreshViews();
119+
}
120+
121+
get shouldShowAnalysis(): boolean {
122+
return !this.viewContext['error'] &&
123+
['loggedIn', 'uploadApproved', 'workspaceFound'].every(
124+
(c) => !!this.viewContext[c]
118125
);
126+
}
127+
128+
private getProgressBadgePromise(): Promise<void> {
129+
if (!this.progressBadge || this.progressBadge.isCompleted) {
130+
this.progressBadge = new PendingTask();
119131
}
120-
return this.progressBadgePromise;
132+
return this.progressBadge.waiter;
121133
}
122134

123135
// Leave viewId undefined to remove the badge from all views
124-
async setLoadingBadge(viewId?: string): Promise<void> {
125-
if (viewId) {
136+
async setLoadingBadge(value: boolean): Promise<void> {
137+
if (value) {
126138
// Using closure on this to allow partial binding in arbitrary positions
127139
const self = this;
128-
vscode.window.withProgress(
129-
{ location: { viewId } },
130-
() => self.getProgressBadgePromise()
140+
this.initializedView.waiter.then(
141+
() => vscode.window.withProgress(
142+
{ location: { viewId: DEEPCODE_VIEW_ANALYSIS } },
143+
() => self.getProgressBadgePromise()
144+
)
131145
).then(
132146
() => {},
133147
(error) => self.processError(error, {
134148
message: errorsLogs.loadingBadge,
135149
})
136150
);
137151
} else {
138-
if (this.progressBadgeResolveFn) this.progressBadgeResolveFn();
139-
this.progressBadgePromise = undefined;
140-
this.progressBadgeResolveFn = undefined;
152+
if (this.progressBadge && !this.progressBadge.isCompleted) {
153+
this.progressBadge.complete();
154+
}
141155
}
142156
}
143157

158+
emitViewInitialized(): void {
159+
if (!this.initializedView.isCompleted) this.initializedView.complete();
160+
}
161+
144162
// Avoid refreshing context/views too often:
145163
// https://github.com/Microsoft/vscode/issues/68424
146164
refreshViews = _.debounce(

src/deepcode/lib/modules/BundlesModule.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { checkIfBundleIsEmpty } from "../../utils/bundlesUtils";
77
import { createListOfDirFiles } from "../../utils/packageUtils";
88
import { BUNDLE_EVENTS } from "../../constants/events";
99
import LoginModule from "../../lib/modules/LoginModule";
10-
import { setContext } from "../../utils/vscodeCommandsUtils";
1110
import { DEEPCODE_ANALYSIS_STATUS, DEEPCODE_CONTEXT } from "../../constants/views";
1211
import { errorsLogs } from "../../messages/errorsServerLogMessages";
1312

@@ -288,22 +287,22 @@ abstract class BundlesModule extends LoginModule
288287
try {
289288
const workspaceFolders: readonly vscode.WorkspaceFolder[] | undefined = vscode.workspace.workspaceFolders;
290289
if (!workspaceFolders || !workspaceFolders.length) {
291-
await setContext(DEEPCODE_CONTEXT.ANALYZING, false);
290+
await this.setContext(DEEPCODE_CONTEXT.ANALYZING, false);
292291
return;
293292
}
294293

295294
this.createWorkspacesList(workspaceFolders);
296295

297296
if (this.workspacesPaths.length) {
298-
await setContext(DEEPCODE_CONTEXT.ANALYZING, true);
297+
await this.setContext(DEEPCODE_CONTEXT.ANALYZING, true);
299298
this.updateCurrentWorkspacePath(this.workspacesPaths[0]);
300299

301300
await this.updateHashesBundles();
302301
for await (const path of this.workspacesPaths) {
303302
await this.performBundlesActions(path);
304303
}
305304
} else {
306-
await setContext(DEEPCODE_CONTEXT.ANALYZING, false);
305+
await this.setContext(DEEPCODE_CONTEXT.ANALYZING, false);
307306
}
308307
} catch(err) {
309308
await this.processError(err, {

src/deepcode/lib/modules/DeepCodeLib.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import * as _ from "lodash";
22
import DeepCode from "../../../interfaces/DeepCodeInterfaces";
33
import BundlesModule from "./BundlesModule";
4-
import { setContext } from "../../utils/vscodeCommandsUtils";
54
import { DEEPCODE_CONTEXT, DEEPCODE_MODE_CODES } from "../../constants/views";
65
import { errorsLogs } from "../../messages/errorsServerLogMessages";
76
import {
@@ -43,8 +42,8 @@ export default class DeepCodeLib extends BundlesModule implements DeepCode.DeepC
4342

4443
private async executeExtensionPipeline(): Promise<void> {
4544
console.log("DeepCode: starting execution pipeline");
46-
await setContext(DEEPCODE_CONTEXT.ERROR, false);
47-
await this.setLoadingBadge();
45+
await this.setContext(DEEPCODE_CONTEXT.ERROR, false);
46+
await this.setLoadingBadge(false);
4847

4948
const loggedIn = await this.checkSession();
5049
if (!loggedIn) return;
@@ -83,7 +82,7 @@ export default class DeepCodeLib extends BundlesModule implements DeepCode.DeepC
8382
async setMode(mode: string): Promise<void> {
8483
if (!Object.values(DEEPCODE_MODE_CODES).includes(mode)) return;
8584
this._mode = mode;
86-
await setContext(DEEPCODE_CONTEXT.MODE, mode);
85+
await this.setContext(DEEPCODE_CONTEXT.MODE, mode);
8786
switch(mode) {
8887
case DEEPCODE_MODE_CODES.PAUSED:
8988
this._unpauseTimeout = setTimeout(this.unpause.bind(this), EXECUTION_PAUSE_INTERVAL);

src/deepcode/lib/modules/LoginModule.ts

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@ import * as vscode from "vscode";
22
import ReportModule from "./ReportModule";
33
import DeepCode from "../../../interfaces/DeepCodeInterfaces";
44
import http from "../../http/requests";
5-
import { setContext, viewInBrowser } from "../../utils/vscodeCommandsUtils";
6-
import {
7-
DEEPCODE_VIEW_WELCOME,
8-
DEEPCODE_VIEW_TC,
9-
DEEPCODE_CONTEXT
10-
} from "../../constants/views";
5+
import { viewInBrowser } from "../../utils/vscodeCommandsUtils";
6+
import { DEEPCODE_CONTEXT } from "../../constants/views";
117
import { openDeepcodeViewContainer } from "../../utils/vscodeCommandsUtils";
128
import { errorsLogs } from "../../messages/errorsServerLogMessages";
139
import { deepCodeMessages } from "../../messages/deepCodeMessages";
@@ -48,14 +44,14 @@ abstract class LoginModule extends ReportModule implements DeepCode.LoginModuleI
4844
if (this.token) {
4945
try {
5046
validSession = !!(await http.checkSession(this.baseURL, this.token));
51-
if (!validSession) await this.setLoadingBadge(DEEPCODE_VIEW_WELCOME);
5247
} catch (err) {
5348
await this.processError(err, {
5449
message: errorsLogs.loginStatus
5550
});
5651
}
5752
}
58-
await setContext(DEEPCODE_CONTEXT.LOGGEDIN, validSession);
53+
await this.setContext(DEEPCODE_CONTEXT.LOGGEDIN, validSession);
54+
if (!validSession) await this.setLoadingBadge(true);
5955
return validSession;
6056
}
6157

@@ -74,14 +70,14 @@ abstract class LoginModule extends ReportModule implements DeepCode.LoginModuleI
7470

7571
async checkApproval(): Promise<boolean> {
7672
const approved = this.uploadApproved;
77-
await setContext(DEEPCODE_CONTEXT.APPROVED, approved);
78-
if (!approved) await this.setLoadingBadge(DEEPCODE_VIEW_TC);
73+
await this.setContext(DEEPCODE_CONTEXT.APPROVED, approved);
74+
if (!approved) await this.setLoadingBadge(true);
7975
return approved;
8076
}
8177

8278
async approveUpload(): Promise<void> {
8379
await this.setUploadApproved(true);
84-
await this.setLoadingBadge();
80+
await this.setLoadingBadge(false);
8581
await this.checkApproval();
8682
}
8783

@@ -99,7 +95,7 @@ abstract class LoginModule extends ReportModule implements DeepCode.LoginModuleI
9995
}
10096

10197
async checkAdvancedMode(): Promise<void> {
102-
await setContext(DEEPCODE_CONTEXT.ADVANCED, this.shouldShowAdvancedView);
98+
await this.setContext(DEEPCODE_CONTEXT.ADVANCED, this.shouldShowAdvancedView);
10399
}
104100
}
105101

src/deepcode/lib/modules/ReportModule.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import http from "../../http/requests";
33
import BaseDeepCodeModule from "./BaseDeepCodeModule";
44
import { statusCodes } from "../../constants/statusCodes";
55
import { errorsLogs } from "../../messages/errorsServerLogMessages";
6-
import { setContext } from "../../utils/vscodeCommandsUtils";
7-
import { DEEPCODE_CONTEXT, DEEPCODE_ERROR_CODES, DEEPCODE_VIEW_ERROR } from "../../constants/views";
6+
import { DEEPCODE_CONTEXT, DEEPCODE_ERROR_CODES } from "../../constants/views";
87
import { MAX_CONNECTION_RETRIES, CONNECTION_ERROR_RETRY_INTERVAL } from "../../constants/general";
98

109
abstract class ReportModule extends BaseDeepCodeModule implements DeepCode.ReportModuleInterface {
@@ -117,15 +116,15 @@ abstract class ReportModule extends BaseDeepCodeModule implements DeepCode.Repor
117116

118117
private async generalErrorHandler(): Promise<void> {
119118
this.transientErrors = 0;
120-
await setContext(DEEPCODE_CONTEXT.ERROR, DEEPCODE_ERROR_CODES.BLOCKING);
121-
await this.setLoadingBadge(DEEPCODE_VIEW_ERROR);
119+
await this.setContext(DEEPCODE_CONTEXT.ERROR, DEEPCODE_ERROR_CODES.BLOCKING);
120+
await this.setLoadingBadge(true);
122121
}
123122

124123
private async connectionErrorHandler(): Promise<void> {
125124
if (this.transientErrors > MAX_CONNECTION_RETRIES) return this.generalErrorHandler();
126125

127126
++this.transientErrors;
128-
await setContext(DEEPCODE_CONTEXT.ERROR, DEEPCODE_ERROR_CODES.TRANSIENT);
127+
await this.setContext(DEEPCODE_CONTEXT.ERROR, DEEPCODE_ERROR_CODES.TRANSIENT);
129128
setTimeout(() => {
130129
this.startExtension().catch((err) => this.processError(err, {
131130
message: errorsLogs.failedExecutionTransient,

src/deepcode/utils/pendingTask.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
export interface PendingTaskInterface {
2+
waiter: Promise<void>;
3+
isCompleted: boolean;
4+
complete(): void;
5+
};
6+
7+
export class PendingTask implements PendingTaskInterface {
8+
private _promise: Promise<void>;
9+
private _resolve: (() => void) | undefined;
10+
private _resolved: boolean;
11+
12+
constructor() {
13+
this._resolved = false;
14+
this._promise = new Promise((resolve) => {
15+
this._resolve = resolve;
16+
}).then((nullValue) => {
17+
this._resolved = true;
18+
});
19+
}
20+
21+
get waiter(): Promise<void> {
22+
return this._promise;
23+
}
24+
25+
get isCompleted(): boolean {
26+
return this._resolved;
27+
}
28+
29+
complete(): void {
30+
if (this._resolve !== undefined) this._resolve();
31+
}
32+
}

src/deepcode/utils/vscodeCommandsUtils.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ export const openDeepcodeViewContainer = async (): Promise<void> => {
1717
};
1818

1919
export const setContext = async (key: string, value: unknown): Promise<void> => {
20-
console.log("DeepCode context", key, value);
2120
await vscode.commands.executeCommand('setContext', `${DEEPCODE_CONTEXT_PREFIX}${key}`, value);
2221
};
2322

src/deepcode/view/IssueProvider.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,13 @@ export class IssueProvider extends NodeProvider {
4747
}
4848

4949
getRootChildren(): Node[] {
50+
this.extension.emitViewInitialized();
5051
const review: Node[] = [];
5152
let nIssues = 0;
52-
if (!this.extension.analyzer.deepcodeReview) return review;
53+
if (
54+
!this.extension.shouldShowAnalysis ||
55+
!this.extension.analyzer.deepcodeReview
56+
) return review;
5357
this.extension.analyzer.deepcodeReview.forEach(
5458
(uri: Uri, diagnostics: readonly Diagnostic[]): void => {
5559
const counts: ISeverityCounts = {

0 commit comments

Comments
 (0)