Skip to content

Commit 0e2a0f9

Browse files
committed
Prompt when there is an AMD module cycle
1 parent d63aa23 commit 0e2a0f9

File tree

4 files changed

+44
-4
lines changed

4 files changed

+44
-4
lines changed

src/typings/require.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ interface NodeRequire {
5050
onError: Function;
5151
__$__nodeRequire<T>(moduleName: string): T;
5252
getStats(): ReadonlyArray<LoaderEvent>;
53+
hasDependencyCycle(): boolean;
5354
define(amdModuleId: string, dependencies: string[], callback: (...args: any[]) => any): any;
5455
}
5556

src/vs/loader.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,31 +36,31 @@ var AMDLoader;
3636
this._detect();
3737
return this._isWindows;
3838
},
39-
enumerable: true,
39+
enumerable: false,
4040
configurable: true
4141
});
4242
Object.defineProperty(Environment.prototype, "isNode", {
4343
get: function () {
4444
this._detect();
4545
return this._isNode;
4646
},
47-
enumerable: true,
47+
enumerable: false,
4848
configurable: true
4949
});
5050
Object.defineProperty(Environment.prototype, "isElectronRenderer", {
5151
get: function () {
5252
this._detect();
5353
return this._isElectronRenderer;
5454
},
55-
enumerable: true,
55+
enumerable: false,
5656
configurable: true
5757
});
5858
Object.defineProperty(Environment.prototype, "isWebWorker", {
5959
get: function () {
6060
this._detect();
6161
return this._isWebWorker;
6262
},
63-
enumerable: true,
63+
enumerable: false,
6464
configurable: true
6565
});
6666
Environment.prototype._detect = function () {
@@ -199,6 +199,7 @@ var AMDLoader;
199199
return obj;
200200
}
201201
if (!Array.isArray(obj) && Object.getPrototypeOf(obj) !== Object.prototype) {
202+
// only clone "simple" objects
202203
return obj;
203204
}
204205
var result = Array.isArray(obj) ? [] : {};
@@ -1217,6 +1218,7 @@ var AMDLoader;
12171218
this._requireFunc = requireFunc;
12181219
this._moduleIdProvider = new ModuleIdProvider();
12191220
this._config = new AMDLoader.Configuration(this._env);
1221+
this._hasDependencyCycle = false;
12201222
this._modules2 = [];
12211223
this._knownModules2 = [];
12221224
this._inverseDependencies2 = [];
@@ -1561,6 +1563,9 @@ var AMDLoader;
15611563
result.getStats = function () {
15621564
return _this.getLoaderEvents();
15631565
};
1566+
result.hasDependencyCycle = function () {
1567+
return _this._hasDependencyCycle;
1568+
};
15641569
result.config = function (params, shouldOverwrite) {
15651570
if (shouldOverwrite === void 0) { shouldOverwrite = false; }
15661571
_this.configure(params, shouldOverwrite);
@@ -1666,6 +1671,7 @@ var AMDLoader;
16661671
continue;
16671672
}
16681673
if (this._hasDependencyPath(dependency.id, module.id)) {
1674+
this._hasDependencyCycle = true;
16691675
console.warn('There is a dependency cycle between \'' + this._moduleIdProvider.getStrModuleId(dependency.id) + '\' and \'' + this._moduleIdProvider.getStrModuleId(module.id) + '\'. The cyclic path follows:');
16701676
var cyclePath = this._findCyclePath(dependency.id, module.id, 0) || [];
16711677
cyclePath.reverse();

src/vs/workbench/electron-sandbox/desktop.contribution.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import { INativeHostService } from 'vs/platform/native/electron-sandbox/native';
2222
import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
2323
import product from 'vs/platform/product/common/product';
2424
import { IJSONSchema } from 'vs/base/common/jsonSchema';
25+
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
26+
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
27+
import { LoaderCyclicChecker } from 'vs/workbench/electron-sandbox/loaderCyclicChecker';
2528

2629
// Actions
2730
(function registerActions(): void {
@@ -97,6 +100,9 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema';
97100
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_I,
98101
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_I }
99102
});
103+
104+
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(LoaderCyclicChecker, LifecyclePhase.Ready);
105+
100106
})();
101107

102108
// Actions: Runtime Arguments
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as nls from 'vs/nls';
7+
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
8+
import { Disposable } from 'vs/base/common/lifecycle';
9+
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
10+
import { Severity } from 'vs/platform/notification/common/notification';
11+
import { INativeHostService } from 'vs/platform/native/electron-sandbox/native';
12+
13+
export class LoaderCyclicChecker extends Disposable implements IWorkbenchContribution {
14+
15+
constructor(
16+
@IDialogService dialogService: IDialogService,
17+
@INativeHostService nativeHostService: INativeHostService,
18+
) {
19+
super();
20+
21+
if (require.hasDependencyCycle()) {
22+
dialogService.show(Severity.Error, nls.localize('loaderCycle', "There is a dependency cycle in the AMD modules"), [nls.localize('ok', "OK")]);
23+
nativeHostService.openDevTools();
24+
}
25+
}
26+
}
27+

0 commit comments

Comments
 (0)