🚧 Move some code to CacheWorker
This commit is contained in:
parent
4d1ea863df
commit
3fa4e39342
2 changed files with 426 additions and 235 deletions
102
src/layers.ts
102
src/layers.ts
|
@ -205,105 +205,27 @@ export const tagRenderingImplementationProvider =
|
|||
if (references.length === 0) {
|
||||
return null;
|
||||
} else {
|
||||
// TODO: This is way too much to be executing at this time, most of this should be cached
|
||||
// TODO: Also, this seems to fail for the first time, but work for every subsequent time
|
||||
console.log(`Found ${references.length} references to ${to}`);
|
||||
|
||||
const links: vscode.DefinitionLink[] = [];
|
||||
for (const reference of references) {
|
||||
const originType = reference.reference?.from.split(".")[0];
|
||||
const originName = reference.reference?.from.split(".")[1];
|
||||
|
||||
// We need to open the file where the reference is located
|
||||
const originFile = await vscode.workspace.findFiles(
|
||||
`assets/${originType}/${originName}/${originName}.json`
|
||||
);
|
||||
if (originFile.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const originText = await vscode.workspace.fs.readFile(
|
||||
originFile[0]
|
||||
);
|
||||
const originTextString = new TextDecoder().decode(originText);
|
||||
const origin = JSON.parse(originTextString);
|
||||
|
||||
let tagRenderings: unknown[] = [];
|
||||
let tagRenderingsPath: JSONPath = [];
|
||||
|
||||
// Now we'll need to find the tagRenderings object, and its path
|
||||
if (originType === "themes") {
|
||||
const parts = reference.reference?.from.split(".");
|
||||
if (!parts) {
|
||||
continue;
|
||||
} else {
|
||||
console.log("Parts", parts);
|
||||
// Now we need to find the correct inline layer
|
||||
const layerIndex = origin.layers.findIndex(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(layer: any) => layer.id === parts[3]
|
||||
);
|
||||
|
||||
const path: JSONPath = [
|
||||
parts[2],
|
||||
layerIndex,
|
||||
...reference.jsonPath,
|
||||
];
|
||||
|
||||
console.log("Trying to get tagRenderings from theme", path);
|
||||
|
||||
const tagRenderingsFromOrigin = getValueFromPath(
|
||||
originTextString,
|
||||
path
|
||||
);
|
||||
if (!tagRenderingsFromOrigin) {
|
||||
console.error(
|
||||
"Could not find tagRenderings in theme",
|
||||
originName
|
||||
);
|
||||
continue;
|
||||
} else {
|
||||
// Yaay, we found the tagRenderings
|
||||
console.log("Found tagRenderings in theme", originName);
|
||||
tagRenderings = tagRenderingsFromOrigin as unknown[];
|
||||
tagRenderingsPath = path;
|
||||
}
|
||||
}
|
||||
} else if (originType === "layers") {
|
||||
tagRenderings = origin.tagRenderings;
|
||||
tagRenderingsPath = ["tagRenderings"];
|
||||
}
|
||||
|
||||
// The index is actually a really complicated, because a reference could be a string or an object with a builtin property, which can be a string or a list of strings
|
||||
// Also if the reference is from an inline layer
|
||||
const tagRenderingIndex = tagRenderings.findIndex(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(tr: any) => {
|
||||
if (typeof tr === "string") {
|
||||
return tr === reference.id;
|
||||
} else if (typeof tr.builtin === "string") {
|
||||
return tr.builtin === reference.id;
|
||||
}
|
||||
// } else if (tr.builtin) {
|
||||
// return tr.builtin.includes(reference.id);
|
||||
// }
|
||||
}
|
||||
);
|
||||
const path: JSONPath = [
|
||||
...tagRenderingsPath,
|
||||
tagRenderingIndex,
|
||||
];
|
||||
const startEnd = getStartEnd(originTextString, path);
|
||||
|
||||
console.log(
|
||||
`Pushing link from ${document.fileName} to ${originFile[0].path} at ${startEnd.start.line}.${startEnd.start.character} to ${startEnd.end.line}.${startEnd.end.character}`
|
||||
`Pushing link from ${document.fileName} to ${reference.reference?.to.uri?.fsPath} at ${reference.reference?.to.range?.start.line}.${reference.reference?.to.range?.start.character} to ${reference.reference?.to.range?.end.line}.${reference.reference?.to.range?.end.character}`
|
||||
);
|
||||
|
||||
// Check if we have a targetRange and targetUri
|
||||
if (
|
||||
reference.reference?.to.range &&
|
||||
reference.reference?.to.uri
|
||||
) {
|
||||
links.push({
|
||||
originSelectionRange: getStartEnd(text, rawJsonPath),
|
||||
targetRange: startEnd,
|
||||
targetUri: originFile[0],
|
||||
originSelectionRange: reference.reference?.from.range,
|
||||
targetRange: reference.reference?.to.range,
|
||||
targetUri: reference.reference?.to.uri,
|
||||
});
|
||||
} else {
|
||||
console.error("Incomplete reference", reference);
|
||||
}
|
||||
}
|
||||
console.log(`Found ${links.length} implementations`);
|
||||
return links;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import * as vscode from "vscode";
|
||||
import { JSONPath } from "jsonc-parser";
|
||||
import { getStartEnd } from "./cursor";
|
||||
|
||||
/**
|
||||
* Worker class to handle the cache creation and updates
|
||||
|
@ -164,15 +165,24 @@ export class CacheWorker {
|
|||
const text = new TextDecoder().decode(await content);
|
||||
const json = JSON.parse(text);
|
||||
|
||||
// Determine some locations
|
||||
const from = `themes.${json.id}`;
|
||||
const fromFile = uri;
|
||||
|
||||
// Look through the layers
|
||||
for (const layer of json.layers) {
|
||||
const layerIndex = json.layers.indexOf(layer);
|
||||
|
||||
// Reference if it's a string
|
||||
if (typeof layer === "string") {
|
||||
// It is a reference
|
||||
console.log(`Reference found to ${layer} in ${filePath}`);
|
||||
|
||||
const from = `themes.${json.id}`;
|
||||
const fromStartEnd = getStartEnd(text, ["layers", layerIndex]);
|
||||
const to = `layers.${layer}`;
|
||||
const toFile = await vscode.workspace.findFiles(
|
||||
`**/assets/layers/${layer}/${layer}.json`
|
||||
);
|
||||
|
||||
this.cache.push({
|
||||
id: layer,
|
||||
|
@ -180,8 +190,15 @@ export class CacheWorker {
|
|||
jsonPath: ["layers"],
|
||||
type: "reference",
|
||||
reference: {
|
||||
from,
|
||||
to,
|
||||
from: {
|
||||
id: from,
|
||||
uri: fromFile,
|
||||
range: fromStartEnd,
|
||||
},
|
||||
to: {
|
||||
id: to,
|
||||
uri: toFile[0],
|
||||
},
|
||||
type: "layer",
|
||||
},
|
||||
});
|
||||
|
@ -192,8 +209,15 @@ export class CacheWorker {
|
|||
// Single layer
|
||||
console.log(`Reference found to ${layer.builtin} in ${filePath}`);
|
||||
|
||||
const from = `themes.${json.id}`;
|
||||
const fromStartEnd = getStartEnd(text, [
|
||||
"layers",
|
||||
layerIndex,
|
||||
"builtin",
|
||||
]);
|
||||
const to = `layers.${layer.builtin}`;
|
||||
const toFile = await vscode.workspace.findFiles(
|
||||
`**/assets/layers/${layer.builtin}/${layer.builtin}.json`
|
||||
);
|
||||
|
||||
this.cache.push({
|
||||
id: layer.builtin,
|
||||
|
@ -201,8 +225,15 @@ export class CacheWorker {
|
|||
jsonPath: ["layers"],
|
||||
type: "reference",
|
||||
reference: {
|
||||
from,
|
||||
to,
|
||||
from: {
|
||||
id: from,
|
||||
uri: fromFile,
|
||||
range: fromStartEnd,
|
||||
},
|
||||
to: {
|
||||
id: to,
|
||||
uri: toFile[0],
|
||||
},
|
||||
type: "layer",
|
||||
},
|
||||
});
|
||||
|
@ -211,8 +242,17 @@ export class CacheWorker {
|
|||
for (const builtinLayer of layer.builtin) {
|
||||
console.log(`Reference found to ${builtinLayer} in ${filePath}`);
|
||||
|
||||
const from = `themes.${json.id}`;
|
||||
const builtinLayerIndex = layer.builtin.indexOf(builtinLayer);
|
||||
const fromStartEnd = getStartEnd(text, [
|
||||
"layers",
|
||||
layerIndex,
|
||||
"builtin",
|
||||
builtinLayerIndex,
|
||||
]);
|
||||
const to = `layers.${builtinLayer}`;
|
||||
const toFile = await vscode.workspace.findFiles(
|
||||
`**/assets/layers/${builtinLayer}/${builtinLayer}.json`
|
||||
);
|
||||
|
||||
this.cache.push({
|
||||
id: builtinLayer,
|
||||
|
@ -220,8 +260,15 @@ export class CacheWorker {
|
|||
jsonPath: ["layers"],
|
||||
type: "reference",
|
||||
reference: {
|
||||
from,
|
||||
to,
|
||||
from: {
|
||||
id: from,
|
||||
uri: fromFile,
|
||||
range: fromStartEnd,
|
||||
},
|
||||
to: {
|
||||
id: to,
|
||||
uri: toFile[0],
|
||||
},
|
||||
type: "layer",
|
||||
},
|
||||
});
|
||||
|
@ -231,9 +278,9 @@ export class CacheWorker {
|
|||
// Inline layer else
|
||||
else {
|
||||
console.log(`Found inline layer ${layer.id} in ${filePath}`);
|
||||
const text = JSON.stringify(layer);
|
||||
const layerText = JSON.stringify(layer);
|
||||
const from = `themes.${json.id}.layers.${layer.id}`;
|
||||
this.saveLayerTextToCache(text, uri, from, true);
|
||||
await this.saveLayerTextToCache(layerText, uri, from, true, text);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,22 +302,24 @@ export class CacheWorker {
|
|||
const uriFileName = uriPathSplit[uriPathSplit.length - 1];
|
||||
const from = `layers.${uriFileName.split(".")[0]}`;
|
||||
|
||||
this.saveLayerTextToCache(text, uri, from);
|
||||
await this.saveLayerTextToCache(text, uri, from);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a layer to the cache, given the text of the layer
|
||||
*
|
||||
* @param text The text of the layer
|
||||
* @param text Text representation of layer
|
||||
* @param uri The URI of the layer file
|
||||
* @param from The theme or layer where the layer is from, e.g. layers.bicycle_rental or themes.cyclofix.layers.0
|
||||
* @param referencesOnly Whether to only save references, or also the tagRenderings and filters. This is useful for inline layers, because their filters and tagRenderings can't be reused
|
||||
* @param fullFileText The full text of the original theme file, used for calculating position
|
||||
*/
|
||||
private saveLayerTextToCache(
|
||||
private async saveLayerTextToCache(
|
||||
text: string,
|
||||
uri: vscode.Uri,
|
||||
from: string,
|
||||
referencesOnly = false
|
||||
referencesOnly = false,
|
||||
fullFileText?: string
|
||||
) {
|
||||
const filePath = uri.fsPath;
|
||||
console.log("Saving layer to cache", filePath);
|
||||
|
@ -287,93 +336,16 @@ export class CacheWorker {
|
|||
|
||||
// Look through the tagRenderings, if the layer has any
|
||||
if (json.tagRenderings) {
|
||||
for (const tagRendering of json.tagRenderings) {
|
||||
// Check if it is a string and not an object
|
||||
if (typeof tagRendering === "string") {
|
||||
// It is a reference
|
||||
console.log(`Reference found to ${tagRendering} in ${filePath}`);
|
||||
|
||||
const to = tagRendering.includes(".")
|
||||
? `layers.${tagRendering.split(".")[0]}.tagRenderings.${
|
||||
tagRendering.split(".")[1]
|
||||
}`
|
||||
: `layers.questions.tagRenderings.${tagRendering}`;
|
||||
|
||||
this.cache.push({
|
||||
id: tagRendering,
|
||||
filePath: uri,
|
||||
jsonPath: ["tagRenderings"],
|
||||
type: "reference",
|
||||
reference: {
|
||||
try {
|
||||
await this.saveTagRenderingsToCache(
|
||||
text,
|
||||
from,
|
||||
to,
|
||||
type: "tagRendering",
|
||||
},
|
||||
});
|
||||
} else if (typeof tagRendering === "object") {
|
||||
// This is a tagRendering, or a reference to one
|
||||
if (tagRendering.builtin) {
|
||||
// This is a reference to a built-in tagRendering (or multiple ones)
|
||||
if (typeof tagRendering.builtin === "string") {
|
||||
// Single tagRendering
|
||||
console.log(
|
||||
`Reference found to ${tagRendering.builtin} in ${filePath}`
|
||||
uri,
|
||||
referencesOnly,
|
||||
fullFileText
|
||||
);
|
||||
|
||||
const to = tagRendering.builtin.includes(".")
|
||||
? `layers.${tagRendering.builtin.split(".")[0]}.tagRenderings.${
|
||||
tagRendering.builtin.split(".")[1]
|
||||
}`
|
||||
: `layers.questions.tagRenderings.${tagRendering.builtin}`;
|
||||
|
||||
this.cache.push({
|
||||
id: tagRendering.builtin,
|
||||
filePath: uri,
|
||||
jsonPath: ["tagRenderings"],
|
||||
type: "reference",
|
||||
reference: {
|
||||
from,
|
||||
to,
|
||||
type: "tagRendering",
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// Multiple tagRenderings
|
||||
for (const builtinTagRendering of tagRendering.builtin) {
|
||||
console.log(
|
||||
`Reference found to ${builtinTagRendering} in ${filePath}`
|
||||
);
|
||||
|
||||
const to = builtinTagRendering.includes(".")
|
||||
? `layers.${
|
||||
builtinTagRendering.split(".")[0]
|
||||
}.tagRenderings.${builtinTagRendering.split(".")[1]}`
|
||||
: `layers.questions.tagRenderings.${builtinTagRendering}`;
|
||||
|
||||
this.cache.push({
|
||||
id: builtinTagRendering,
|
||||
filePath: uri,
|
||||
jsonPath: ["tagRenderings"],
|
||||
type: "reference",
|
||||
reference: {
|
||||
from,
|
||||
to,
|
||||
type: "tagRendering",
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (!referencesOnly) {
|
||||
// This is a tagRendering, which can be reused
|
||||
console.log(`TagRendering found in ${filePath}`);
|
||||
this.cache.push({
|
||||
id: `${json.id}.${tagRendering.id}`,
|
||||
filePath: uri,
|
||||
jsonPath: ["tagRenderings"],
|
||||
type: "tagRendering",
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error saving tagRenderings for ${from}`, error);
|
||||
}
|
||||
} else {
|
||||
console.log("No tagRenderings found in", filePath);
|
||||
|
@ -381,36 +353,16 @@ export class CacheWorker {
|
|||
|
||||
if (json.filter) {
|
||||
// Look through the filters
|
||||
for (const filter of json.filter) {
|
||||
// Check if it is a string and not an object
|
||||
if (typeof filter === "string") {
|
||||
// It is a reference
|
||||
console.log(`Reference found to ${filter} in ${filePath}`);
|
||||
|
||||
const from = `layers.${json.id}`;
|
||||
const to = `layers.${filter}`;
|
||||
|
||||
this.cache.push({
|
||||
id: filter,
|
||||
filePath: uri,
|
||||
jsonPath: ["filters"],
|
||||
type: "reference",
|
||||
reference: {
|
||||
try {
|
||||
await this.saveFiltersToCache(
|
||||
text,
|
||||
from,
|
||||
to,
|
||||
type: "filter",
|
||||
},
|
||||
});
|
||||
} else if (typeof filter === "object" && !referencesOnly) {
|
||||
// This is a filter, which can be reused
|
||||
console.log(`Filter found in ${filePath}`);
|
||||
this.cache.push({
|
||||
id: `${json.id}.${filter.id}`,
|
||||
filePath: uri,
|
||||
jsonPath: ["filters"],
|
||||
type: "filter",
|
||||
});
|
||||
}
|
||||
uri,
|
||||
referencesOnly,
|
||||
fullFileText
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(`Error saving filters for ${from}`, error);
|
||||
}
|
||||
} else {
|
||||
console.log("No filters found in", filePath);
|
||||
|
@ -420,6 +372,305 @@ export class CacheWorker {
|
|||
this.printCache();
|
||||
}
|
||||
|
||||
private async saveTagRenderingsToCache(
|
||||
text: string,
|
||||
from: string,
|
||||
fromUri: vscode.Uri,
|
||||
referencesOnly = false,
|
||||
fullFileText?: string
|
||||
) {
|
||||
const json = JSON.parse(text);
|
||||
|
||||
for (const tagRendering of json.tagRenderings) {
|
||||
// Check if it is a string and not an object
|
||||
if (typeof tagRendering === "string") {
|
||||
// It is a reference
|
||||
console.log(
|
||||
`Reference found to tagRendering ${tagRendering} in ${from}`
|
||||
);
|
||||
|
||||
// The range is dependent on whether we're dealing with a full file or not
|
||||
// const fromStartEnd = fullFileText
|
||||
// ? getStartEnd(fullFileText, [
|
||||
// ...from.split("."),
|
||||
// "",
|
||||
// filterReferenceIndex,
|
||||
// ])
|
||||
// : getStartEnd(text, ["filter", filterReferenceIndex]);
|
||||
|
||||
// The range depends on whether we're dealing with a full file or not
|
||||
// const fromStartEnd = fullFileText
|
||||
// ? getStartEnd(fullFileText, [
|
||||
// ...from.split("."),
|
||||
// "tagRenderings",
|
||||
// json.tagRenderings.indexOf(tagRendering),
|
||||
// ])
|
||||
// : getStartEnd(text, [
|
||||
// "tagRenderings",
|
||||
// json.tagRenderings.indexOf(tagRendering),
|
||||
// ]);
|
||||
|
||||
// const to = tagRendering.includes(".")
|
||||
// ? `layers.${tagRendering.split(".")[0]}.tagRenderings.${
|
||||
// tagRendering.split(".")[1]
|
||||
// }`
|
||||
// : `layers.questions.tagRenderings.${tagRendering}`;
|
||||
// const toFile = await vscode.workspace.findFiles(
|
||||
// `**/assets/layers/${to.split("."[1])}/${to.split(".")[1]}.json`
|
||||
// );
|
||||
// // Read toFile and get the text
|
||||
// const toContent = await vscode.workspace.fs.readFile(toFile[0]);
|
||||
// const toText = new TextDecoder().decode(toContent);
|
||||
// const toJson = JSON.parse(toText);
|
||||
// const trIndex = toJson.tagRenderings.findIndex(
|
||||
// // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
// (tr: any) => tr.id === tagRendering.split(".")?.pop()
|
||||
// );
|
||||
// const toRange = getStartEnd(toText, ["tagRenderings", trIndex]);
|
||||
|
||||
// this.cache.push({
|
||||
// id: tagRendering,
|
||||
// filePath: fromUri,
|
||||
// jsonPath: ["tagRenderings"],
|
||||
// type: "reference",
|
||||
// reference: {
|
||||
// from: {
|
||||
// id: from,
|
||||
// uri: fromUri,
|
||||
// range: fromStartEnd,
|
||||
// },
|
||||
// to: {
|
||||
// id: to,
|
||||
// uri: toFile[0],
|
||||
// range: toRange,
|
||||
// },
|
||||
// type: "tagRendering",
|
||||
// },
|
||||
// });
|
||||
}
|
||||
// } else if (typeof tagRendering === "object") {
|
||||
// // This is a tagRendering, or a reference to one
|
||||
// if (tagRendering.builtin) {
|
||||
// // This is a reference to a built-in tagRendering (or multiple ones)
|
||||
// if (typeof tagRendering.builtin === "string") {
|
||||
// // Single tagRendering
|
||||
// console.log(
|
||||
// `Reference found to ${tagRendering.builtin} in ${from}`
|
||||
// );
|
||||
|
||||
// // The range depends on whether we're dealing with a full file or not
|
||||
// const fromStartEnd = fullFileText
|
||||
// ? getStartEnd(fullFileText, [
|
||||
// ...from.split("."),
|
||||
// "tagRenderings",
|
||||
// json.tagRenderings.indexOf(tagRendering),
|
||||
// ])
|
||||
// : getStartEnd(text, [
|
||||
// "tagRenderings",
|
||||
// json.tagRenderings.indexOf(tagRendering),
|
||||
// ]);
|
||||
|
||||
// const to = tagRendering.builtin.includes(".")
|
||||
// ? `layers.${tagRendering.builtin.split(".")[0]}.tagRenderings.${
|
||||
// tagRendering.builtin.split(".")[1]
|
||||
// }`
|
||||
// : `layers.questions.tagRenderings.${tagRendering.builtin}`;
|
||||
// const toFile = await vscode.workspace.findFiles(
|
||||
// `**/assets/layers/${to.split("."[1])}/${to.split(".")[1]}.json`
|
||||
// );
|
||||
// // Read toFile and get the text
|
||||
// const toContent = await vscode.workspace.fs.readFile(toFile[0]);
|
||||
// const toText = new TextDecoder().decode(toContent);
|
||||
// const toJson = JSON.parse(toText);
|
||||
// const trIndex = toJson.tagRenderings.findIndex(
|
||||
// // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
// (tr: any) => tr.id === tagRendering.builtin.split(".")?.pop()
|
||||
// );
|
||||
// const toRange = getStartEnd(toText, ["tagRenderings", trIndex]);
|
||||
|
||||
// this.cache.push({
|
||||
// id: tagRendering.builtin,
|
||||
// filePath: fromUri,
|
||||
// jsonPath: ["tagRenderings"],
|
||||
// type: "reference",
|
||||
// reference: {
|
||||
// from: {
|
||||
// id: from,
|
||||
// uri: fromUri,
|
||||
// range: fromStartEnd,
|
||||
// },
|
||||
// to: {
|
||||
// id: to,
|
||||
// uri: toFile[0],
|
||||
// range: toRange,
|
||||
// },
|
||||
// type: "tagRendering",
|
||||
// },
|
||||
// });
|
||||
// } else {
|
||||
// // Multiple tagRenderings
|
||||
// for (const builtinTagRendering of tagRendering.builtin) {
|
||||
// console.log(
|
||||
// `Reference found to ${builtinTagRendering} in ${from}`
|
||||
// );
|
||||
|
||||
// // The range depends on whether we're dealing with a full file or not
|
||||
// const fromStartEnd = fullFileText
|
||||
// ? getStartEnd(fullFileText, [
|
||||
// ...from.split("."),
|
||||
// "tagRenderings",
|
||||
// json.tagRenderings.indexOf(tagRendering),
|
||||
// ])
|
||||
// : getStartEnd(text, [
|
||||
// "tagRenderings",
|
||||
// json.tagRenderings.indexOf(tagRendering),
|
||||
// ]);
|
||||
|
||||
// const to = builtinTagRendering.includes(".")
|
||||
// ? `layers.${builtinTagRendering.split(".")[0]}.tagRenderings.${
|
||||
// builtinTagRendering.split(".")[1]
|
||||
// }`
|
||||
// : `layers.questions.tagRenderings.${builtinTagRendering}`;
|
||||
// const toFile = await vscode.workspace.findFiles(
|
||||
// `**/assets/layers/${to.split("."[1])}/${to.split(".")[1]}.json`
|
||||
// );
|
||||
// // Read toFile and get the text
|
||||
// const toContent = await vscode.workspace.fs.readFile(toFile[0]);
|
||||
// const toText = new TextDecoder().decode(toContent);
|
||||
// const toJson = JSON.parse(toText);
|
||||
// const trIndex = toJson.tagRenderings.findIndex(
|
||||
// // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
// (tr: any) => tr.id === builtinTagRendering.split(".")?.pop()
|
||||
// );
|
||||
// const toRange = getStartEnd(toText, ["tagRenderings", trIndex]);
|
||||
|
||||
// this.cache.push({
|
||||
// id: builtinTagRendering,
|
||||
// filePath: fromUri,
|
||||
// jsonPath: ["tagRenderings"],
|
||||
// type: "reference",
|
||||
// reference: {
|
||||
// from: {
|
||||
// id: from,
|
||||
// uri: fromUri,
|
||||
// range: fromStartEnd,
|
||||
// },
|
||||
// to: {
|
||||
// id: to,
|
||||
// uri: toFile[0],
|
||||
// range: toRange,
|
||||
// },
|
||||
// type: "tagRendering",
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// } else if (!referencesOnly) {
|
||||
// // This is a tagRendering, which can be reused
|
||||
// console.log(`TagRendering found in ${from}`);
|
||||
// this.cache.push({
|
||||
// id: `${json.id}.${tagRendering.id}`,
|
||||
// filePath: fromUri,
|
||||
// jsonPath: ["tagRenderings"],
|
||||
// type: "tagRendering",
|
||||
// });
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save filters to cache
|
||||
*
|
||||
* @param text Text representation of layer
|
||||
* @param from The theme or layer where the layer is from, e.g. layers.bicycle_rental or themes.cyclofix.layers.0
|
||||
* @param fromUri URI of the layer file
|
||||
* @param referencesOnly Whether to only save references, or also the tagRenderings and filters. This is useful for inline layers, because their filters and tagRenderings can't be reused
|
||||
* @param fullFileText The full text of the original theme file, used for calculating position
|
||||
*/
|
||||
private async saveFiltersToCache(
|
||||
text: string,
|
||||
from: string,
|
||||
fromUri: vscode.Uri,
|
||||
referencesOnly = false,
|
||||
fullFileText?: string
|
||||
) {
|
||||
const json = JSON.parse(text);
|
||||
|
||||
for (const filter of json.filter) {
|
||||
const filterReferenceIndex = json.filter.indexOf(filter);
|
||||
|
||||
// Check if it is a string and not an object
|
||||
if (typeof filter === "string") {
|
||||
// It is a reference
|
||||
console.log(`Reference found to filter ${filter} in ${from}`);
|
||||
|
||||
// The range is dependent on whether we're dealing with a full file or not
|
||||
const fromStartEnd = fullFileText
|
||||
? getStartEnd(fullFileText, [
|
||||
...from.split("."),
|
||||
"filter",
|
||||
filterReferenceIndex,
|
||||
])
|
||||
: getStartEnd(text, ["filter", filterReferenceIndex]);
|
||||
|
||||
const filterId = filter.includes(".") ? filter.split(".")[1] : filter;
|
||||
const to = filter.includes(".")
|
||||
? `layers.${filter.split(".")[0]}`
|
||||
: `layers.filters`;
|
||||
// Now we'll need to determine what file we need to look in
|
||||
const toFileName = filter.includes(".")
|
||||
? `**/assets/layers/${filter.split(".")[0]}/${
|
||||
filter.split(".")[0]
|
||||
}.json`
|
||||
: `**/assets/layers/filters/filters.json`;
|
||||
const toFile = await vscode.workspace.findFiles(toFileName);
|
||||
|
||||
const toContent = await vscode.workspace.fs.readFile(toFile[0]);
|
||||
const toText = new TextDecoder().decode(toContent);
|
||||
const toJson = JSON.parse(toText);
|
||||
const toFilterIndex = toJson.filter.findIndex(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(f: any) => f.id === filterId
|
||||
);
|
||||
|
||||
if (toFilterIndex === -1) {
|
||||
console.error(`Filter ${filter} not found`);
|
||||
continue;
|
||||
}
|
||||
const toRange = getStartEnd(toText, ["filter", toFilterIndex]);
|
||||
|
||||
this.cache.push({
|
||||
id: filter,
|
||||
filePath: fromUri,
|
||||
jsonPath: ["filters"],
|
||||
type: "reference",
|
||||
reference: {
|
||||
from: {
|
||||
id: from,
|
||||
uri: fromUri,
|
||||
range: fromStartEnd,
|
||||
},
|
||||
to: {
|
||||
id: to,
|
||||
uri: toFile[0],
|
||||
range: toRange,
|
||||
},
|
||||
type: "filter",
|
||||
},
|
||||
});
|
||||
} else if (typeof filter === "object" && !referencesOnly) {
|
||||
// This is a filter, which can be reused
|
||||
console.log(`Filter found in ${from}`);
|
||||
this.cache.push({
|
||||
id: `${json.id}.${filter.id}`,
|
||||
filePath: fromUri,
|
||||
jsonPath: ["filters"],
|
||||
type: "filter",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the current cache state
|
||||
* TODO: This probably needs to be removed at some point
|
||||
|
@ -522,7 +773,7 @@ export class Cache {
|
|||
public getReferences(to: string): CacheItem[] {
|
||||
return this.cache.filter((item) => {
|
||||
if (item.type === "reference") {
|
||||
return item.reference?.to === to;
|
||||
return item.reference?.to.id === to;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
@ -570,23 +821,41 @@ interface CacheItem {
|
|||
*/
|
||||
interface Reference {
|
||||
/**
|
||||
* The theme or layer where the reference is from
|
||||
*
|
||||
* @example themes.cyclofix
|
||||
* The place where the item is being used (eg. themes.cyclofix)
|
||||
*/
|
||||
from: string;
|
||||
from: ReferenceDetail;
|
||||
|
||||
/**
|
||||
* The path of the file where the reference points to
|
||||
* This can also be more specific, like a tagRendering or filter
|
||||
*
|
||||
* @example layers.bicycle_rental
|
||||
* @example layers.questions.tagRenderings.name
|
||||
* The place where the item is defined (eg. layers.bicycle_rental)
|
||||
*/
|
||||
to: string;
|
||||
to: ReferenceDetail;
|
||||
|
||||
/**
|
||||
* The type of item being referenced/reused
|
||||
*/
|
||||
type: "tagRendering" | "filter" | "layer";
|
||||
}
|
||||
|
||||
interface ReferenceDetail {
|
||||
/**
|
||||
* The path of the file for this side of the reference
|
||||
*
|
||||
* @example layers.bicycle_rental
|
||||
* @example layers.questions.tagRenderings.name
|
||||
* @example themes.cyclofix
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* The URI of the file for this side of the reference
|
||||
*/
|
||||
uri?: vscode.Uri;
|
||||
|
||||
/**
|
||||
* The range of the reference in the file
|
||||
* Useful for highlighting the reference in the file
|
||||
*
|
||||
* Only defined when referencing to a part of a file
|
||||
*/
|
||||
range?: vscode.Range;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue