From 9a0aed532436a37869372c34a2dbbd78c33da3a9 Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Fri, 28 Aug 2020 01:11:41 -0400 Subject: [PATCH] add AST as component, need to fix styling --- .eslintignore | 3 + sandbox/package.json | 1 + sandbox/src/components/AST.js | 72 ++++++++++++++++++++++ sandbox/src/components/App.js | 109 ++++++++++++++++++++++------------ sandbox/src/standalone.js | 17 +++++- yarn.lock | 54 +++++++++++++++++ 6 files changed, 216 insertions(+), 40 deletions(-) create mode 100644 sandbox/src/components/AST.js diff --git a/.eslintignore b/.eslintignore index 1fba0618658f..9d488dd02b68 100644 --- a/.eslintignore +++ b/.eslintignore @@ -27,3 +27,6 @@ packages/babel-parser/test/expressions eslint/*/lib eslint/*/node_modules eslint/*/test/fixtures + +# jsx +sandbox/src diff --git a/sandbox/package.json b/sandbox/package.json index 3251b163697e..4af3797ac070 100644 --- a/sandbox/package.json +++ b/sandbox/package.json @@ -13,6 +13,7 @@ "react": "^16.11.0", "react-codemirror2": "^7.2.0", "react-dom": "^16.11.0", + "react-json-tree": "^0.12.1", "styled-components": "4.4.1" }, "scripts": { diff --git a/sandbox/src/components/AST.js b/sandbox/src/components/AST.js new file mode 100644 index 000000000000..03399e0a5579 --- /dev/null +++ b/sandbox/src/components/AST.js @@ -0,0 +1,72 @@ +import React from "react"; +import JSONTree from "react-json-tree"; + +function formatNode(data) { + if (data.type === "Identifier") { + return {`${data.type} (${data.name})`}; + } else if (data.type === "StringLiteral") { + return {`${data.type} (${data.value})`}; + } else if (data.type === "TemplateElement") { + return {`${data.type} (${data.value.cooked})`}; + } else if (data.type === "BooleanLiteral") { + return {`${data.type} (${data.value})`}; + } else if (data.type === "RegExpLiteral") { + return {`${data.type} (${data.pattern})`}; + } + return {`${data.type}`}; +} + +let autoExpand = { + root: true, + program: true, + body: true, +}; + +export default function AST({ ast }) { + return ( + { + // hide start/end? + if (value?.type) { + if (typeof value.start === "number") delete value.start; + if (typeof value.end === "number") delete value.end; + } + return value; + }} + nestedNodeLabel={({ style }, keyPath, nodeType, expanded) => ({ + style: { + ...style, + textTransform: expanded ? "uppercase" : style.textTransform, + }, + })} + shouldExpandNode={(keyPath, data, level) => { + return autoExpand[keyPath[0]]; + }} + getItemString={(type, data, itemType, itemString) => { + if (data.type) { + return formatNode(data); + } else if (data.start) { + return ( + + {`${data.start.line}:${data.start.column}, ${data.end.line}:${data.end.column}`} + + ); + } else if (data.line) { + return {`${data.line}:${data.column}`}; + } + + return ( + + {itemType} {itemString} + + ); + }} + /> + ); +} diff --git a/sandbox/src/components/App.js b/sandbox/src/components/App.js index b2533bd2a941..f0b5d6553027 100644 --- a/sandbox/src/components/App.js +++ b/sandbox/src/components/App.js @@ -3,6 +3,7 @@ import * as Babel from "@babel/core"; import traverse from "@babel/traverse"; import styled, { css } from "styled-components"; +import AST from "./AST"; import { Editor } from "./Editor"; import { processOptions } from "../standalone"; import { gzipSize } from "../gzip"; @@ -85,6 +86,8 @@ let proposalMap = { function CompiledOutput({ source, + sourceAST, + parserError, customPlugin, config, onConfigChange, @@ -97,7 +100,6 @@ function CompiledOutput({ const [outputEditor, setOutputEditor] = useState(null); const [compiled, setCompiled] = useState({ nodes: [] }); const [gzip, setGzip] = useState(null); - const debouncedPlugin = useDebounce(customPlugin, 125); useEffect(() => { if (!outputEditor || !debouncedCursor) return; @@ -152,13 +154,21 @@ function CompiledOutput({ }, [outputEditor, compiled.nodes]); useEffect(() => { + if (parserError) { + setCompiled({ + code: parserError, + error: true, + }); + return; + } try { let nodes = []; - const { code, ast } = Babel.transform( + const { code, ast } = Babel.transformFromAstSync( + sourceAST, source, - processOptions(config, debouncedPlugin) + processOptions(config, customPlugin) ); - let newAST = Babel.parse(code, processOptions(config, debouncedPlugin)); + let newAST = Babel.parse(code, processOptions(config, customPlugin)); mergeLoc(ast, newAST, (value, loc) => { let node = { ...value, loc }; let added = nodes.some((existingNode, i) => { @@ -191,7 +201,7 @@ function CompiledOutput({ error: true, }); } - }, [source, config, debouncedPlugin]); + }, [source, config, sourceAST, parserError, customPlugin]); return ( @@ -227,7 +237,7 @@ function CompiledOutput({ {compiled?.size}b, {gzip}b{" "} - + @@ -243,6 +253,7 @@ export default function App({ const [source, setSource] = React.useState(defaultSource); const [enableCustomPlugin, toggleCustomPlugin] = React.useState(gist); const [customPlugin, setCustomPlugin] = React.useState(defCustomPlugin); + const debouncedPlugin = useDebounce(customPlugin, 125); const [babelConfig, setBabelConfig] = useState( Array.isArray(defaultBabelConfig) ? defaultBabelConfig @@ -251,6 +262,9 @@ export default function App({ const [size, setSize] = useState(null); const [gzip, setGzip] = useState(null); const debouncedSource = useDebounce(source, 125); + const [ast, setAST] = React.useState(null); + const [parserError, setParserError] = React.useState(null); + const [showAST, toggleAST] = useState(true); // TODO: false const updateBabelConfig = useCallback((config, index) => { setBabelConfig(configs => { @@ -265,25 +279,22 @@ export default function App({ setBabelConfig(configs => configs.filter((c, i) => index !== i)); }, []); - let results = babelConfig.map((config, index) => { - return ( - updateBabelConfig(config, index)} - removeConfig={() => removeBabelConfig(index)} - /> - ); - }); - useEffect(() => { + try { + let sourceAST = Babel.parse( + debouncedSource, + processOptions({}, debouncedPlugin) + ); + setAST(sourceAST); + setParserError(null); + } catch (e) { + console.warn(e.stack); + setParserError(e.message); + } let size = new Blob([debouncedSource], { type: "text/plain" }).size; setSize(size); gzipSize(debouncedSource).then(s => setGzip(s)); - }, [debouncedSource]); + }, [debouncedSource, debouncedPlugin]); return ( @@ -311,24 +322,44 @@ export default function App({ toggleCustomPlugin(false)} /> )} - -
Source
- setSource(val)} - docName="source.js" - getEditor={editor => { - window.sourceEditor = editor; - }} - /> - - {size}b, {gzip}b - - -
- {results} + + +
Source
+ setSource(val)} + docName="source.js" + getEditor={editor => { + window.sourceEditor = editor; + }} + /> + + {size}b, {gzip}b + + + + {showAST && ast ? : null} +
+
+ {ast && + babelConfig.map((config, index) => { + return ( + updateBabelConfig(config, index)} + removeConfig={() => removeBabelConfig(index)} + /> + ); + })}
); diff --git a/sandbox/src/standalone.js b/sandbox/src/standalone.js index 0f2efa0fc26e..2f4b72c73aa9 100644 --- a/sandbox/src/standalone.js +++ b/sandbox/src/standalone.js @@ -13,7 +13,22 @@ export function transpilePlugin(pluginString) { configFile: false, ast: false, highlightCode: false, - presets: [availablePresets["@babel/preset-env"]], + presets: [ + [ + availablePresets["@babel/preset-env"], + { loose: true, shippedProposals: true }, + ], + [ + availablePresets["@babel/preset-typescript"], + { + isTSX: true, + allExtensions: true, + allowDeclareFields: true, + allowNamespaces: true, + onlyRemoveTypeImports: true, + }, + ], + ], plugins: [metadataPlugin], }).code; } diff --git a/yarn.lock b/yarn.lock index 0faf069a7685..e619d83e688d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6773,6 +6773,7 @@ __metadata: react: ^16.11.0 react-codemirror2: ^7.2.0 react-dom: ^16.11.0 + react-json-tree: ^0.12.1 react-scripts: ~3.4.1 styled-components: 4.4.1 languageName: unknown @@ -7028,6 +7029,13 @@ __metadata: languageName: node linkType: hard +"base16@npm:^1.0.0": + version: 1.0.0 + resolution: "base16@npm:1.0.0" + checksum: adc3f12a6b363a2bfa4062d45e2782791737f7ceb0857c027486fc90fd3fc8eaf1829c55cc7a4afd6e482105282ffc18362bc10b2a4c788f3102de3054558eba + languageName: node + linkType: hard + "base64-js@npm:^1.0.2": version: 1.3.1 resolution: "base64-js@npm:1.3.1" @@ -14718,6 +14726,20 @@ fsevents@~2.1.2: languageName: node linkType: hard +"lodash.curry@npm:^4.1.1": + version: 4.1.1 + resolution: "lodash.curry@npm:4.1.1" + checksum: 081f9214b5d65030e66d0219c330de5a07089096f20362fc965c671b70b2bdb7b8f4cbac45546f79afed3bf17ae46434ffea9db1dbcbe043a09b722e2834ac3d + languageName: node + linkType: hard + +"lodash.flow@npm:^3.5.0": + version: 3.5.0 + resolution: "lodash.flow@npm:3.5.0" + checksum: 52204602c6ec53e78497387751bf2cf432a9db7b0982e62b01b489be847b68efde8f7efed6fbeaeaeb66d7c7bd171d389c32d548908eafc00958bba8d462e55a + languageName: node + linkType: hard + "lodash.get@npm:^4.4.2": version: 4.4.2 resolution: "lodash.get@npm:4.4.2" @@ -18187,6 +18209,13 @@ fsevents@~2.1.2: languageName: node linkType: hard +"pure-color@npm:^1.3.0": + version: 1.3.0 + resolution: "pure-color@npm:1.3.0" + checksum: 73ceb18cf945bd632e98b068dff16fb50178a067df3af8c7aa5c2bbd847ed3f3d158e7dd0f6ff705c23fe69bf215ca94af36cd4ca7cef4da0ce57031f8238a7a + languageName: node + linkType: hard + "q@npm:^1.1.2, q@npm:^1.5.1": version: 1.5.1 resolution: "q@npm:1.5.1" @@ -18321,6 +18350,18 @@ fsevents@~2.1.2: languageName: node linkType: hard +"react-base16-styling@npm:^0.7.0": + version: 0.7.0 + resolution: "react-base16-styling@npm:0.7.0" + dependencies: + base16: ^1.0.0 + lodash.curry: ^4.1.1 + lodash.flow: ^3.5.0 + pure-color: ^1.3.0 + checksum: 1f99f8f18c3acd8468614c2efd2424b6f526143bb5de29520feabe33e219841c39acc8029cb576d5573e8fe94f23da0ddd886cf4fa1a7302e97fa34735486eb9 + languageName: node + linkType: hard + "react-codemirror2@npm:^7.2.0": version: 7.2.1 resolution: "react-codemirror2@npm:7.2.1" @@ -18391,6 +18432,19 @@ fsevents@~2.1.2: languageName: node linkType: hard +"react-json-tree@npm:^0.12.1": + version: 0.12.1 + resolution: "react-json-tree@npm:0.12.1" + dependencies: + prop-types: ^15.7.2 + react-base16-styling: ^0.7.0 + peerDependencies: + react: ^16.3.0 + react-dom: ^16.3.0 + checksum: 4c0250bc4f8a09e537dc2df0989881b8747e79bd223a56e181c5c173e32671d906a14ae5792387c62c4c1d47dbefea8c2e96db1dc6d1fb6bb8f3c0d728f7a4c4 + languageName: node + linkType: hard + "react-scripts@npm:~3.4.1": version: 3.4.3 resolution: "react-scripts@npm:3.4.3"