-
Notifications
You must be signed in to change notification settings - Fork 2.5k
/
Copy pathplugin-vscode-init.ts
80 lines (66 loc) · 3.03 KB
/
plugin-vscode-init.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// *****************************************************************************
// Copyright (C) 2018-2019 Red Hat, Inc.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************
/* eslint-disable @typescript-eslint/no-explicit-any */
import * as theia from '@theia/plugin';
import { BackendInitializationFn, PluginAPIFactory, Plugin, emptyPlugin } from '@theia/plugin-ext';
import { VSCODE_DEFAULT_API_VERSION } from '../common/plugin-vscode-types';
process.env['VSCODE_PID'] = process.env['THEIA_PARENT_PID'];
const pluginsApiImpl = new Map<string, typeof theia>();
const plugins = new Array<Plugin>();
let defaultApi: typeof theia;
let isLoadOverride = false;
let pluginApiFactory: PluginAPIFactory;
export const doInitialization: BackendInitializationFn = (apiFactory: PluginAPIFactory, plugin: Plugin) => {
pluginsApiImpl.set(plugin.model.id, createVSCodeAPI(apiFactory, plugin));
plugins.push(plugin);
pluginApiFactory = apiFactory;
if (!isLoadOverride) {
overrideInternalLoad();
isLoadOverride = true;
}
};
function createVSCodeAPI(apiFactory: PluginAPIFactory, plugin: Plugin): typeof theia {
const vscode = apiFactory(plugin);
// override the version for vscode to be a VSCode version
(<any>vscode).version = process.env['VSCODE_API_VERSION'] || VSCODE_DEFAULT_API_VERSION;
return vscode;
}
function overrideInternalLoad(): void {
const module = require('module');
const vscodeModuleName = 'vscode';
// save original load method
const internalLoad = module._load;
// if we try to resolve theia module, return the filename entry to use cache.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
module._load = function (request: string, parent: any, isMain: {}): any {
if (request !== vscodeModuleName) {
return internalLoad.apply(this, arguments);
}
const plugin = findPlugin(parent.filename);
if (plugin) {
const apiImpl = pluginsApiImpl.get(plugin.model.id);
return apiImpl;
}
if (!defaultApi) {
console.warn(`Could not identify plugin for 'Theia' require call from ${parent.filename}`);
defaultApi = createVSCodeAPI(pluginApiFactory, emptyPlugin);
}
return defaultApi;
};
}
function findPlugin(filePath: string): Plugin | undefined {
return plugins.find(plugin => filePath.startsWith(plugin.pluginFolder));
}