diff options
author | Tyler Schicke <tyler_schicke@brown.edu> | 2019-05-24 00:56:32 -0400 |
---|---|---|
committer | Tyler Schicke <tyler_schicke@brown.edu> | 2019-05-24 00:56:32 -0400 |
commit | dcfc5d77779117616503c31fc03f36841e25a3f9 (patch) | |
tree | fc31bed4ec807f147cbaf51c81d584377b370024 | |
parent | 34b38c7382a40fb2a117d3c7418a81b34fa7ed7f (diff) |
Added basic repl page
-rw-r--r-- | deploy/debug/repl.html | 14 | ||||
-rw-r--r-- | src/client/util/Scripting.ts | 7 | ||||
-rw-r--r-- | src/debug/Repl.tsx | 58 | ||||
-rw-r--r-- | src/new_fields/Doc.ts | 15 | ||||
-rw-r--r-- | webpack.config.js | 1 |
5 files changed, 91 insertions, 4 deletions
diff --git a/deploy/debug/repl.html b/deploy/debug/repl.html new file mode 100644 index 000000000..8ab07ec49 --- /dev/null +++ b/deploy/debug/repl.html @@ -0,0 +1,14 @@ +<html> + +<head> + <title>Debug REPL</title> + <link href="https://fonts.googleapis.com/css?family=Fjalla+One|Hind+Siliguri:300" rel="stylesheet"> + <script src="https://cdnjs.cloudflare.com/ajax/libs/typescript/3.3.1/typescript.min.js"></script> +</head> + +<body> + <div id="root"></div> + <script src="../repl.js"></script> +</body> + +</html>
\ No newline at end of file diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index e45f61c11..beaf5cb03 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -41,7 +41,7 @@ export type CompileResult = CompiledScript | CompileError; function Run(script: string | undefined, customParams: string[], diagnostics: any[], originalScript: string, options: ScriptOptions): CompileResult { const errors = diagnostics.some(diag => diag.category === ts.DiagnosticCategory.Error); - if (errors || !script) { + if ((options.typecheck !== false && errors) || !script) { return { compiled: false, errors: diagnostics }; } @@ -131,10 +131,11 @@ export interface ScriptOptions { addReturn?: boolean; params?: { [name: string]: string }; capturedVariables?: { [name: string]: Field }; + typecheck?: boolean; } export function CompileScript(script: string, options: ScriptOptions = {}): CompileResult { - const { requiredType = "", addReturn = false, params = {}, capturedVariables = {} } = options; + const { requiredType = "", addReturn = false, params = {}, capturedVariables = {}, typecheck = true } = options; let host = new ScriptingCompilerHost; let paramNames: string[] = []; if ("this" in params || "this" in capturedVariables) { @@ -158,7 +159,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp ${addReturn ? `return ${script};` : script} })`; host.writeFile("file.ts", funcScript); - host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib); + if (typecheck) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib); let program = ts.createProgram(["file.ts"], {}, host); let testResult = program.emit(); let outputText = host.readFile("file.js"); diff --git a/src/debug/Repl.tsx b/src/debug/Repl.tsx new file mode 100644 index 000000000..16aef1925 --- /dev/null +++ b/src/debug/Repl.tsx @@ -0,0 +1,58 @@ +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { observer } from 'mobx-react'; +import { observable, computed } from 'mobx'; +import { CompileScript } from '../client/util/Scripting'; + +@observer +class Repl extends React.Component { + @observable text: string = ""; + + @observable executedCommands: { command: string, result: any }[] = []; + + onChange = (e: React.ChangeEvent<HTMLInputElement>) => { + this.text = e.target.value; + } + + onKeyDown = (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + const script = CompileScript(this.text, { addReturn: true, typecheck: false }); + if (!script.compiled) { + this.executedCommands.push({ command: this.text, result: "Compile Error" }); + } else { + const result = script.run(); + if (result.success) { + this.executedCommands.push({ command: this.text, result: result.result }); + } else { + this.executedCommands.push({ command: this.text, result: result.error }); + } + } + this.text = ""; + } + } + + @computed + get commands() { + return this.executedCommands.map(command => { + return ( + <div style={{ marginTop: "5px" }}> + <p>{command.command}</p> + <p>{JSON.stringify(command.result)}</p> + </div> + ); + }); + } + + render() { + return ( + <div> + <div style={{ verticalAlign: "bottom" }}> + {this.commands} + </div> + <input style={{ width: "100%", position: "absolute", bottom: "0px" }} value={this.text} onChange={this.onChange} onKeyDown={this.onKeyDown} /> + </div> + ); + } +} + +ReactDOM.render(<Repl />, document.getElementById("root"));
\ No newline at end of file diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 793a83750..0c74b8f65 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -62,6 +62,7 @@ export class Doc extends RefField { const doc = new Proxy<this>(this, { set: setter, get: getter, + // getPrototypeOf: (target) => Cast(target[SelfProxy].proto, Doc) || null, // TODO this might be able to replace the proto logic in getter has: (target, key) => key in target.__fields, ownKeys: target => Object.keys(target.__fields), getOwnPropertyDescriptor: (target, prop) => { @@ -69,6 +70,7 @@ export class Doc extends RefField { return { configurable: true,//TODO Should configurable be true? enumerable: true, + value: target.__fields[prop] }; } return Reflect.getOwnPropertyDescriptor(target, prop); @@ -197,6 +199,18 @@ export namespace Doc { return Doc.GetT(doc, "isPrototype", "boolean", true) ? doc : doc.proto!; } + export function allKeys(doc: Doc): string[] { + const results: Set<string> = new Set; + + let proto: Doc | undefined = doc; + while (proto) { + Object.keys(proto).forEach(key => results.add(key)); + proto = proto.proto; + } + + return Array.from(results); + } + export function MakeAlias(doc: Doc) { const proto = Object.getOwnPropertyNames(doc).indexOf("isPrototype") === -1 ? doc.proto : undefined; @@ -246,5 +260,4 @@ export namespace Doc { delegate.proto = doc; return delegate; } - export const Prototype = Symbol("Prototype"); }
\ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index c08742272..5e0a6a883 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -8,6 +8,7 @@ module.exports = { entry: { bundle: ["./src/client/views/Main.tsx", 'webpack-hot-middleware/client?reload=true'], viewer: ["./src/debug/Viewer.tsx", 'webpack-hot-middleware/client?reload=true'], + repl: ["./src/debug/Repl.tsx", 'webpack-hot-middleware/client?reload=true'], test: ["./src/debug/Test.tsx", 'webpack-hot-middleware/client?reload=true'], inkControls: ["./src/mobile/InkControls.tsx", 'webpack-hot-middleware/client?reload=true'], imageUpload: ["./src/mobile/ImageUpload.tsx", 'webpack-hot-middleware/client?reload=true'], |