@spyglassmc/core 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/common/TwoWayMap.d.ts +21 -0
- package/lib/common/TwoWayMap.js +75 -0
- package/lib/common/index.js +5 -1
- package/lib/common/util.d.ts +3 -20
- package/lib/common/util.js +6 -40
- package/lib/index.js +5 -1
- package/lib/node/LiteralNode.d.ts +1 -1
- package/lib/node/LiteralNode.js +1 -1
- package/lib/node/ResourceLocationNode.d.ts +2 -4
- package/lib/node/Sequence.d.ts +2 -1
- package/lib/node/Sequence.js +3 -2
- package/lib/node/SymbolNode.d.ts +1 -1
- package/lib/node/SymbolNode.js +1 -1
- package/lib/node/index.js +5 -1
- package/lib/parser/float.js +1 -1
- package/lib/parser/index.js +5 -1
- package/lib/parser/integer.js +1 -1
- package/lib/parser/long.js +1 -1
- package/lib/parser/string.js +4 -2
- package/lib/parser/util.d.ts +25 -7
- package/lib/parser/util.js +50 -17
- package/lib/processor/checker/builtin.js +1 -1
- package/lib/processor/checker/index.js +5 -1
- package/lib/processor/colorizer/index.js +5 -1
- package/lib/processor/completer/builtin.js +16 -16
- package/lib/processor/completer/index.js +5 -1
- package/lib/processor/formatter/index.js +5 -1
- package/lib/processor/index.js +5 -1
- package/lib/processor/linter/builtin/undeclaredSymbol.js +3 -3
- package/lib/processor/linter/builtin.js +1 -1
- package/lib/processor/linter/index.js +5 -1
- package/lib/service/Config.d.ts +6 -4
- package/lib/service/Config.js +6 -6
- package/lib/service/Context.d.ts +2 -2
- package/lib/service/Context.js +1 -0
- package/lib/service/Downloader.d.ts +1 -0
- package/lib/service/Downloader.js +4 -0
- package/lib/service/ErrorReporter.js +1 -1
- package/lib/service/FileService.d.ts +29 -4
- package/lib/service/FileService.js +82 -19
- package/lib/service/Project.d.ts +1 -0
- package/lib/service/Project.js +23 -11
- package/lib/service/Service.d.ts +2 -2
- package/lib/service/Service.js +25 -15
- package/lib/service/fileUtil.d.ts +15 -5
- package/lib/service/fileUtil.js +39 -4
- package/lib/service/index.js +5 -1
- package/lib/source/LanguageError.js +1 -1
- package/lib/source/Source.d.ts +6 -1
- package/lib/source/Source.js +30 -2
- package/lib/source/index.js +5 -1
- package/lib/symbol/Symbol.d.ts +10 -10
- package/lib/symbol/Symbol.js +7 -6
- package/lib/symbol/SymbolUtil.d.ts +1 -8
- package/lib/symbol/SymbolUtil.js +12 -12
- package/lib/symbol/index.js +5 -1
- package/package.json +2 -2
|
@@ -28,8 +28,8 @@ exports.dispatch = dispatch;
|
|
|
28
28
|
exports.fallback = exports.dispatch;
|
|
29
29
|
const boolean = (node, ctx) => {
|
|
30
30
|
return [
|
|
31
|
-
Completer_1.CompletionItem.create('false', node, { kind: 21 /* Constant */ }),
|
|
32
|
-
Completer_1.CompletionItem.create('true', node, { kind: 21 /* Constant */ }),
|
|
31
|
+
Completer_1.CompletionItem.create('false', node, { kind: 21 /* CompletionKind.Constant */ }),
|
|
32
|
+
Completer_1.CompletionItem.create('true', node, { kind: 21 /* CompletionKind.Constant */ }),
|
|
33
33
|
];
|
|
34
34
|
};
|
|
35
35
|
exports.boolean = boolean;
|
|
@@ -43,17 +43,17 @@ const file = (node, ctx) => {
|
|
|
43
43
|
exports.file = file;
|
|
44
44
|
const literal = node => {
|
|
45
45
|
const kind = new Map([
|
|
46
|
-
['enum', 13 /* Enum */],
|
|
47
|
-
['enumMember', 20 /* EnumMember */],
|
|
48
|
-
['function', 3 /* Function */],
|
|
49
|
-
['keyword', 14 /* Keyword */],
|
|
50
|
-
['literal', 14 /* Keyword */],
|
|
51
|
-
['number', 21 /* Constant */],
|
|
52
|
-
['operator', 24 /* Operator */],
|
|
53
|
-
['property', 10 /* Property */],
|
|
54
|
-
['resourceLocation', 17 /* File */],
|
|
55
|
-
['variable', 6 /* Variable */],
|
|
56
|
-
]).get(node.options.colorTokenType ?? 'keyword') ?? 14 /* Keyword */;
|
|
46
|
+
['enum', 13 /* CompletionKind.Enum */],
|
|
47
|
+
['enumMember', 20 /* CompletionKind.EnumMember */],
|
|
48
|
+
['function', 3 /* CompletionKind.Function */],
|
|
49
|
+
['keyword', 14 /* CompletionKind.Keyword */],
|
|
50
|
+
['literal', 14 /* CompletionKind.Keyword */],
|
|
51
|
+
['number', 21 /* CompletionKind.Constant */],
|
|
52
|
+
['operator', 24 /* CompletionKind.Operator */],
|
|
53
|
+
['property', 10 /* CompletionKind.Property */],
|
|
54
|
+
['resourceLocation', 17 /* CompletionKind.File */],
|
|
55
|
+
['variable', 6 /* CompletionKind.Variable */],
|
|
56
|
+
]).get(node.options.colorTokenType ?? 'keyword') ?? 14 /* CompletionKind.Keyword */;
|
|
57
57
|
return node.options.pool.map(v => Completer_1.CompletionItem.create(v, node, { kind })) ?? [];
|
|
58
58
|
};
|
|
59
59
|
exports.literal = literal;
|
|
@@ -134,7 +134,7 @@ const resourceLocation = (node, ctx) => {
|
|
|
134
134
|
.map(v => `${common_1.ResourceLocation.TagPrefix}${v}`)
|
|
135
135
|
: [],
|
|
136
136
|
];
|
|
137
|
-
return pool.map(v => Completer_1.CompletionItem.create(v, node, { kind: 3 /* Function */ }));
|
|
137
|
+
return pool.map(v => Completer_1.CompletionItem.create(v, node, { kind: 3 /* CompletionKind.Function */ }));
|
|
138
138
|
};
|
|
139
139
|
exports.resourceLocation = resourceLocation;
|
|
140
140
|
const string = (node, ctx) => {
|
|
@@ -145,7 +145,7 @@ const string = (node, ctx) => {
|
|
|
145
145
|
if (node.options.quotes && node.value === '') {
|
|
146
146
|
return node.options.quotes.map(q => Completer_1.CompletionItem.create(`${q}${q}`, node, {
|
|
147
147
|
insertText: `${q}$1${q}`,
|
|
148
|
-
kind: 12 /* Value */,
|
|
148
|
+
kind: 12 /* CompletionKind.Value */,
|
|
149
149
|
}));
|
|
150
150
|
}
|
|
151
151
|
return [];
|
|
@@ -154,7 +154,7 @@ exports.string = string;
|
|
|
154
154
|
const symbol = (node, ctx) => {
|
|
155
155
|
return Object
|
|
156
156
|
.keys(ctx.symbols.query(ctx.doc, node.options.category, ...node.options.parentPath ?? []).visibleMembers)
|
|
157
|
-
.map(v => Completer_1.CompletionItem.create(v, node, { kind: 6 /* Variable */ }));
|
|
157
|
+
.map(v => Completer_1.CompletionItem.create(v, node, { kind: 6 /* CompletionKind.Variable */ }));
|
|
158
158
|
};
|
|
159
159
|
exports.symbol = symbol;
|
|
160
160
|
function registerCompleters(meta) {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
package/lib/processor/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -63,11 +63,11 @@ function getAction(config, symbol, ctx) {
|
|
|
63
63
|
function getVisibility(input) {
|
|
64
64
|
switch (input) {
|
|
65
65
|
case 'block':
|
|
66
|
-
return 0 /* Block */;
|
|
66
|
+
return 0 /* SymbolVisibility.Block */;
|
|
67
67
|
case 'file':
|
|
68
|
-
return 1 /* File */;
|
|
68
|
+
return 1 /* SymbolVisibility.File */;
|
|
69
69
|
case 'public':
|
|
70
|
-
return 2 /* Public */;
|
|
70
|
+
return 2 /* SymbolVisibility.Public */;
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
//# sourceMappingURL=undeclaredSymbol.js.map
|
|
@@ -108,7 +108,7 @@ function registerLinters(meta) {
|
|
|
108
108
|
meta.registerLinter('undeclaredSymbol', {
|
|
109
109
|
configValidator: configValidator.symbolLinterConfig,
|
|
110
110
|
linter: undeclaredSymbol_1.undeclaredSymbol,
|
|
111
|
-
nodePredicate: n => n.symbol && !symbol_1.
|
|
111
|
+
nodePredicate: n => n.symbol && !symbol_1.McdocCategories.includes(n.symbol.category),
|
|
112
112
|
});
|
|
113
113
|
}
|
|
114
114
|
exports.registerLinters = registerLinters;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
package/lib/service/Config.d.ts
CHANGED
|
@@ -24,15 +24,17 @@ export interface Config {
|
|
|
24
24
|
}
|
|
25
25
|
export interface EnvConfig {
|
|
26
26
|
/**
|
|
27
|
-
* Where to download data like `mcmeta` or `
|
|
27
|
+
* Where to download data like `mcmeta` or `vanilla-mcdoc` from (case-insensitive).
|
|
28
28
|
*
|
|
29
|
-
* * `GitHub`
|
|
30
|
-
* * `
|
|
29
|
+
* * `GitHub`: Recommended, unless you have trouble connecting to `raw.githubusercontent.com`.
|
|
30
|
+
* * `fastly`
|
|
31
|
+
* * `jsDelivr`
|
|
32
|
+
* * A custom URL, with placeholder variables: `${user}`, `${repo}`, `${tag}`, and `${path}`.
|
|
31
33
|
*/
|
|
32
34
|
dataSource: string;
|
|
33
35
|
/**
|
|
34
36
|
* A list of data packs the current project depends on. Each value in this array can be either an absolute file path
|
|
35
|
-
* to a data pack folder or data pack archive (e.g. `.zip` or `.tar.gz`), or a special string like `@
|
|
37
|
+
* to a data pack folder or data pack archive (e.g. `.zip` or `.tar.gz`), or a special string like `@vanilla-mcdoc`.
|
|
36
38
|
*/
|
|
37
39
|
dependencies: string[];
|
|
38
40
|
feature: {
|
package/lib/service/Config.js
CHANGED
|
@@ -21,13 +21,13 @@ var LinterSeverity;
|
|
|
21
21
|
function toErrorSeverity(value) {
|
|
22
22
|
switch (value) {
|
|
23
23
|
case 'error':
|
|
24
|
-
return 3 /* Error */;
|
|
24
|
+
return 3 /* ErrorSeverity.Error */;
|
|
25
25
|
case 'hint':
|
|
26
|
-
return 0 /* Hint */;
|
|
26
|
+
return 0 /* ErrorSeverity.Hint */;
|
|
27
27
|
case 'information':
|
|
28
|
-
return 1 /* Information */;
|
|
28
|
+
return 1 /* ErrorSeverity.Information */;
|
|
29
29
|
case 'warning':
|
|
30
|
-
return 2 /* Warning */;
|
|
30
|
+
return 2 /* ErrorSeverity.Warning */;
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
LinterSeverity.toErrorSeverity = toErrorSeverity;
|
|
@@ -51,7 +51,7 @@ var LinterConfigValue;
|
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
return {
|
|
54
|
-
ruleSeverity: 2 /* Warning */,
|
|
54
|
+
ruleSeverity: 2 /* ErrorSeverity.Warning */,
|
|
55
55
|
ruleValue: value,
|
|
56
56
|
};
|
|
57
57
|
}
|
|
@@ -118,7 +118,7 @@ exports.VanillaConfig = {
|
|
|
118
118
|
env: {
|
|
119
119
|
dataSource: 'GitHub',
|
|
120
120
|
dependencies: [
|
|
121
|
-
'@
|
|
121
|
+
'@vanilla-mcdoc',
|
|
122
122
|
],
|
|
123
123
|
feature: {
|
|
124
124
|
codeActions: true,
|
package/lib/service/Context.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type { RootUriString } from './fileUtil';
|
|
|
10
10
|
import type { Logger } from './Logger';
|
|
11
11
|
import type { MetaRegistry } from './MetaRegistry';
|
|
12
12
|
import { Operations } from './Operations';
|
|
13
|
+
import type { ProfilerFactory } from './Profiler';
|
|
13
14
|
import type { DocAndNode, ProjectData } from './Project';
|
|
14
15
|
export interface ContextBase {
|
|
15
16
|
fs: FileService;
|
|
@@ -17,6 +18,7 @@ export interface ContextBase {
|
|
|
17
18
|
global: SymbolTable;
|
|
18
19
|
logger: Logger;
|
|
19
20
|
meta: MetaRegistry;
|
|
21
|
+
profilers: ProfilerFactory;
|
|
20
22
|
project: Record<string, string>;
|
|
21
23
|
roots: readonly RootUriString[];
|
|
22
24
|
}
|
|
@@ -27,7 +29,6 @@ export interface ParserContext extends ContextBase {
|
|
|
27
29
|
config: Config;
|
|
28
30
|
doc: TextDocument;
|
|
29
31
|
err: ErrorReporter;
|
|
30
|
-
/** @deprecated */
|
|
31
32
|
symbols: SymbolUtil;
|
|
32
33
|
}
|
|
33
34
|
interface ParserContextOptions {
|
|
@@ -41,7 +42,6 @@ export interface ProcessorContext extends ContextBase {
|
|
|
41
42
|
config: Config;
|
|
42
43
|
doc: TextDocument;
|
|
43
44
|
src: ReadonlySource;
|
|
44
|
-
/** @deprecated */
|
|
45
45
|
symbols: SymbolUtil;
|
|
46
46
|
}
|
|
47
47
|
interface ProcessorContextOptions {
|
package/lib/service/Context.js
CHANGED
|
@@ -3,6 +3,7 @@ import type { Logger } from './Logger';
|
|
|
3
3
|
declare type RemoteProtocol = 'http:' | 'https:';
|
|
4
4
|
export declare type RemoteUriString = `${RemoteProtocol}${string}`;
|
|
5
5
|
export declare namespace RemoteUriString {
|
|
6
|
+
function is(value: string): value is RemoteUriString;
|
|
6
7
|
function getProtocol(uri: RemoteUriString): RemoteProtocol;
|
|
7
8
|
}
|
|
8
9
|
export interface DownloaderDownloadOut {
|
|
@@ -18,6 +18,10 @@ const common_1 = require("../common");
|
|
|
18
18
|
const fileUtil_1 = require("./fileUtil");
|
|
19
19
|
var RemoteUriString;
|
|
20
20
|
(function (RemoteUriString) {
|
|
21
|
+
function is(value) {
|
|
22
|
+
return value.startsWith('http:') || value.startsWith('https:');
|
|
23
|
+
}
|
|
24
|
+
RemoteUriString.is = is;
|
|
21
25
|
function getProtocol(uri) {
|
|
22
26
|
return uri.slice(0, uri.indexOf(':') + 1);
|
|
23
27
|
}
|
|
@@ -10,7 +10,7 @@ class ErrorReporter {
|
|
|
10
10
|
/**
|
|
11
11
|
* Reports a new error.
|
|
12
12
|
*/
|
|
13
|
-
report(message, range, severity = 3 /* Error */, info) {
|
|
13
|
+
report(message, range, severity = 3 /* ErrorSeverity.Error */, info) {
|
|
14
14
|
this.errors.push(source_1.LanguageError.create(message, source_1.Range.get(range), severity, info));
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
@@ -37,12 +37,28 @@ export interface FileService extends UriProtocolSupporter {
|
|
|
37
37
|
* Unregister the supported associated with `protocol`. Nothing happens if the `protocol` isn't supported.
|
|
38
38
|
*/
|
|
39
39
|
unregister(protocol: Protocol): void;
|
|
40
|
+
/**
|
|
41
|
+
* Map the item at `uri` to physical disk.
|
|
42
|
+
*
|
|
43
|
+
* @returns The `file:` URI of the mapped file, or `undefined` if it cannot be mapped.
|
|
44
|
+
*/
|
|
45
|
+
mapToDisk(uri: string): Promise<string | undefined>;
|
|
46
|
+
/**
|
|
47
|
+
* Map the item at `uri` from physical disk back to a (virtual) URI used by Spyglass internally.
|
|
48
|
+
*/
|
|
49
|
+
mapFromDisk(uri: string): string;
|
|
40
50
|
}
|
|
41
51
|
export declare namespace FileService {
|
|
42
|
-
function create(): FileService;
|
|
52
|
+
function create(cacheRoot: string): FileService;
|
|
43
53
|
}
|
|
44
54
|
export declare class FileServiceImpl implements FileService {
|
|
55
|
+
private readonly virtualUrisRoot?;
|
|
45
56
|
private readonly supporters;
|
|
57
|
+
/**
|
|
58
|
+
* A two-way map from mapped physical URIs to virtual URIs.
|
|
59
|
+
*/
|
|
60
|
+
private readonly map;
|
|
61
|
+
constructor(virtualUrisRoot?: `${string}/` | undefined);
|
|
46
62
|
register(protocol: Protocol, supporter: UriProtocolSupporter, force?: boolean): void;
|
|
47
63
|
unregister(protocol: Protocol): void;
|
|
48
64
|
/**
|
|
@@ -61,6 +77,8 @@ export declare class FileServiceImpl implements FileService {
|
|
|
61
77
|
readFile(uri: string): Promise<Buffer>;
|
|
62
78
|
listFiles(): Generator<string, void, undefined>;
|
|
63
79
|
listRoots(): Generator<`${string}/`, void, undefined>;
|
|
80
|
+
mapToDisk(virtualUri: string): Promise<string | undefined>;
|
|
81
|
+
mapFromDisk(mappedUri: string): string;
|
|
64
82
|
}
|
|
65
83
|
export declare class FileUriSupporter implements UriProtocolSupporter {
|
|
66
84
|
private readonly roots;
|
|
@@ -71,12 +89,14 @@ export declare class FileUriSupporter implements UriProtocolSupporter {
|
|
|
71
89
|
readFile(uri: string): Promise<Buffer>;
|
|
72
90
|
listFiles(): Generator<string, void, undefined>;
|
|
73
91
|
listRoots(): `${string}/`[];
|
|
92
|
+
mapToDisk(uri: string): Promise<string | undefined>;
|
|
74
93
|
private static rootUriToGlob;
|
|
75
94
|
static create(dependencies: readonly Dependency[], logger: Logger): Promise<FileUriSupporter>;
|
|
76
95
|
}
|
|
77
|
-
export declare class
|
|
96
|
+
export declare class ArchiveUriSupporter implements UriProtocolSupporter {
|
|
78
97
|
private readonly entries;
|
|
79
|
-
readonly protocol = "
|
|
98
|
+
readonly protocol = "archive:";
|
|
99
|
+
static readonly Protocol = "archive:";
|
|
80
100
|
private static readonly SupportedArchiveExtnames;
|
|
81
101
|
/**
|
|
82
102
|
* @param entries A map from archive URIs to unzipped entries.
|
|
@@ -90,7 +110,12 @@ export declare class SpyglassUriSupporter implements UriProtocolSupporter {
|
|
|
90
110
|
private getDataInArchive;
|
|
91
111
|
listFiles(): Generator<string, void, unknown>;
|
|
92
112
|
listRoots(): Generator<`${string}/`, void, unknown>;
|
|
93
|
-
static
|
|
113
|
+
private static getUri;
|
|
114
|
+
/**
|
|
115
|
+
* @throws When `uri` has the wrong protocol or hostname.
|
|
116
|
+
*/
|
|
117
|
+
private static decodeUri;
|
|
118
|
+
static create(dependencies: readonly Dependency[], logger: Logger, checksums: Record<RootUriString, string>): Promise<ArchiveUriSupporter>;
|
|
94
119
|
}
|
|
95
120
|
export {};
|
|
96
121
|
//# sourceMappingURL=FileService.d.ts.map
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
/* istanbul ignore file */
|
|
3
3
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
4
|
if (k2 === undefined) k2 = k;
|
|
5
|
-
Object.
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
6
10
|
}) : (function(o, m, k, k2) {
|
|
7
11
|
if (k2 === undefined) k2 = k;
|
|
8
12
|
o[k2] = m[k];
|
|
@@ -23,25 +27,32 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
23
27
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
28
|
};
|
|
25
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.
|
|
30
|
+
exports.ArchiveUriSupporter = exports.FileUriSupporter = exports.FileServiceImpl = exports.FileService = void 0;
|
|
27
31
|
const crypto_1 = __importDefault(require("crypto"));
|
|
28
32
|
const decompress_1 = __importDefault(require("decompress"));
|
|
29
33
|
const fs_1 = __importStar(require("fs"));
|
|
30
34
|
const globby_1 = __importDefault(require("globby"));
|
|
35
|
+
const path_1 = __importDefault(require("path"));
|
|
31
36
|
const common_1 = require("../common");
|
|
37
|
+
const TwoWayMap_1 = require("../common/TwoWayMap");
|
|
32
38
|
const fileUtil_1 = require("./fileUtil");
|
|
33
39
|
const HashAlgorithm = 'sha1';
|
|
34
40
|
var FileService;
|
|
35
41
|
(function (FileService) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return
|
|
42
|
+
function create(cacheRoot) {
|
|
43
|
+
const virtualUrisRoot = fileUtil_1.fileUtil.ensureEndingSlash(fileUtil_1.fileUtil.pathToFileUri(path_1.default.join(cacheRoot, 'virtual-uris')));
|
|
44
|
+
return new FileServiceImpl(virtualUrisRoot);
|
|
39
45
|
}
|
|
40
46
|
FileService.create = create;
|
|
41
47
|
})(FileService = exports.FileService || (exports.FileService = {}));
|
|
42
48
|
class FileServiceImpl {
|
|
43
|
-
constructor() {
|
|
49
|
+
constructor(virtualUrisRoot) {
|
|
50
|
+
this.virtualUrisRoot = virtualUrisRoot;
|
|
44
51
|
this.supporters = new Map();
|
|
52
|
+
/**
|
|
53
|
+
* A two-way map from mapped physical URIs to virtual URIs.
|
|
54
|
+
*/
|
|
55
|
+
this.map = new TwoWayMap_1.TwoWayMap();
|
|
45
56
|
}
|
|
46
57
|
register(protocol, supporter, force = false) {
|
|
47
58
|
if (!force && this.supporters.has(protocol)) {
|
|
@@ -88,6 +99,34 @@ class FileServiceImpl {
|
|
|
88
99
|
yield* supporter.listRoots();
|
|
89
100
|
}
|
|
90
101
|
}
|
|
102
|
+
async mapToDisk(virtualUri) {
|
|
103
|
+
if (fileUtil_1.fileUtil.isFileUri(virtualUri)) {
|
|
104
|
+
return virtualUri;
|
|
105
|
+
}
|
|
106
|
+
if (!this.virtualUrisRoot) {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
let mappedUri = this.map.getKey(virtualUri);
|
|
111
|
+
if (mappedUri === undefined) {
|
|
112
|
+
mappedUri = `${this.virtualUrisRoot}${(0, common_1.getSha1)(virtualUri)}/${fileUtil_1.fileUtil.basename(virtualUri)}`;
|
|
113
|
+
const buffer = await this.readFile(virtualUri);
|
|
114
|
+
await fileUtil_1.fileUtil.writeFile(mappedUri, buffer, 0o444);
|
|
115
|
+
this.map.set(mappedUri, virtualUri);
|
|
116
|
+
}
|
|
117
|
+
return mappedUri;
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
// Ignored.
|
|
121
|
+
}
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
mapFromDisk(mappedUri) {
|
|
125
|
+
if (!this.virtualUrisRoot) {
|
|
126
|
+
return mappedUri;
|
|
127
|
+
}
|
|
128
|
+
return this.map.get(mappedUri) ?? mappedUri;
|
|
129
|
+
}
|
|
91
130
|
}
|
|
92
131
|
exports.FileServiceImpl = FileServiceImpl;
|
|
93
132
|
class FileUriSupporter {
|
|
@@ -110,6 +149,9 @@ class FileUriSupporter {
|
|
|
110
149
|
listRoots() {
|
|
111
150
|
return this.roots;
|
|
112
151
|
}
|
|
152
|
+
async mapToDisk(uri) {
|
|
153
|
+
return uri;
|
|
154
|
+
}
|
|
113
155
|
static rootUriToGlob(root) {
|
|
114
156
|
return fileUtil_1.fileUtil.fileUriToPath(root) + '**/*';
|
|
115
157
|
}
|
|
@@ -132,33 +174,38 @@ class FileUriSupporter {
|
|
|
132
174
|
}
|
|
133
175
|
}
|
|
134
176
|
exports.FileUriSupporter = FileUriSupporter;
|
|
135
|
-
|
|
177
|
+
// namespace ArchiveUri {
|
|
178
|
+
// export function is(uri: Uri): boolean {
|
|
179
|
+
// return uri.protocol === Protocol && uri.hostname === Hostname
|
|
180
|
+
// }
|
|
181
|
+
// }
|
|
182
|
+
class ArchiveUriSupporter {
|
|
136
183
|
/**
|
|
137
184
|
* @param entries A map from archive URIs to unzipped entries.
|
|
138
185
|
*/
|
|
139
186
|
constructor(entries) {
|
|
140
187
|
this.entries = entries;
|
|
141
|
-
this.protocol =
|
|
188
|
+
this.protocol = ArchiveUriSupporter.Protocol;
|
|
142
189
|
}
|
|
143
190
|
async hash(uri) {
|
|
144
|
-
const { archiveUri, pathInArchive } =
|
|
191
|
+
const { archiveUri, pathInArchive } = ArchiveUriSupporter.decodeUri(new common_1.Uri(uri));
|
|
145
192
|
if (!pathInArchive) {
|
|
146
193
|
// Hash the archive itself.
|
|
147
194
|
return hashFile(archiveUri);
|
|
148
195
|
}
|
|
149
196
|
else {
|
|
150
197
|
// Hash the corresponding file.
|
|
151
|
-
return (0, common_1.getSha1)(
|
|
198
|
+
return (0, common_1.getSha1)(this.getDataInArchive(archiveUri, pathInArchive));
|
|
152
199
|
}
|
|
153
200
|
}
|
|
154
201
|
async readFile(uri) {
|
|
155
|
-
const { archiveUri, pathInArchive } =
|
|
202
|
+
const { archiveUri, pathInArchive } = ArchiveUriSupporter.decodeUri(new common_1.Uri(uri));
|
|
156
203
|
return this.getDataInArchive(archiveUri, pathInArchive);
|
|
157
204
|
}
|
|
158
205
|
/**
|
|
159
206
|
* @throws
|
|
160
207
|
*/
|
|
161
|
-
|
|
208
|
+
getDataInArchive(archiveUri, pathInArchive) {
|
|
162
209
|
const entries = this.entries.get(archiveUri);
|
|
163
210
|
if (!entries) {
|
|
164
211
|
throw new Error(`Archive “${archiveUri}” has not been loaded into the memory`);
|
|
@@ -175,21 +222,36 @@ class SpyglassUriSupporter {
|
|
|
175
222
|
*listFiles() {
|
|
176
223
|
for (const [archiveUri, files] of this.entries.entries()) {
|
|
177
224
|
for (const file of files.values()) {
|
|
178
|
-
yield
|
|
225
|
+
yield ArchiveUriSupporter.getUri(archiveUri, file.path);
|
|
179
226
|
}
|
|
180
227
|
}
|
|
181
228
|
}
|
|
182
229
|
*listRoots() {
|
|
183
230
|
for (const archiveUri of this.entries.keys()) {
|
|
184
|
-
yield
|
|
231
|
+
yield ArchiveUriSupporter.getUri(archiveUri);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
static getUri(archiveUri, pathInArchive = '') {
|
|
235
|
+
return `${ArchiveUriSupporter.Protocol}//${encodeURIComponent(archiveUri)}/${pathInArchive.replace(/\\/g, '/')}`;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* @throws When `uri` has the wrong protocol or hostname.
|
|
239
|
+
*/
|
|
240
|
+
static decodeUri(uri) {
|
|
241
|
+
if (uri.protocol !== ArchiveUriSupporter.Protocol) {
|
|
242
|
+
throw new Error(`Expected protocol “${ArchiveUriSupporter.Protocol}” in “${uri}”`);
|
|
185
243
|
}
|
|
244
|
+
return {
|
|
245
|
+
archiveUri: decodeURIComponent(uri.hostname),
|
|
246
|
+
pathInArchive: uri.pathname.charAt(0) === '/' ? uri.pathname.slice(1) : uri.pathname,
|
|
247
|
+
};
|
|
186
248
|
}
|
|
187
249
|
static async create(dependencies, logger, checksums) {
|
|
188
250
|
const entries = new Map();
|
|
189
251
|
for (const { uri, info } of dependencies) {
|
|
190
252
|
try {
|
|
191
|
-
if (uri.startsWith('file:') &&
|
|
192
|
-
const rootUri =
|
|
253
|
+
if (uri.startsWith('file:') && ArchiveUriSupporter.SupportedArchiveExtnames.some(ext => uri.endsWith(ext)) && (await fs_1.promises.stat(new common_1.Uri(uri))).isFile()) {
|
|
254
|
+
const rootUri = ArchiveUriSupporter.getUri(uri);
|
|
193
255
|
const cachedChecksum = checksums[rootUri];
|
|
194
256
|
if (cachedChecksum !== undefined) {
|
|
195
257
|
const checksum = await hashFile(uri);
|
|
@@ -207,11 +269,12 @@ class SpyglassUriSupporter {
|
|
|
207
269
|
logger.error(`[SpyglassUriSupporter#create] Bad dependency “${uri}”`, e);
|
|
208
270
|
}
|
|
209
271
|
}
|
|
210
|
-
return new
|
|
272
|
+
return new ArchiveUriSupporter(entries);
|
|
211
273
|
}
|
|
212
274
|
}
|
|
213
|
-
exports.
|
|
214
|
-
|
|
275
|
+
exports.ArchiveUriSupporter = ArchiveUriSupporter;
|
|
276
|
+
ArchiveUriSupporter.Protocol = 'archive:';
|
|
277
|
+
ArchiveUriSupporter.SupportedArchiveExtnames = ['.tar', '.tar.bz2', '.tar.gz', '.zip'];
|
|
215
278
|
async function hashFile(uri) {
|
|
216
279
|
return new Promise((resolve, reject) => {
|
|
217
280
|
const hash = crypto_1.default.createHash(HashAlgorithm);
|
package/lib/service/Project.d.ts
CHANGED
|
@@ -131,6 +131,7 @@ export declare class Project extends EventEmitter {
|
|
|
131
131
|
close(): Promise<void>;
|
|
132
132
|
restart(): Promise<void>;
|
|
133
133
|
resetCache(): void;
|
|
134
|
+
normalizeUri(uri: string): string;
|
|
134
135
|
/**
|
|
135
136
|
* @returns The language ID of the file, or the file extension without the leading dot.
|
|
136
137
|
*/
|