-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
AST Explorer #1933
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sujinleeme
wants to merge
43
commits into
babel:main
Choose a base branch
from
sujinleeme:AST
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
AST Explorer #1933
Changes from all commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
ca9e033
Add AST checkbox in options and set state in url
sujinleeme d2dad33
Updates to old posts (#1758)
hzoo 74f64d9
fix headings
hzoo 59d8ffc
Fix some broken links (#1752)
notlmn 732c99e
rename 6.x to 6.26.3 (#1759) [skip ci]
hzoo 6122e99
Remove outdated reference to Makefile from readme (#1761) [skip ci]
suchipi 7aa44ae
Upgrade prettier (#1760)
suchipi 8fb71e6
Hide docs version on repl page (#1762)
suchipi 673e1ba
[email protected] (#1765)
existentialism 0bcd398
add browserslist config
existentialism e3a0160
Update v7-migration.md
hzoo 565f2f6
Rewrite env docs (#1766)
existentialism 0397c4f
match css custom class names to hljs class names
vikr01 d297059
Change package titles to be scoped (#1770)
notlmn f176b63
add css style for JSX
vikr01 924a505
Add AST Panel in Repl
ianchobuilds dfbd537
Complie AST ouput and add astContexxt in Relp's state
sujinleeme 5d36491
Merge branch 'AST_worker' into AST
sujinleeme 6feafb1
Persist AST context state when its compiled
sujinleeme f780507
Use decodeURI() instead of deprecated unescape()
sujinleeme 8750cf8
Remove duplicate compiled AST variable
sujinleeme 6cd3d4c
Collapse most nodes and fix scroll
ianchobuilds 543e4e1
Sync upstream repo
7c18a63
Sync upstream repo
sujinleeme ed92794
wip
sujinleeme 7df9280
Install react-json-view
sujinleeme 0380002
Create ASTPanel component
sujinleeme 1593578
Create flatten, unflatten funcs to control AST source
sujinleeme 262c531
Create deleteFlatten, mergeFlatten funcs
sujinleeme c975379
Trigger show/hide type keys in AST ouput object
sujinleeme 2d8aba1
code review by @benevbright
sujinleeme 5f4ac6c
fix popup error msg while ast code is compiling
sujinleeme 3c6e1a6
filter location, null value in AST options
sujinleeme 5f236b6
if-else shorthand in getDerivedStateFromProps
sujinleeme e0ee4c8
Add default in triggerAstOutput func
sujinleeme 02d8e83
Update ASTOption and ASTpanel styling
sujinleeme d534988
Update ReactJson styling
sujinleeme c5f8d84
Sync upstream repo
sujinleeme 8256bd0
remove _fromTemplate, _letDone props in AST
sujinleeme 03067db
Merge branch 'master' into AST
sujinleeme 1d08d6d
Fix conflict on yarn.lock
sujinleeme 0828e25
Update yarn.lock
sujinleeme 00da94b
Remove '_' props in AST
sujinleeme File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,192 @@ | ||
| // @flow | ||
|
|
||
| import { css } from "emotion"; | ||
| import { colors } from "./styles"; | ||
| import React from "react"; | ||
| import ReactJson from "react-json-view"; | ||
| import { | ||
| flatten, | ||
| filterFlatten, | ||
| unflatten, | ||
| deleteFlatten, | ||
| mergeFlatten, | ||
| reject, | ||
| } from "./ASTUtils"; | ||
|
|
||
| type Props = { | ||
| className?: string, | ||
| src: Object, | ||
| }; | ||
|
|
||
| type State = { | ||
| src: Object, | ||
| flattenEmpty: Object, | ||
| flattenSrc: Object, | ||
| flattenType: Object, | ||
| flattenLocation: Object, | ||
| astOption: { | ||
| location: boolean, | ||
| empty: boolean, | ||
| type: boolean, | ||
| }, | ||
| }; | ||
|
|
||
| const OPTION_ORDER = ["location", "empty", "type"]; | ||
|
|
||
| export default class ASTPanel extends React.Component<Props, State> { | ||
| state = { | ||
| src: {}, | ||
| flattenEmpty: {}, | ||
| flattenSrc: {}, | ||
| flattenType: {}, | ||
| flattenLocation: {}, | ||
| astOption: { | ||
| autofocus: true, | ||
| location: true, | ||
| empty: true, | ||
| type: true, | ||
| }, | ||
| }; | ||
|
|
||
| static getDerivedStateFromProps(nextProps: Props, prevState: State) { | ||
| if (nextProps.src && nextProps.src !== prevState.src) { | ||
| let flattenSrc = flatten(nextProps.src); | ||
| flattenSrc = reject(flattenSrc, "_"); | ||
| const src = unflatten(flattenSrc); | ||
|
|
||
| return { | ||
| src: src, | ||
| flattenSrc: flattenSrc, | ||
| flattenType: filterFlatten(flattenSrc, "type"), | ||
| flattenLocation: { | ||
| ...filterFlatten(flattenSrc, "start"), | ||
| ...filterFlatten(flattenSrc, "end"), | ||
| }, | ||
| flattenEmpty: filterFlatten(flattenSrc, null, "null"), | ||
| }; | ||
| } | ||
| } | ||
|
|
||
| _onOptionSettingCheck(option: string) { | ||
| this.setState(prevState => ({ | ||
| astOption: { | ||
| ...prevState.astOption, | ||
| [option]: !prevState.astOption[option], | ||
| }, | ||
| })); | ||
| this._onChangeJson(option); | ||
| } | ||
|
|
||
| _onChangeJson(option: string) { | ||
| const { | ||
| astOption, | ||
| flattenEmpty, | ||
| flattenSrc, | ||
| flattenType, | ||
| flattenLocation, | ||
| } = this.state; | ||
|
|
||
| function triggerAstOutput(type) { | ||
| const isShow = astOption[type]; | ||
| let newSrc = {}; | ||
| const types = { | ||
| empty: () => { | ||
| newSrc = isShow | ||
| ? deleteFlatten(flattenSrc, flattenEmpty) | ||
| : mergeFlatten(flattenSrc, flattenEmpty); | ||
| return newSrc; | ||
| }, | ||
| type: () => { | ||
| newSrc = isShow | ||
| ? deleteFlatten(flattenSrc, flattenType) | ||
| : mergeFlatten(flattenSrc, flattenType); | ||
| return newSrc; | ||
| }, | ||
| location: () => { | ||
| newSrc = isShow | ||
| ? deleteFlatten(flattenSrc, flattenLocation) | ||
| : mergeFlatten(flattenSrc, flattenLocation); | ||
| return newSrc; | ||
| }, | ||
| default: () => flattenSrc, | ||
| }; | ||
| return (types[type] || types["default"])(); | ||
| } | ||
|
|
||
| const result = triggerAstOutput(option); | ||
| this.setState({ flattenSrc: result, src: unflatten(result) }); | ||
| } | ||
|
|
||
| render() { | ||
| const { src, astOption } = this.state; | ||
| const { className = "" } = this.props; | ||
|
|
||
| return ( | ||
| <div className={`${styles.astWrapper} ${className}`}> | ||
| {src && ( | ||
| <div className={styles.optionWrapper}> | ||
| {OPTION_ORDER.map(option => ( | ||
| <label className={styles.settingsLabel}> | ||
| <input | ||
| checked={astOption[option]} | ||
| type="checkbox" | ||
| className={styles.inputCheckboxLeft} | ||
| onChange={() => this._onOptionSettingCheck(option)} | ||
| /> | ||
| {option} | ||
| </label> | ||
| ))} | ||
| </div> | ||
| )} | ||
| <ReactJson | ||
| src={src} | ||
| style={styles.reactJson} | ||
| sortKeys={true} | ||
| name={false} | ||
| enableClipboard={false} | ||
| displayObjectSize={true} | ||
| displayDataTypes={false} | ||
| /> | ||
| </div> | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| const styles = { | ||
| astWrapper: css({ | ||
| height: "100%", | ||
| }), | ||
| optionWrapper: css({ | ||
| display: "flex", | ||
| flexDirection: "row", | ||
| width: "100%", | ||
| justifyContent: "stretch", | ||
| color: colors.inverseForegroundLight, | ||
| backgroundColor: colors.inverseBackgroundLight, | ||
| }), | ||
| settingsLabel: css({ | ||
| alignItems: "center", | ||
| display: "flex", | ||
| flexDirection: "colum", | ||
| fontSize: "0.875rem", | ||
| fontWeight: "normal", | ||
| padding: "0.19rem 1rem", | ||
| transition: "background-color 250ms ease-in-out, color 250ms ease-in-out", | ||
| "&:hover": { | ||
| backgroundColor: colors.inverseBackgroundDark, | ||
| color: colors.inverseForeground, | ||
| }, | ||
| }), | ||
| inputCheckboxLeft: css({ | ||
| margin: "0 0.75rem 0 0 !important", // TODO (bvaughn) Override input[type="checkbox"] style in main.css | ||
| "&:disabled": { | ||
| opacity: 0.5, | ||
| }, | ||
| }), | ||
| reactJson: { | ||
| overflowY: "scroll", | ||
| overflow: "show", | ||
| width: "100%", | ||
| height: "100%", | ||
| }, | ||
| }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,164 @@ | ||
| // https://github.com/hughsk/flat/blob/master/index.js | ||
|
|
||
| function isBuffer(obj) { | ||
| return ( | ||
| obj != null && | ||
| obj.constructor != null && | ||
| typeof obj.constructor.isBuffer === "function" && | ||
| obj.constructor.isBuffer(obj) | ||
| ); | ||
| } | ||
|
|
||
| function flatten(target, opts) { | ||
| opts = opts || {}; | ||
|
|
||
| const delimiter = opts.delimiter || "."; | ||
| const maxDepth = opts.maxDepth; | ||
| const output = {}; | ||
|
|
||
| function step(object, prev, currentDepth) { | ||
| currentDepth = currentDepth || 1; | ||
| Object.keys(object).forEach(function(key) { | ||
| const value = object[key]; | ||
| const isarray = opts.safe && Array.isArray(value); | ||
| const type = Object.prototype.toString.call(value); | ||
| const isbuffer = isBuffer(value); | ||
| const isobject = type === "[object Object]" || type === "[object Array]"; | ||
| const newKey = prev ? prev + delimiter + key : key; | ||
| if ( | ||
| !isarray && | ||
| !isbuffer && | ||
| isobject && | ||
| Object.keys(value).length && | ||
| (!opts.maxDepth || currentDepth < maxDepth) | ||
| ) { | ||
| return step(value, newKey, currentDepth + 1); | ||
| } | ||
| output[newKey] = value; | ||
| }); | ||
| } | ||
| step(target); | ||
| return output; | ||
| } | ||
|
|
||
| function unflatten(target, opts) { | ||
| opts = opts || {}; | ||
| const delimiter = opts.delimiter || "."; | ||
| const overwrite = opts.overwrite || false; | ||
| const result = {}; | ||
| const isbuffer = isBuffer(target); | ||
| if ( | ||
| isbuffer || | ||
| Object.prototype.toString.call(target) !== "[object Object]" | ||
| ) { | ||
| return target; | ||
| } | ||
|
|
||
| // safely ensure that the key is | ||
| // an integer. | ||
| function getkey(key) { | ||
| const parsedKey = Number(key); | ||
| return isNaN(parsedKey) || key.indexOf(".") !== -1 || opts.object | ||
| ? key | ||
| : parsedKey; | ||
| } | ||
|
|
||
| const sortedKeys = Object.keys(target).sort(function(keyA, keyB) { | ||
| return keyA.length - keyB.length; | ||
| }); | ||
|
|
||
| sortedKeys.forEach(function(key) { | ||
| const split = key.split(delimiter); | ||
| let key1 = getkey(split.shift()); | ||
| let key2 = getkey(split[0]); | ||
| let recipient = result; | ||
|
|
||
| while (key2 !== undefined) { | ||
| const type = Object.prototype.toString.call(recipient[key1]); | ||
| const isobject = type === "[object Object]" || type === "[object Array]"; | ||
|
|
||
| // do not write over falsey, non-undefined values if overwrite is false | ||
| if (!overwrite && !isobject && typeof recipient[key1] !== "undefined") { | ||
| return; | ||
| } | ||
|
|
||
| if ((overwrite && !isobject) || (!overwrite && recipient[key1] == null)) { | ||
| recipient[key1] = typeof key2 === "number" && !opts.object ? [] : {}; | ||
| } | ||
|
|
||
| recipient = recipient[key1]; | ||
| if (split.length > 0) { | ||
| key1 = getkey(split.shift()); | ||
| key2 = getkey(split[0]); | ||
| } | ||
| } | ||
|
|
||
| // unflatten again for 'messy objects' | ||
| recipient[key1] = unflatten(target[key], opts); | ||
| }); | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| function filterFlatten(flattenSrc, type = "", value) { | ||
| const result = Object.keys(flattenSrc) | ||
| .filter(key => { | ||
| if (type) { | ||
| const keys = key.split("."); | ||
| return keys.includes(type); | ||
| } | ||
| if (value) { | ||
| const v = value === "null" || value === "undefined" ? null : value; | ||
| return flattenSrc[key] === v; | ||
| } | ||
| }) | ||
| .reduce((object, key) => { | ||
| object[key] = flattenSrc[key]; | ||
| return object; | ||
| }, {}); | ||
| return result; | ||
| } | ||
|
|
||
| function deleteFlatten(currentSrc, deletedSrc) { | ||
| const deletedKeys = Object.keys(deletedSrc); | ||
| const result = Object.keys(currentSrc).reduce((object, key) => { | ||
| !deletedKeys.includes(key) ? (object[key] = currentSrc[key]) : null; | ||
| return object; | ||
| }, {}); | ||
| return result; | ||
| } | ||
|
|
||
| function mergeFlatten(currentSrc, nextSrc) { | ||
| return { | ||
| ...currentSrc, | ||
| ...nextSrc, | ||
| }; | ||
| } | ||
|
|
||
| function reject(obj, char) { | ||
| return Object.keys(obj) | ||
| .filter(key => !key.includes(char)) | ||
| .reduce((o, key) => { | ||
| return { | ||
| ...o, | ||
| [key]: obj[key], | ||
| }; | ||
| }, {}); | ||
| } | ||
|
|
||
| // function reject(obj, keys) { | ||
| // const result = Object.keys(obj) | ||
| // .filter(k => !keys.includes(k)) | ||
| // .map(k => Object.assign({}, { [k]: obj[k] })) | ||
| // .reduce((res, o) => Object.assign(res, o), {}); | ||
| // return result; | ||
| // } | ||
|
|
||
| export { | ||
| flatten, | ||
| unflatten, | ||
| filterFlatten, | ||
| deleteFlatten, | ||
| mergeFlatten, | ||
| reject, | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the input is changed (
props.src) the options here are ignored. So I disabledlocationbut as soon as I change the input the locations are back. I have to enable and then disable thelocationsoption again to remove locations.