@defold-typescript/tstl-plugin 0.28.3 → 0.30.0
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/dist/build-config.d.ts +1 -2
- package/dist/completion-harness.d.ts +38 -0
- package/dist/index.cjs +6 -0
- package/dist/index.js +32 -66
- package/dist/scene-index-cache.d.ts +1 -1
- package/package.json +8 -6
- package/src/build-config.ts +6 -2
- package/src/index.ts +6 -8
- package/src/require-entry.cjs +6 -0
- package/src/scene-index-cache.ts +2 -2
- package/src/scene-provenance.ts +5 -7
- package/dist/scene-documents.d.ts +0 -18
- package/src/scene-documents.ts +0 -126
package/dist/build-config.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { type BuildConfig } from "@defold-typescript/transpiler";
|
|
2
|
-
import type { SceneReadHost } from "./scene-documents";
|
|
1
|
+
import { type BuildConfig, type SceneReadHost } from "@defold-typescript/transpiler";
|
|
3
2
|
export declare function readBuildConfigFromHost(host: SceneReadHost, projectRoot: string): BuildConfig;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
export type PluginFactory = (modules: {
|
|
3
|
+
typescript: typeof import("typescript");
|
|
4
|
+
}) => {
|
|
5
|
+
create(info: ts.server.PluginCreateInfo): ts.LanguageService;
|
|
6
|
+
};
|
|
7
|
+
export declare const SCENE_DOCUMENTS: Record<string, string>;
|
|
8
|
+
export interface ProxyHost {
|
|
9
|
+
documents: Record<string, string>;
|
|
10
|
+
directoryReads: string[][];
|
|
11
|
+
openWatchers: number;
|
|
12
|
+
fireDirectory(hostPath: string): void;
|
|
13
|
+
}
|
|
14
|
+
export interface CompletionSetup {
|
|
15
|
+
service: ts.LanguageService;
|
|
16
|
+
host: ProxyHost;
|
|
17
|
+
baseDisposeCalls(): number;
|
|
18
|
+
detailsCalls(): unknown[][];
|
|
19
|
+
}
|
|
20
|
+
export declare function completionSetup(options: {
|
|
21
|
+
source: string;
|
|
22
|
+
base: ts.WithMetadata<ts.CompletionInfo> | undefined;
|
|
23
|
+
documents?: Record<string, string>;
|
|
24
|
+
serverHost?: boolean;
|
|
25
|
+
watch?: boolean;
|
|
26
|
+
baseDispose?: boolean;
|
|
27
|
+
baseDetails?: ts.CompletionEntryDetails;
|
|
28
|
+
fileName?: string;
|
|
29
|
+
init?: PluginFactory;
|
|
30
|
+
}): CompletionSetup;
|
|
31
|
+
export declare function completionProxy(options: {
|
|
32
|
+
source: string;
|
|
33
|
+
base: ts.WithMetadata<ts.CompletionInfo> | undefined;
|
|
34
|
+
documents?: Record<string, string>;
|
|
35
|
+
serverHost?: boolean;
|
|
36
|
+
fileName?: string;
|
|
37
|
+
init?: PluginFactory;
|
|
38
|
+
}): ts.LanguageService;
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// tsserver resolves a plugin with Node10 resolution — `exports` is not
|
|
2
|
+
// consulted — and then rejects the loaded value unless it is itself a function.
|
|
3
|
+
// `require()` of the ESM entry yields the namespace object instead, so this
|
|
4
|
+
// CommonJS shim is what `main` points at: it unwraps the factory, and the ESM
|
|
5
|
+
// bundle stays the single build of the plugin.
|
|
6
|
+
module.exports = require("./index.js").default;
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import {
|
|
5
|
+
ANIMATION_ASSET_EXTENSIONS as ANIMATION_ASSET_EXTENSIONS2,
|
|
5
6
|
buildConfigKeyIndex as buildConfigKeyIndex2,
|
|
6
7
|
buildGuiNodeIndex as buildGuiNodeIndex2,
|
|
7
8
|
buildInputActionIndex as buildInputActionIndex2,
|
|
@@ -10,14 +11,22 @@ import {
|
|
|
10
11
|
buildSpriteAnimationIndex as buildSpriteAnimationIndex2,
|
|
11
12
|
componentIdOfSameObjectAddress as componentIdOfSameObjectAddress2,
|
|
12
13
|
computeOutputRel as computeOutputRel2,
|
|
14
|
+
displayPathOf as displayPathOf3,
|
|
15
|
+
GAME_PROJECT_DOCUMENT as GAME_PROJECT_DOCUMENT2,
|
|
16
|
+
GUI_EXTENSIONS as GUI_EXTENSIONS2,
|
|
13
17
|
getProgramDiagnostics,
|
|
18
|
+
INPUT_BINDING_EXTENSIONS as INPUT_BINDING_EXTENSIONS2,
|
|
14
19
|
isAddressClass as isAddressClass2,
|
|
15
20
|
isFragmentCaret as isFragmentCaret2,
|
|
21
|
+
PROJECT_EXTENSIONS as PROJECT_EXTENSIONS2,
|
|
16
22
|
resolveClassifiedSlotAtPosition
|
|
17
23
|
} from "@defold-typescript/transpiler";
|
|
18
24
|
|
|
19
25
|
// src/build-config.ts
|
|
20
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
DEFAULT_INCLUDE,
|
|
28
|
+
parseBuildConfig
|
|
29
|
+
} from "@defold-typescript/transpiler";
|
|
21
30
|
var ALONGSIDE = { outDir: undefined, include: DEFAULT_INCLUDE };
|
|
22
31
|
function readBuildConfigFromHost(host, projectRoot) {
|
|
23
32
|
const root = projectRoot.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
@@ -78,63 +87,14 @@ function buildWholeLiteralCompletionEntries(input) {
|
|
|
78
87
|
});
|
|
79
88
|
}
|
|
80
89
|
|
|
81
|
-
// src/scene-documents.ts
|
|
82
|
-
import { isDefignoredPath } from "@defold-typescript/transpiler";
|
|
83
|
-
var SCENE_EXTENSIONS = [".go", ".collection"];
|
|
84
|
-
var GUI_EXTENSIONS = [".gui"];
|
|
85
|
-
var INPUT_BINDING_EXTENSIONS = [".input_binding"];
|
|
86
|
-
var ANIMATION_ASSET_EXTENSIONS = [".atlas", ".tilesource", ".sprite"];
|
|
87
|
-
var PROJECT_EXTENSIONS = [".project"];
|
|
88
|
-
var GAME_PROJECT_DOCUMENT = "game.project";
|
|
89
|
-
function displayPathOf(projectRoot, filePath) {
|
|
90
|
-
const path = filePath.replace(/\\/g, "/");
|
|
91
|
-
const root = projectRoot.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
92
|
-
return path.startsWith(`${root}/`) ? path.slice(root.length + 1) : path;
|
|
93
|
-
}
|
|
94
|
-
function isBuildOutput(displayPath) {
|
|
95
|
-
return displayPath.split("/").includes("build");
|
|
96
|
-
}
|
|
97
|
-
function isExcludedProjectPath(displayPath) {
|
|
98
|
-
return isBuildOutput(displayPath) || isDefignoredPath(displayPath);
|
|
99
|
-
}
|
|
100
|
-
function readSceneDocuments(host, projectRoot, extensions = SCENE_EXTENSIONS) {
|
|
101
|
-
const documents = new Map;
|
|
102
|
-
const unreadable = [];
|
|
103
|
-
const paths = [];
|
|
104
|
-
if (!host.readDirectory) {
|
|
105
|
-
unreadable.push("the editor host cannot enumerate project files, so no scene source was read");
|
|
106
|
-
return { documents, unreadable, paths };
|
|
107
|
-
}
|
|
108
|
-
for (const filePath of host.readDirectory(projectRoot, extensions)) {
|
|
109
|
-
const displayPath = displayPathOf(projectRoot, filePath);
|
|
110
|
-
if (isExcludedProjectPath(displayPath))
|
|
111
|
-
continue;
|
|
112
|
-
const text = host.readFile(filePath);
|
|
113
|
-
if (text === undefined) {
|
|
114
|
-
unreadable.push(`${displayPath}: could not be read`);
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
documents.set(displayPath, text);
|
|
118
|
-
paths.push(filePath);
|
|
119
|
-
}
|
|
120
|
-
return { documents, unreadable, paths };
|
|
121
|
-
}
|
|
122
|
-
function listProjectResourcePaths(host, projectRoot, extensions) {
|
|
123
|
-
if (!host.readDirectory)
|
|
124
|
-
return new Set;
|
|
125
|
-
const paths = [];
|
|
126
|
-
for (const filePath of host.readDirectory(projectRoot, extensions)) {
|
|
127
|
-
const displayPath = displayPathOf(projectRoot, filePath);
|
|
128
|
-
if (isExcludedProjectPath(displayPath))
|
|
129
|
-
continue;
|
|
130
|
-
if (!extensions.some((extension) => displayPath.endsWith(extension)))
|
|
131
|
-
continue;
|
|
132
|
-
paths.push(`/${displayPath}`);
|
|
133
|
-
}
|
|
134
|
-
return new Set(paths.sort());
|
|
135
|
-
}
|
|
136
|
-
|
|
137
90
|
// src/scene-index-cache.ts
|
|
91
|
+
import {
|
|
92
|
+
displayPathOf,
|
|
93
|
+
isExcludedProjectPath,
|
|
94
|
+
listProjectResourcePaths,
|
|
95
|
+
readSceneDocuments,
|
|
96
|
+
SCENE_EXTENSIONS
|
|
97
|
+
} from "@defold-typescript/transpiler";
|
|
138
98
|
function cacheKey(extensions) {
|
|
139
99
|
return [...extensions].sort().join("|");
|
|
140
100
|
}
|
|
@@ -250,6 +210,7 @@ function createSceneIndexCache(host, projectRoot) {
|
|
|
250
210
|
|
|
251
211
|
// src/scene-provenance.ts
|
|
252
212
|
import {
|
|
213
|
+
ANIMATION_ASSET_EXTENSIONS,
|
|
253
214
|
buildConfigKeyIndex,
|
|
254
215
|
buildGuiNodeIndex,
|
|
255
216
|
buildInputActionIndex,
|
|
@@ -258,8 +219,13 @@ import {
|
|
|
258
219
|
buildSpriteAnimationIndex,
|
|
259
220
|
componentIdOfSameObjectAddress,
|
|
260
221
|
computeOutputRel,
|
|
222
|
+
displayPathOf as displayPathOf2,
|
|
223
|
+
GAME_PROJECT_DOCUMENT,
|
|
224
|
+
GUI_EXTENSIONS,
|
|
225
|
+
INPUT_BINDING_EXTENSIONS,
|
|
261
226
|
isAddressClass,
|
|
262
|
-
isFragmentCaret
|
|
227
|
+
isFragmentCaret,
|
|
228
|
+
PROJECT_EXTENSIONS
|
|
263
229
|
} from "@defold-typescript/transpiler";
|
|
264
230
|
var COMPONENT_PROVENANCE = "provenance:component-ids";
|
|
265
231
|
var ACTION_PROVENANCE = "provenance:input-actions";
|
|
@@ -317,7 +283,7 @@ function actionProvenance(cache) {
|
|
|
317
283
|
function nodeProvenance(cache, fileName) {
|
|
318
284
|
const byResource = cache.derived(GUI_PROVENANCE, () => byClaimedScript(cache.documents(GUI_EXTENSIONS).documents));
|
|
319
285
|
const config = readBuildConfigFromHost(cache.host, cache.projectRoot);
|
|
320
|
-
const resource = computeOutputRel(
|
|
286
|
+
const resource = computeOutputRel(displayPathOf2(cache.projectRoot, fileName), config, "gui-script");
|
|
321
287
|
return byResource.get(resource) ?? new Map;
|
|
322
288
|
}
|
|
323
289
|
function pathProvenance(cache) {
|
|
@@ -333,7 +299,7 @@ function animationProvenance(input) {
|
|
|
333
299
|
assets: cache.documents(ANIMATION_ASSET_EXTENSIONS).documents
|
|
334
300
|
}));
|
|
335
301
|
const config = readBuildConfigFromHost(cache.host, cache.projectRoot);
|
|
336
|
-
const resource = computeOutputRel(
|
|
302
|
+
const resource = computeOutputRel(displayPathOf2(cache.projectRoot, fileName), config, "script");
|
|
337
303
|
const tileSet = index.tileSetByScriptResource.get(resource)?.get(component);
|
|
338
304
|
if (tileSet === undefined)
|
|
339
305
|
return [];
|
|
@@ -411,9 +377,9 @@ function objectPathEntries(slot, position, cache, baseEntries) {
|
|
|
411
377
|
}
|
|
412
378
|
function nodeEntries(slot, cache, fileName, baseEntries) {
|
|
413
379
|
const { projectRoot } = cache;
|
|
414
|
-
const index = cache.derived("gui-nodes", () => buildGuiNodeIndex2(cache.documents(
|
|
380
|
+
const index = cache.derived("gui-nodes", () => buildGuiNodeIndex2(cache.documents(GUI_EXTENSIONS2).documents));
|
|
415
381
|
const config = readBuildConfigFromHost(cache.host, projectRoot);
|
|
416
|
-
const resource = computeOutputRel2(
|
|
382
|
+
const resource = computeOutputRel2(displayPathOf3(projectRoot, fileName), config, "gui-script");
|
|
417
383
|
const ids = index.byScriptResource.get(resource);
|
|
418
384
|
return ids === undefined ? [] : buildWholeLiteralCompletionEntries({ slot, ids, baseEntries });
|
|
419
385
|
}
|
|
@@ -425,10 +391,10 @@ function animationEntries(slot, cache, fileName, baseEntries) {
|
|
|
425
391
|
const { projectRoot } = cache;
|
|
426
392
|
const index = cache.derived("sprite-animations", () => buildSpriteAnimationIndex2({
|
|
427
393
|
scenes: cache.documents().documents,
|
|
428
|
-
assets: cache.documents(
|
|
394
|
+
assets: cache.documents(ANIMATION_ASSET_EXTENSIONS2).documents
|
|
429
395
|
}));
|
|
430
396
|
const config = readBuildConfigFromHost(cache.host, projectRoot);
|
|
431
|
-
const resource = computeOutputRel2(
|
|
397
|
+
const resource = computeOutputRel2(displayPathOf3(projectRoot, fileName), config, "script");
|
|
432
398
|
const ids = index.byScriptResource.get(resource)?.get(component);
|
|
433
399
|
return ids === undefined ? [] : buildWholeLiteralCompletionEntries({ slot, ids, baseEntries });
|
|
434
400
|
}
|
|
@@ -441,7 +407,7 @@ function resourceEntries(slot, cache, baseEntries) {
|
|
|
441
407
|
return buildWholeLiteralCompletionEntries({ slot, ids, baseEntries });
|
|
442
408
|
}
|
|
443
409
|
function configKeyEntries(slot, cache, baseEntries) {
|
|
444
|
-
const text = cache.documents(
|
|
410
|
+
const text = cache.documents(PROJECT_EXTENSIONS2).documents.get(GAME_PROJECT_DOCUMENT2);
|
|
445
411
|
if (text === undefined) {
|
|
446
412
|
return [];
|
|
447
413
|
}
|
|
@@ -449,7 +415,7 @@ function configKeyEntries(slot, cache, baseEntries) {
|
|
|
449
415
|
return buildWholeLiteralCompletionEntries({ slot, ids, baseEntries });
|
|
450
416
|
}
|
|
451
417
|
function actionIdEntries(slot, cache, baseEntries) {
|
|
452
|
-
const ids = cache.derived("input-actions", () => buildInputActionIndex2(cache.documents(
|
|
418
|
+
const ids = cache.derived("input-actions", () => buildInputActionIndex2(cache.documents(INPUT_BINDING_EXTENSIONS2).documents));
|
|
453
419
|
return buildWholeLiteralCompletionEntries({ slot, ids, baseEntries });
|
|
454
420
|
}
|
|
455
421
|
function provenancePanel(entryName, declaredIn) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { readSceneDocuments, type SceneReadHost } from "@defold-typescript/transpiler";
|
|
1
2
|
import type * as ts from "typescript";
|
|
2
|
-
import { readSceneDocuments, type SceneReadHost } from "./scene-documents";
|
|
3
3
|
export interface SceneWatchHost extends SceneReadHost {
|
|
4
4
|
watchFile?(path: string, callback: ts.FileWatcherCallback, pollingInterval?: number): ts.FileWatcher;
|
|
5
5
|
watchDirectory?(path: string, callback: ts.DirectoryWatcherCallback, recursive?: boolean): ts.FileWatcher;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defold-typescript/tstl-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"description": "TypeScript language-service plugin surfacing Defold transpiler diagnostics live in the editor.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -11,32 +11,34 @@
|
|
|
11
11
|
"homepage": "https://github.com/defold-typescript/toolchain#readme",
|
|
12
12
|
"bugs": "https://github.com/defold-typescript/toolchain/issues",
|
|
13
13
|
"type": "module",
|
|
14
|
-
"main": "./dist/index.
|
|
14
|
+
"main": "./dist/index.cjs",
|
|
15
15
|
"types": "./dist/index.d.ts",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
18
18
|
"types": "./dist/index.d.ts",
|
|
19
19
|
"bun": "./src/index.ts",
|
|
20
|
-
"import": "./dist/index.js"
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"require": "./dist/index.cjs"
|
|
21
22
|
}
|
|
22
23
|
},
|
|
23
24
|
"files": [
|
|
24
25
|
"dist",
|
|
25
26
|
"src",
|
|
26
27
|
"!src/**/*.test.ts",
|
|
28
|
+
"!src/**/completion-harness.ts",
|
|
27
29
|
"!src/**/__snapshots__"
|
|
28
30
|
],
|
|
29
31
|
"publishConfig": {
|
|
30
32
|
"access": "public"
|
|
31
33
|
},
|
|
32
34
|
"scripts": {
|
|
33
|
-
"build": "rm -rf dist && bun build src/index.ts --target=node --format=esm --packages=external --outdir=dist && tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
35
|
+
"build": "rm -rf dist && bun build src/index.ts --target=node --format=esm --packages=external --outdir=dist && cp src/require-entry.cjs dist/index.cjs && tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
34
36
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
35
37
|
"test": "bun test"
|
|
36
38
|
},
|
|
37
39
|
"dependencies": {
|
|
38
|
-
"@defold-typescript/transpiler": "0.
|
|
39
|
-
"@defold-typescript/types": "0.
|
|
40
|
+
"@defold-typescript/transpiler": "0.30.0",
|
|
41
|
+
"@defold-typescript/types": "0.30.0"
|
|
40
42
|
},
|
|
41
43
|
"peerDependencies": {
|
|
42
44
|
"typescript": ">=5.0.0 <7"
|
package/src/build-config.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
type BuildConfig,
|
|
3
|
+
DEFAULT_INCLUDE,
|
|
4
|
+
parseBuildConfig,
|
|
5
|
+
type SceneReadHost,
|
|
6
|
+
} from "@defold-typescript/transpiler";
|
|
3
7
|
|
|
4
8
|
// Alongside output is what the build itself does with no `outDir`, so it is also
|
|
5
9
|
// the honest answer when the config cannot be read: a wrong guess would offer
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import {
|
|
4
|
+
ANIMATION_ASSET_EXTENSIONS,
|
|
4
5
|
buildConfigKeyIndex,
|
|
5
6
|
buildGuiNodeIndex,
|
|
6
7
|
buildInputActionIndex,
|
|
@@ -10,9 +11,14 @@ import {
|
|
|
10
11
|
type ClassifiedSlot,
|
|
11
12
|
componentIdOfSameObjectAddress,
|
|
12
13
|
computeOutputRel,
|
|
14
|
+
displayPathOf,
|
|
15
|
+
GAME_PROJECT_DOCUMENT,
|
|
16
|
+
GUI_EXTENSIONS,
|
|
13
17
|
getProgramDiagnostics,
|
|
18
|
+
INPUT_BINDING_EXTENSIONS,
|
|
14
19
|
isAddressClass,
|
|
15
20
|
isFragmentCaret,
|
|
21
|
+
PROJECT_EXTENSIONS,
|
|
16
22
|
resolveClassifiedSlotAtPosition,
|
|
17
23
|
} from "@defold-typescript/transpiler";
|
|
18
24
|
import type { UrlParameterTable } from "@defold-typescript/types";
|
|
@@ -25,14 +31,6 @@ import {
|
|
|
25
31
|
CONTRIBUTED_ENTRY_KIND,
|
|
26
32
|
DEFOLD_COMPLETION_SOURCE,
|
|
27
33
|
} from "./scene-completions";
|
|
28
|
-
import {
|
|
29
|
-
ANIMATION_ASSET_EXTENSIONS,
|
|
30
|
-
displayPathOf,
|
|
31
|
-
GAME_PROJECT_DOCUMENT,
|
|
32
|
-
GUI_EXTENSIONS,
|
|
33
|
-
INPUT_BINDING_EXTENSIONS,
|
|
34
|
-
PROJECT_EXTENSIONS,
|
|
35
|
-
} from "./scene-documents";
|
|
36
34
|
import {
|
|
37
35
|
createSceneIndexCache,
|
|
38
36
|
type SceneIndexCache,
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// tsserver resolves a plugin with Node10 resolution — `exports` is not
|
|
2
|
+
// consulted — and then rejects the loaded value unless it is itself a function.
|
|
3
|
+
// `require()` of the ESM entry yields the namespace object instead, so this
|
|
4
|
+
// CommonJS shim is what `main` points at: it unwraps the factory, and the ESM
|
|
5
|
+
// bundle stays the single build of the plugin.
|
|
6
|
+
module.exports = require("./index.js").default;
|
package/src/scene-index-cache.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type * as ts from "typescript";
|
|
2
1
|
import {
|
|
3
2
|
displayPathOf,
|
|
4
3
|
isExcludedProjectPath,
|
|
@@ -6,7 +5,8 @@ import {
|
|
|
6
5
|
readSceneDocuments,
|
|
7
6
|
SCENE_EXTENSIONS,
|
|
8
7
|
type SceneReadHost,
|
|
9
|
-
} from "
|
|
8
|
+
} from "@defold-typescript/transpiler";
|
|
9
|
+
import type * as ts from "typescript";
|
|
10
10
|
|
|
11
11
|
// `SceneReadHost` plus the two watch facilities `ts.System` declares as
|
|
12
12
|
// optional, typed off the editor's own callback types so the real
|
package/src/scene-provenance.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ANIMATION_ASSET_EXTENSIONS,
|
|
2
3
|
buildConfigKeyIndex,
|
|
3
4
|
buildGuiNodeIndex,
|
|
4
5
|
buildInputActionIndex,
|
|
@@ -8,18 +9,15 @@ import {
|
|
|
8
9
|
type ClassifiedSlot,
|
|
9
10
|
componentIdOfSameObjectAddress,
|
|
10
11
|
computeOutputRel,
|
|
11
|
-
isAddressClass,
|
|
12
|
-
isFragmentCaret,
|
|
13
|
-
} from "@defold-typescript/transpiler";
|
|
14
|
-
import { readBuildConfigFromHost } from "./build-config";
|
|
15
|
-
import {
|
|
16
|
-
ANIMATION_ASSET_EXTENSIONS,
|
|
17
12
|
displayPathOf,
|
|
18
13
|
GAME_PROJECT_DOCUMENT,
|
|
19
14
|
GUI_EXTENSIONS,
|
|
20
15
|
INPUT_BINDING_EXTENSIONS,
|
|
16
|
+
isAddressClass,
|
|
17
|
+
isFragmentCaret,
|
|
21
18
|
PROJECT_EXTENSIONS,
|
|
22
|
-
} from "
|
|
19
|
+
} from "@defold-typescript/transpiler";
|
|
20
|
+
import { readBuildConfigFromHost } from "./build-config";
|
|
23
21
|
import type { SceneIndexCache } from "./scene-index-cache";
|
|
24
22
|
|
|
25
23
|
// Keys of their own under the same cache the completion indexes use, so a
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export interface SceneReadHost {
|
|
2
|
-
readDirectory?(path: string, extensions?: readonly string[]): string[];
|
|
3
|
-
readFile(path: string): string | undefined;
|
|
4
|
-
}
|
|
5
|
-
export declare const SCENE_EXTENSIONS: string[];
|
|
6
|
-
export declare const GUI_EXTENSIONS: string[];
|
|
7
|
-
export declare const INPUT_BINDING_EXTENSIONS: string[];
|
|
8
|
-
export declare const ANIMATION_ASSET_EXTENSIONS: string[];
|
|
9
|
-
export declare const PROJECT_EXTENSIONS: string[];
|
|
10
|
-
export declare const GAME_PROJECT_DOCUMENT = "game.project";
|
|
11
|
-
export declare function displayPathOf(projectRoot: string, filePath: string): string;
|
|
12
|
-
export declare function isExcludedProjectPath(displayPath: string): boolean;
|
|
13
|
-
export declare function readSceneDocuments(host: SceneReadHost, projectRoot: string, extensions?: readonly string[]): {
|
|
14
|
-
documents: Map<string, string>;
|
|
15
|
-
unreadable: string[];
|
|
16
|
-
paths: string[];
|
|
17
|
-
};
|
|
18
|
-
export declare function listProjectResourcePaths(host: SceneReadHost, projectRoot: string, extensions: readonly string[]): Set<string>;
|
package/src/scene-documents.ts
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { isDefignoredPath } from "@defold-typescript/transpiler";
|
|
2
|
-
|
|
3
|
-
// The narrow slice of `ts.server.ServerHost` this needs: the real host
|
|
4
|
-
// satisfies it structurally, and a test fake is two methods rather than a whole
|
|
5
|
-
// server. `readDirectory` is optional because a host may not provide it, and a
|
|
6
|
-
// plugin that throws takes the editor's completions down with it.
|
|
7
|
-
export interface SceneReadHost {
|
|
8
|
-
readDirectory?(path: string, extensions?: readonly string[]): string[];
|
|
9
|
-
readFile(path: string): string | undefined;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const SCENE_EXTENSIONS = [".go", ".collection"];
|
|
13
|
-
|
|
14
|
-
// The extension sets more than one reader asks the host for. They live here
|
|
15
|
-
// rather than beside either caller because the index cache serves exactly the
|
|
16
|
-
// sets it is handed: a second definition that drifted would walk — and watch —
|
|
17
|
-
// a universe the other reader never invalidates.
|
|
18
|
-
export const GUI_EXTENSIONS = [".gui"];
|
|
19
|
-
export const INPUT_BINDING_EXTENSIONS = [".input_binding"];
|
|
20
|
-
|
|
21
|
-
// The documents an animation id is declared by: an atlas or tile source names
|
|
22
|
-
// the ids, and a `.sprite` is the hop a referenced component takes to reach one.
|
|
23
|
-
export const ANIMATION_ASSET_EXTENSIONS = [".atlas", ".tilesource", ".sprite"];
|
|
24
|
-
|
|
25
|
-
// The walk returns every `.project` the project holds, so the lookup is by
|
|
26
|
-
// display path — a vendored `*.project` declares keys this project's readers
|
|
27
|
-
// cannot resolve.
|
|
28
|
-
export const PROJECT_EXTENSIONS = [".project"];
|
|
29
|
-
export const GAME_PROJECT_DOCUMENT = "game.project";
|
|
30
|
-
|
|
31
|
-
// The project-relative name a file is keyed by — the same name the editor
|
|
32
|
-
// reports for a program file, so a scene's claim on a script can be looked up
|
|
33
|
-
// against the file being edited.
|
|
34
|
-
export function displayPathOf(projectRoot: string, filePath: string): string {
|
|
35
|
-
const path = filePath.replace(/\\/g, "/");
|
|
36
|
-
const root = projectRoot.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
37
|
-
return path.startsWith(`${root}/`) ? path.slice(root.length + 1) : path;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// What both walks exclude is what Defold does not load as a project resource:
|
|
41
|
-
// `build/` output, plus the directories the scaffolded `.defignore` names
|
|
42
|
-
// (`isDefignoredPath`, root-anchored because a `.defignore` line is a
|
|
43
|
-
// root-relative path).
|
|
44
|
-
//
|
|
45
|
-
// Bob writes `_generated_*.go` copies of the project's scenes under `build/`;
|
|
46
|
-
// reading them would report every id twice, against files no author edits. The
|
|
47
|
-
// segment test runs on the project-relative path, so a project that itself
|
|
48
|
-
// lives under a directory named `build` is not excluded wholesale — a different
|
|
49
|
-
// rule from `.defignore`'s, because bob writes those copies below whatever
|
|
50
|
-
// depth it is pointed at.
|
|
51
|
-
function isBuildOutput(displayPath: string): boolean {
|
|
52
|
-
return displayPath.split("/").includes("build");
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// The single rule, exported because the index cache filters watch events with
|
|
56
|
-
// it: a copy in the watcher could drift from what the walks exclude, and an
|
|
57
|
-
// event the walk would have ignored is exactly the event that must not throw the
|
|
58
|
-
// cache away — bob writes `_generated_*.go` throughout a build.
|
|
59
|
-
export function isExcludedProjectPath(displayPath: string): boolean {
|
|
60
|
-
return isBuildOutput(displayPath) || isDefignoredPath(displayPath);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Read the project's own scene sources through the editor host — by default the
|
|
64
|
-
// `.go`/`.collection` set the component-id universe is built from, or whatever
|
|
65
|
-
// `extensions` names instead. The two universes stay disjoint: a `.gui` declares
|
|
66
|
-
// node ids, not component ids, so folding it into the default would feed gui
|
|
67
|
-
// text to `buildSceneComponentIndex`. Keys are project-relative display paths,
|
|
68
|
-
// matching what `buildSceneComponentIndex` reports in `incomplete`, and every
|
|
69
|
-
// file that could not be read is named in `unreadable` — a universe with a
|
|
70
|
-
// silent hole cannot be reasoned about. `paths` names the host paths actually
|
|
71
|
-
// read — what a watcher must be registered on, which cannot be reconstructed
|
|
72
|
-
// from a display path for a file outside the project root.
|
|
73
|
-
export function readSceneDocuments(
|
|
74
|
-
host: SceneReadHost,
|
|
75
|
-
projectRoot: string,
|
|
76
|
-
extensions: readonly string[] = SCENE_EXTENSIONS,
|
|
77
|
-
): { documents: Map<string, string>; unreadable: string[]; paths: string[] } {
|
|
78
|
-
const documents = new Map<string, string>();
|
|
79
|
-
const unreadable: string[] = [];
|
|
80
|
-
const paths: string[] = [];
|
|
81
|
-
|
|
82
|
-
if (!host.readDirectory) {
|
|
83
|
-
unreadable.push("the editor host cannot enumerate project files, so no scene source was read");
|
|
84
|
-
return { documents, unreadable, paths };
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
for (const filePath of host.readDirectory(projectRoot, extensions)) {
|
|
88
|
-
const displayPath = displayPathOf(projectRoot, filePath);
|
|
89
|
-
if (isExcludedProjectPath(displayPath)) continue;
|
|
90
|
-
const text = host.readFile(filePath);
|
|
91
|
-
if (text === undefined) {
|
|
92
|
-
unreadable.push(`${displayPath}: could not be read`);
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
documents.set(displayPath, text);
|
|
96
|
-
paths.push(filePath);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return { documents, unreadable, paths };
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// The project's own files of the given kinds, as the `/`-prefixed
|
|
103
|
-
// project-relative paths a Defold resource property names. Nothing is read: a
|
|
104
|
-
// resource path is the whole suggestion, so the walk is the entire universe.
|
|
105
|
-
//
|
|
106
|
-
// The extension filter is re-applied rather than trusted. `readSceneDocuments`
|
|
107
|
-
// can take the host at its word because a wrong document merely contributes no
|
|
108
|
-
// ids, but here a wrong file *is* the suggestion — a host that ignored its
|
|
109
|
-
// `extensions` argument would turn a `.font` slot into a project-wide file dump.
|
|
110
|
-
export function listProjectResourcePaths(
|
|
111
|
-
host: SceneReadHost,
|
|
112
|
-
projectRoot: string,
|
|
113
|
-
extensions: readonly string[],
|
|
114
|
-
): Set<string> {
|
|
115
|
-
if (!host.readDirectory) return new Set();
|
|
116
|
-
|
|
117
|
-
const paths: string[] = [];
|
|
118
|
-
for (const filePath of host.readDirectory(projectRoot, extensions)) {
|
|
119
|
-
const displayPath = displayPathOf(projectRoot, filePath);
|
|
120
|
-
if (isExcludedProjectPath(displayPath)) continue;
|
|
121
|
-
if (!extensions.some((extension) => displayPath.endsWith(extension))) continue;
|
|
122
|
-
paths.push(`/${displayPath}`);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return new Set(paths.sort());
|
|
126
|
-
}
|