feat: 添加vscode编辑器

This commit is contained in:
dhx
2022-09-29 16:48:09 +08:00
parent a93bdac4ff
commit 150898ec1e
1126 changed files with 933348 additions and 0 deletions
@@ -0,0 +1,11 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export class SyncDescriptor {
constructor(ctor, staticArguments = [], supportsDelayedInstantiation = false) {
this.ctor = ctor;
this.staticArguments = staticArguments;
this.supportsDelayedInstantiation = supportsDelayedInstantiation;
}
}
@@ -0,0 +1,15 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { SyncDescriptor } from './descriptors.js';
const _registry = [];
export function registerSingleton(id, ctorOrDescriptor, supportsDelayedInstantiation) {
if (!(ctorOrDescriptor instanceof SyncDescriptor)) {
ctorOrDescriptor = new SyncDescriptor(ctorOrDescriptor, [], supportsDelayedInstantiation);
}
_registry.push([id, ctorOrDescriptor]);
}
export function getSingletonServiceDescriptors() {
return _registry;
}
@@ -0,0 +1,88 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export class Node {
constructor(data) {
this.incoming = new Map();
this.outgoing = new Map();
this.data = data;
}
}
export class Graph {
constructor(_hashFn) {
this._hashFn = _hashFn;
this._nodes = new Map();
// empty
}
roots() {
const ret = [];
for (const node of this._nodes.values()) {
if (node.outgoing.size === 0) {
ret.push(node);
}
}
return ret;
}
insertEdge(from, to) {
const fromNode = this.lookupOrInsertNode(from);
const toNode = this.lookupOrInsertNode(to);
fromNode.outgoing.set(this._hashFn(to), toNode);
toNode.incoming.set(this._hashFn(from), fromNode);
}
removeNode(data) {
const key = this._hashFn(data);
this._nodes.delete(key);
for (const node of this._nodes.values()) {
node.outgoing.delete(key);
node.incoming.delete(key);
}
}
lookupOrInsertNode(data) {
const key = this._hashFn(data);
let node = this._nodes.get(key);
if (!node) {
node = new Node(data);
this._nodes.set(key, node);
}
return node;
}
isEmpty() {
return this._nodes.size === 0;
}
toString() {
const data = [];
for (const [key, value] of this._nodes) {
data.push(`${key}, (incoming)[${[...value.incoming.keys()].join(', ')}], (outgoing)[${[...value.outgoing.keys()].join(',')}]`);
}
return data.join('\n');
}
/**
* This is brute force and slow and **only** be used
* to trouble shoot.
*/
findCycleSlow() {
for (const [id, node] of this._nodes) {
const seen = new Set([id]);
const res = this._findCycle(node, seen);
if (res) {
return res;
}
}
return undefined;
}
_findCycle(node, seen) {
for (const [id, outgoing] of node.outgoing) {
if (seen.has(id)) {
return [...seen, id].join(' -> ');
}
seen.add(id);
const value = this._findCycle(outgoing, seen);
if (value) {
return value;
}
seen.delete(id);
}
return undefined;
}
}
@@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// ------ internal util
export var _util;
(function (_util) {
_util.serviceIds = new Map();
_util.DI_TARGET = '$di$target';
_util.DI_DEPENDENCIES = '$di$dependencies';
function getServiceDependencies(ctor) {
return ctor[_util.DI_DEPENDENCIES] || [];
}
_util.getServiceDependencies = getServiceDependencies;
})(_util || (_util = {}));
export const IInstantiationService = createDecorator('instantiationService');
function storeServiceDependency(id, target, index) {
if (target[_util.DI_TARGET] === target) {
target[_util.DI_DEPENDENCIES].push({ id, index });
}
else {
target[_util.DI_DEPENDENCIES] = [{ id, index }];
target[_util.DI_TARGET] = target;
}
}
/**
* The *only* valid way to create a {{ServiceIdentifier}}.
*/
export function createDecorator(serviceId) {
if (_util.serviceIds.has(serviceId)) {
return _util.serviceIds.get(serviceId);
}
const id = function (target, key, index) {
if (arguments.length !== 3) {
throw new Error('@IServiceName-decorator can only be used to decorate a parameter');
}
storeServiceDependency(id, target, index);
};
id.toString = () => serviceId;
_util.serviceIds.set(serviceId, id);
return id;
}
@@ -0,0 +1,292 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IdleValue } from '../../../base/common/async.js';
import { illegalState } from '../../../base/common/errors.js';
import { SyncDescriptor } from './descriptors.js';
import { Graph } from './graph.js';
import { IInstantiationService, _util } from './instantiation.js';
import { ServiceCollection } from './serviceCollection.js';
// TRACING
const _enableTracing = false;
class CyclicDependencyError extends Error {
constructor(graph) {
var _a;
super('cyclic dependency between services');
this.message = (_a = graph.findCycleSlow()) !== null && _a !== void 0 ? _a : `UNABLE to detect cycle, dumping graph: \n${graph.toString()}`;
}
}
export class InstantiationService {
constructor(services = new ServiceCollection(), strict = false, parent) {
this._activeInstantiations = new Set();
this._services = services;
this._strict = strict;
this._parent = parent;
this._services.set(IInstantiationService, this);
}
createChild(services) {
return new InstantiationService(services, this._strict, this);
}
invokeFunction(fn, ...args) {
const _trace = Trace.traceInvocation(fn);
let _done = false;
try {
const accessor = {
get: (id) => {
if (_done) {
throw illegalState('service accessor is only valid during the invocation of its target method');
}
const result = this._getOrCreateServiceInstance(id, _trace);
if (!result) {
throw new Error(`[invokeFunction] unknown service '${id}'`);
}
return result;
}
};
return fn(accessor, ...args);
}
finally {
_done = true;
_trace.stop();
}
}
createInstance(ctorOrDescriptor, ...rest) {
let _trace;
let result;
if (ctorOrDescriptor instanceof SyncDescriptor) {
_trace = Trace.traceCreation(ctorOrDescriptor.ctor);
result = this._createInstance(ctorOrDescriptor.ctor, ctorOrDescriptor.staticArguments.concat(rest), _trace);
}
else {
_trace = Trace.traceCreation(ctorOrDescriptor);
result = this._createInstance(ctorOrDescriptor, rest, _trace);
}
_trace.stop();
return result;
}
_createInstance(ctor, args = [], _trace) {
// arguments defined by service decorators
const serviceDependencies = _util.getServiceDependencies(ctor).sort((a, b) => a.index - b.index);
const serviceArgs = [];
for (const dependency of serviceDependencies) {
const service = this._getOrCreateServiceInstance(dependency.id, _trace);
if (!service) {
this._throwIfStrict(`[createInstance] ${ctor.name} depends on UNKNOWN service ${dependency.id}.`, false);
}
serviceArgs.push(service);
}
const firstServiceArgPos = serviceDependencies.length > 0 ? serviceDependencies[0].index : args.length;
// check for argument mismatches, adjust static args if needed
if (args.length !== firstServiceArgPos) {
console.trace(`[createInstance] First service dependency of ${ctor.name} at position ${firstServiceArgPos + 1} conflicts with ${args.length} static arguments`);
const delta = firstServiceArgPos - args.length;
if (delta > 0) {
args = args.concat(new Array(delta));
}
else {
args = args.slice(0, firstServiceArgPos);
}
}
// now create the instance
return new ctor(...[...args, ...serviceArgs]);
}
_setServiceInstance(id, instance) {
if (this._services.get(id) instanceof SyncDescriptor) {
this._services.set(id, instance);
}
else if (this._parent) {
this._parent._setServiceInstance(id, instance);
}
else {
throw new Error('illegalState - setting UNKNOWN service instance');
}
}
_getServiceInstanceOrDescriptor(id) {
const instanceOrDesc = this._services.get(id);
if (!instanceOrDesc && this._parent) {
return this._parent._getServiceInstanceOrDescriptor(id);
}
else {
return instanceOrDesc;
}
}
_getOrCreateServiceInstance(id, _trace) {
const thing = this._getServiceInstanceOrDescriptor(id);
if (thing instanceof SyncDescriptor) {
return this._safeCreateAndCacheServiceInstance(id, thing, _trace.branch(id, true));
}
else {
_trace.branch(id, false);
return thing;
}
}
_safeCreateAndCacheServiceInstance(id, desc, _trace) {
if (this._activeInstantiations.has(id)) {
throw new Error(`illegal state - RECURSIVELY instantiating service '${id}'`);
}
this._activeInstantiations.add(id);
try {
return this._createAndCacheServiceInstance(id, desc, _trace);
}
finally {
this._activeInstantiations.delete(id);
}
}
_createAndCacheServiceInstance(id, desc, _trace) {
const graph = new Graph(data => data.id.toString());
let cycleCount = 0;
const stack = [{ id, desc, _trace }];
while (stack.length) {
const item = stack.pop();
graph.lookupOrInsertNode(item);
// a weak but working heuristic for cycle checks
if (cycleCount++ > 1000) {
throw new CyclicDependencyError(graph);
}
// check all dependencies for existence and if they need to be created first
for (const dependency of _util.getServiceDependencies(item.desc.ctor)) {
const instanceOrDesc = this._getServiceInstanceOrDescriptor(dependency.id);
if (!instanceOrDesc) {
this._throwIfStrict(`[createInstance] ${id} depends on ${dependency.id} which is NOT registered.`, true);
}
if (instanceOrDesc instanceof SyncDescriptor) {
const d = { id: dependency.id, desc: instanceOrDesc, _trace: item._trace.branch(dependency.id, true) };
graph.insertEdge(item, d);
stack.push(d);
}
}
}
while (true) {
const roots = graph.roots();
// if there is no more roots but still
// nodes in the graph we have a cycle
if (roots.length === 0) {
if (!graph.isEmpty()) {
throw new CyclicDependencyError(graph);
}
break;
}
for (const { data } of roots) {
// Repeat the check for this still being a service sync descriptor. That's because
// instantiating a dependency might have side-effect and recursively trigger instantiation
// so that some dependencies are now fullfilled already.
const instanceOrDesc = this._getServiceInstanceOrDescriptor(data.id);
if (instanceOrDesc instanceof SyncDescriptor) {
// create instance and overwrite the service collections
const instance = this._createServiceInstanceWithOwner(data.id, data.desc.ctor, data.desc.staticArguments, data.desc.supportsDelayedInstantiation, data._trace);
this._setServiceInstance(data.id, instance);
}
graph.removeNode(data);
}
}
return this._getServiceInstanceOrDescriptor(id);
}
_createServiceInstanceWithOwner(id, ctor, args = [], supportsDelayedInstantiation, _trace) {
if (this._services.get(id) instanceof SyncDescriptor) {
return this._createServiceInstance(ctor, args, supportsDelayedInstantiation, _trace);
}
else if (this._parent) {
return this._parent._createServiceInstanceWithOwner(id, ctor, args, supportsDelayedInstantiation, _trace);
}
else {
throw new Error(`illegalState - creating UNKNOWN service instance ${ctor.name}`);
}
}
_createServiceInstance(ctor, args = [], _supportsDelayedInstantiation, _trace) {
if (!_supportsDelayedInstantiation) {
// eager instantiation
return this._createInstance(ctor, args, _trace);
}
else {
// Return a proxy object that's backed by an idle value. That
// strategy is to instantiate services in our idle time or when actually
// needed but not when injected into a consumer
const idle = new IdleValue(() => this._createInstance(ctor, args, _trace));
return new Proxy(Object.create(null), {
get(target, key) {
if (key in target) {
return target[key];
}
const obj = idle.value;
let prop = obj[key];
if (typeof prop !== 'function') {
return prop;
}
prop = prop.bind(obj);
target[key] = prop;
return prop;
},
set(_target, p, value) {
idle.value[p] = value;
return true;
}
});
}
}
_throwIfStrict(msg, printWarning) {
if (printWarning) {
console.warn(msg);
}
if (this._strict) {
throw new Error(msg);
}
}
}
export class Trace {
constructor(type, name) {
this.type = type;
this.name = name;
this._start = Date.now();
this._dep = [];
}
static traceInvocation(ctor) {
return !_enableTracing ? Trace._None : new Trace(1 /* TraceType.Invocation */, ctor.name || ctor.toString().substring(0, 42).replace(/\n/g, ''));
}
static traceCreation(ctor) {
return !_enableTracing ? Trace._None : new Trace(0 /* TraceType.Creation */, ctor.name);
}
branch(id, first) {
const child = new Trace(2 /* TraceType.Branch */, id.toString());
this._dep.push([id, first, child]);
return child;
}
stop() {
const dur = Date.now() - this._start;
Trace._totals += dur;
let causedCreation = false;
function printChild(n, trace) {
const res = [];
const prefix = new Array(n + 1).join('\t');
for (const [id, first, child] of trace._dep) {
if (first && child) {
causedCreation = true;
res.push(`${prefix}CREATES -> ${id}`);
const nested = printChild(n + 1, child);
if (nested) {
res.push(nested);
}
}
else {
res.push(`${prefix}uses -> ${id}`);
}
}
return res.join('\n');
}
const lines = [
`${this.type === 0 /* TraceType.Creation */ ? 'CREATE' : 'CALL'} ${this.name}`,
`${printChild(1, this)}`,
`DONE, took ${dur.toFixed(2)}ms (grand total ${Trace._totals.toFixed(2)}ms)`
];
if (dur > 2 || causedCreation) {
console.log(lines.join('\n'));
}
}
}
Trace._None = new class extends Trace {
constructor() { super(-1, null); }
stop() { }
branch() { return this; }
};
Trace._totals = 0;
//#endregion
@@ -0,0 +1,20 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export class ServiceCollection {
constructor(...entries) {
this._entries = new Map();
for (const [id, service] of entries) {
this.set(id, service);
}
}
set(id, instanceOrDescriptor) {
const result = this._entries.get(id);
this._entries.set(id, instanceOrDescriptor);
return result;
}
get(id) {
return this._entries.get(id);
}
}