Skip to content

Commit 319a4c3

Browse files
committed
thank ChatGPT
1 parent 7bbd822 commit 319a4c3

File tree

4 files changed

+136
-11
lines changed

4 files changed

+136
-11
lines changed

src/commands/showPanel.tsx

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { FRONTEND_ELEMENT_ID } from "../constants";
1515
import { client, SOURCE_ACADEMY_ICON_URI } from "../extension";
1616
import _ from "lodash";
1717
import { treeDataProvider } from "../treeview";
18+
import { getValue, mirror, setValue } from "../utils/store/test";
1819

1920
let panel: vscode.WebviewPanel | null = null;
2021
// This needs to be a reference to active
@@ -52,18 +53,23 @@ async function handleMessage(
5253
message.initialCode,
5354
);
5455
activeEditor.uri;
55-
const info = context.globalState.get("info") ?? {};
56+
// const info = context.globalState.get("info") ?? {};
57+
const info = getValue(mirror.info);
5658
if (activeEditor.uri) {
5759
// TODO: Write our own wrapper to set nested keys easily, removing lodash
5860
// @ts-ignore
59-
_.set(info, `["${activeEditor.uri}"].chapter`, message.chapter ?? 1);
61+
// _.set(info, `["${activeEditor.uri}"].chapter`, message.chapter ?? 1);
62+
info[activeEditor.uri].chapter = message.chapter ?? 1;
63+
6064
// TODO: message.prepend can be undefined in runtime, investigate
6165
const nPrependLines =
6266
message.prepend && message.prepend !== ""
6367
? message.prepend.split("\n").length + 2 // account for start/end markers
6468
: 0;
65-
_.set(info, `["${activeEditor.uri}"].prepend`, nPrependLines);
66-
context.globalState.update("info", info);
69+
// _.set(info, `["${activeEditor.uri}"].prepend`, nPrependLines);
70+
info[activeEditor.uri].prepend = nPrependLines;
71+
// context.globalState.update("info", info);
72+
setValue(mirror.info, info);
6773
client.sendRequest("source/publishInfo", info);
6874
}
6975

@@ -96,8 +102,10 @@ async function handleMessage(
96102
// break;
97103
case MessageTypeNames.NotifyAssessmentsOverview:
98104
const { assessmentOverviews, courseId } = message;
99-
context.globalState.update("assessmentOverviews", assessmentOverviews);
100-
context.globalState.update("courseId", courseId);
105+
// context.globalState.update("assessmentOverviews", assessmentOverviews);
106+
setValue(mirror.assessmentOverviews, assessmentOverviews);
107+
// context.globalState.update("courseId", courseId);
108+
setValue(mirror.courseId, courseId);
101109
treeDataProvider.refresh();
102110
break;
103111
}

src/extension.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,20 @@ import { setupStatusBar } from "./statusbar/status";
66
import { registerAllCommands } from "./commands";
77
import { activateLspClient, deactivateLspClient } from "./lsp/client";
88
import { LanguageClient } from "vscode-languageclient/node";
9+
import { getValue, mirror } from "./utils/store/test";
910

1011
// TODO: Don't expose this object directly, create an interface via a wrapper class
1112
export let client: LanguageClient;
1213

1314
export let SOURCE_ACADEMY_ICON_URI: vscode.Uri;
1415

16+
export let context_: vscode.ExtensionContext;
17+
1518
// This method is called when your extension is activated
1619
// Your extension is activated the very first time the command is executed
1720
export function activate(context: vscode.ExtensionContext) {
21+
console.log("Activain");
22+
context_ = context;
1823
setupTreeView(context);
1924
registerAllCommands(context);
2025

@@ -25,7 +30,8 @@ export function activate(context: vscode.ExtensionContext) {
2530
// const info = {
2631
// "file:///home/heyzec/.sourceacademy/playground_1.js": { chapter: 4 },
2732
// };
28-
const info = context.globalState.get("info") ?? {};
33+
// const info = context.globalState.get("info") ?? {};
34+
const info = getValue(mirror.info) ?? {};
2935

3036
client.sendRequest("source/publishInfo", info);
3137

@@ -34,6 +40,7 @@ export function activate(context: vscode.ExtensionContext) {
3440
"assets",
3541
"icon.svg",
3642
);
43+
vscode.window.showInformationMessage(`mirror is ${JSON.stringify(mirror)}`);
3744
}
3845

3946
// This method is called when your extension is deactivated

src/treeview/index.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import * as vscode from "vscode";
22
import { VscAssessmentOverview } from "../utils/messages";
33
import { SOURCE_ACADEMY_ICON_URI } from "../extension";
4+
import { getValue, mirror } from "../utils/store/test";
45

56
export let treeDataProvider: AssessmentsSidebarProvider;
67

78
// This will be a source of bug on first extension loads!!
89
let courseId: number;
910

1011
export function setupTreeView(context: vscode.ExtensionContext) {
11-
courseId = context.globalState.get("courseId") as number;
12+
// courseId = context.globalState.get("courseId") as number;
13+
courseId = getValue(mirror.courseId);
1214

1315
treeDataProvider = new AssessmentsSidebarProvider(context);
1416
vscode.window.createTreeView("assessments", {
@@ -33,9 +35,11 @@ export class AssessmentsSidebarProvider
3335
}
3436

3537
getChildren(element?: BaseTreeItem): Thenable<BaseTreeItem[]> {
36-
// @ts-ignore
37-
const assessmentOverviews: VscAssessmentOverview[] =
38-
this.context.globalState.get("assessmentOverviews");
38+
// // @ts-ignore
39+
// const assessmentOverviews: VscAssessmentOverview[] =
40+
// this.context.globalState.get("assessmentOverviews");
41+
const assessmentOverviews = getValue(mirror.assessmentOverviews);
42+
3943
if (!assessmentOverviews) {
4044
return Promise.resolve([]);
4145
}

src/utils/store/test.ts

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import { context_ } from "../../extension";
2+
import { VscAssessmentOverview } from "../messages";
3+
4+
/**
5+
* There is a lot of casting in this file but in theory it should all work...
6+
*/
7+
8+
// 1. Leaf wrapper for types
9+
type Leaf<T> = { __type: T };
10+
11+
type Entry = {
12+
chapter: number;
13+
prepend: number;
14+
};
15+
16+
// 2. Schema with types
17+
const schema = {
18+
courseId: {} as Leaf<number>,
19+
assessmentOverviews: {} as Leaf<VscAssessmentOverview[]>,
20+
info: {} as Leaf<Record<string, Entry>>,
21+
A: {
22+
B: {} as Leaf<string>,
23+
ao: {} as Leaf<VscAssessmentOverview[]>,
24+
},
25+
C: {
26+
D: {} as Leaf<number>,
27+
E: {} as number,
28+
},
29+
};
30+
31+
// Purpose: Creates a nested object that mirrors the shape of T, but replaces leaves with the string path to that leaf.
32+
type PathTree<T, Prefix extends string = ""> = {
33+
[K in keyof T]: T[K] extends Leaf<any>
34+
? `${Prefix}${K & string}`
35+
: T[K] extends object
36+
? PathTree<T[K], `${Prefix}${K & string}.`>
37+
: never;
38+
};
39+
40+
function generateMirrorTree(obj: object, prefix = ""): object {
41+
const result: any = {};
42+
for (const key in obj) {
43+
const path = prefix ? `${prefix}.${key}` : key;
44+
// @ts-ignore
45+
const val = obj[key];
46+
47+
if (val && typeof val === "object" && Object.keys(val).length > 0) {
48+
result[key] = generateMirrorTree(val, path);
49+
} else {
50+
result[key] = path;
51+
}
52+
}
53+
return result;
54+
}
55+
56+
export const mirror = generateMirrorTree(schema) as PathTree<typeof schema>;
57+
58+
const mockStore = {
59+
"A.B": "a string",
60+
"C.D": 1,
61+
} as any;
62+
63+
// Purpose: Creates a union of objects, each mapping a full dot-path string to the type stored in the leaf.
64+
// prettier-ignore
65+
type LeafPathsToTypes<T, Prefix extends string = ""> = {
66+
[K in keyof T]:
67+
// Ask: Is this is a Leaf<...>?
68+
T[K] extends Leaf<infer U>
69+
// Yes, extract its type
70+
? { [P in `${Prefix}${K & string}`]: U }
71+
// Else, ask: Is this a nested object?
72+
// Assume yes, recurse
73+
: T[K] extends object
74+
? LeafPathsToTypes<T[K], `${Prefix}${K & string}.`>
75+
// Else, this never occurs
76+
: never;
77+
}[keyof T];
78+
79+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
80+
k: infer I,
81+
) => void
82+
? I
83+
: never;
84+
85+
type PathTypeMap = UnionToIntersection<LeafPathsToTypes<typeof schema>>;
86+
87+
type Test1 = PathTree<typeof schema>;
88+
type Test2 = LeafPathsToTypes<typeof schema>;
89+
90+
export function getValue<K extends keyof PathTypeMap>(key: K): PathTypeMap[K] {
91+
console.log(`Getting vlaue of ${key}`);
92+
93+
// return mockStore[k];
94+
if (!context_) {
95+
console.log("OHNO w");
96+
}
97+
const x = context_.globalState.get(key);
98+
return x as any;
99+
}
100+
101+
export function setValue<K extends keyof PathTypeMap>(
102+
key: K,
103+
value: PathTypeMap[K],
104+
) {
105+
context_.globalState.update(key, value);
106+
}

0 commit comments

Comments
 (0)