lib - Add node highlighting and consume in log-identifier

This commit is contained in:
2020-01-29 13:42:38 +05:30
parent 3feecc6750
commit a32cd478ac
10 changed files with 153 additions and 60 deletions
+4 -2
View File
@@ -4,7 +4,8 @@ import {
ASTVisualizer,
initSourceFile,
updateSourceFile,
clearSourceFile
clearSourceFile,
clearHighlightedNodes
} from "ts-transformer-visualizer";
import * as ts from "typescript";
@@ -14,7 +15,7 @@ import { moduleMap, ModuleNames } from "./transforms";
export default function App({
moduleName,
timeDelayMs = 3000
timeDelayMs = 1000
}: {
moduleName: ModuleNames;
timeDelayMs?: number;
@@ -41,6 +42,7 @@ export default function App({
// 3. Clean timeout and reset visualizer
clearTimeout(timeoutID);
clearSourceFile();
clearHighlightedNodes();
};
});
@@ -1,4 +1,6 @@
import * as ts from "typescript";
import { highlightNode } from "ts-transformer-visualizer";
import { TransformModuleExport } from "../types";
const sourceCodeString = `\
@@ -15,6 +17,7 @@ const transformer: ts.TransformerFactory<ts.SourceFile> = context => {
return sourceFile => {
const visitor = (node: ts.Node): ts.Node => {
if (ts.isIdentifier(node)) {
highlightNode(node);
console.log(node.text);
}
return ts.visitEachChild(node, visitor, context);
@@ -23,3 +23,9 @@
}
.exitDone {
}
.node {
padding: 0 0.5em;
}
.highlightNode {
background-color: rgba(254, 246, 2, 0.5);
}
+22 -31
View File
@@ -1,20 +1,29 @@
import React from "react";
import { connect } from "react-redux";
import * as ts from "typescript";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import { AppState } from "../../store";
import { useTypedSelector } from "../../store";
import { forEachChild, syntaxKindNameMapping, ObjectHash } from "../../utils";
import styles from "./ASTOutline.css";
interface ASTOutlineProps {
node?: ts.Node;
sourceFile?: ts.SourceFile;
}
function ASTOutline(props: ASTOutlineProps) {
const { node, sourceFile } = props;
const { node: nodeFromProps } = props;
const {
node: nodeFromRedux,
sourceFile,
highlightedNodes
} = useTypedSelector(state => ({
node: state.sourceFiles.currentSourceFile,
sourceFile: state.sourceFiles.currentSourceFile,
highlightedNodes: state.highlightedNodes.nodes
}));
const node = nodeFromProps || nodeFromRedux;
if (node === undefined || sourceFile === undefined) {
return null;
}
@@ -22,7 +31,13 @@ function ASTOutline(props: ASTOutlineProps) {
const output = (
<>
<li>
{syntaxKindNameMapping[node.kind]}
<span
className={
`${styles.node} ${highlightedNodes.includes(node) ? styles.highlightNode : ""}`
}
>
{syntaxKindNameMapping[node.kind]}
</span>
<ul>
<TransitionGroup>
{forEachChild(node).map(childNode => (
@@ -31,7 +46,7 @@ function ASTOutline(props: ASTOutlineProps) {
timeout={1000}
classNames={styles}
>
<ASTOutlineConnected node={childNode} />
<ASTOutline node={childNode} />
</CSSTransition>
))}
</TransitionGroup>
@@ -51,28 +66,4 @@ function ASTOutline(props: ASTOutlineProps) {
}
}
type ASTOutlineStateProps = ASTOutlineProps;
const mapStateToProps = (state: AppState) => ({
node: state.sourceFiles.currentSourceFile,
sourceFile: state.sourceFiles.currentSourceFile
});
// currentSourceFile from ownProps should take preceedence
const mergeProps = (
stateProps: ASTOutlineStateProps,
_dispatchProps: never,
ownProps: ASTOutlineProps
) => {
return {
...stateProps,
...ownProps
};
};
export { ASTOutline as ASTOutlineUnconnected, ASTOutlineProps };
const ASTOutlineConnected = connect(
mapStateToProps,
null,
mergeProps
)(ASTOutline);
export default ASTOutlineConnected;
export default ASTOutline;
+1 -5
View File
@@ -1,7 +1,3 @@
import ASTOutline, {
ASTOutlineUnconnected,
ASTOutlineProps
} from "./ASTOutline";
import ASTOutline from "./ASTOutline";
export { ASTOutlineUnconnected, ASTOutlineProps };
export default ASTOutline;
+24 -8
View File
@@ -10,7 +10,9 @@ import configureStore from "./store";
import {
initSourceFile,
updateSourceFile,
clearSourceFile
clearSourceFile,
highlightNode,
clearHighlightedNodes
} from "./store/sourceFiles/actions";
import styles from "./styles.css";
@@ -27,19 +29,23 @@ export function ASTVisualizer() {
</Col>
</Row>
<Row>
<Col xs={12} md={6} className={styles.hideOverflow}>
<Col xs={12} className={styles.hideOverflow}>
<Row>
<h2 className={styles.titleLight}>AST Inline Diff</h2>
</Row>
<ASTOutline />
</Col>
<Col xs={12} md={6}>
<Col xs={12}>
<Row>
<h2 className={styles.titleLight}>Code output Diff</h2>
</Row>
<Row>
<Col xs={6} className={styles.titleLight}>Input</Col>
<Col xs={6} className={styles.titleLight}>Output</Col>
<Col xs={6} className={styles.titleLight}>
Input
</Col>
<Col xs={6} className={styles.titleLight}>
Output
</Col>
</Row>
<CodeOutputDiff />
</Col>
@@ -52,14 +58,24 @@ export function ASTVisualizer() {
const {
initSourceFile: initSourceFileConnected,
updateSourceFile: updateSourceFileConnected,
clearSourceFile: clearSourceFileConnected
clearSourceFile: clearSourceFileConnected,
highlightNode: highlightNodeConnected,
clearHighlightedNodes: clearHighlightedNodesConnected
} = bindActionCreators(
{ initSourceFile, updateSourceFile, clearSourceFile },
{
initSourceFile,
updateSourceFile,
clearSourceFile,
highlightNode,
clearHighlightedNodes
},
store.dispatch
);
export {
initSourceFileConnected as initSourceFile,
updateSourceFileConnected as updateSourceFile,
clearSourceFileConnected as clearSourceFile
clearSourceFileConnected as clearSourceFile,
highlightNodeConnected as highlightNode,
clearHighlightedNodesConnected as clearHighlightedNodes
};
+9 -2
View File
@@ -4,12 +4,17 @@ import {
applyMiddleware,
Middleware
} from "redux";
import { useSelector, TypedUseSelectorHook } from "react-redux";
import { composeWithDevTools } from "redux-devtools-extension";
import { sourceFilesReducer } from "./sourceFiles/reducer";
import {
sourceFilesReducer,
highlightedNodesReducer
} from "./sourceFiles/reducer";
const rootReducer = combineReducers({
sourceFiles: sourceFilesReducer
sourceFiles: sourceFilesReducer,
highlightedNodes: highlightedNodesReducer
});
export type AppState = ReturnType<typeof rootReducer>;
@@ -25,3 +30,5 @@ export default function configureStore() {
return store;
}
export const useTypedSelector: TypedUseSelectorHook<AppState> = useSelector;
+33 -5
View File
@@ -1,22 +1,50 @@
import * as ts from "typescript";
import { INIT_SOURCEFILE, UPDATE_SOURCEFILE, CLEAR_SOURCEFILE } from "./types";
import {
INIT_SOURCEFILE,
UPDATE_SOURCEFILE,
CLEAR_SOURCEFILE,
HIGHLIGHT_NODE,
CLEAR_HIGHLIGHTED_NODES,
InitSourceFileAction,
UpdateSourceFileAction,
ClearSourceFileAction,
HighlightNodeAction,
ClearHighlightedNodesAction
} from "./types";
export function initSourceFile(sourceFile: ts.SourceFile) {
export function initSourceFile(
sourceFile: ts.SourceFile
): InitSourceFileAction {
return {
type: INIT_SOURCEFILE,
payload: { sourceFile }
};
}
export function updateSourceFile(sourceFile: ts.SourceFile) {
export function updateSourceFile(
sourceFile: ts.SourceFile
): UpdateSourceFileAction {
return {
type: UPDATE_SOURCEFILE,
payload: { sourceFile }
};
}
export function clearSourceFile() {
export function clearSourceFile(): ClearSourceFileAction {
return {
type: CLEAR_SOURCEFILE,
type: CLEAR_SOURCEFILE
};
}
export function highlightNode(node: ts.Node): HighlightNodeAction {
return {
type: HIGHLIGHT_NODE,
payload: { node }
};
}
export function clearHighlightedNodes(): ClearHighlightedNodesAction {
return {
type: CLEAR_HIGHLIGHTED_NODES
};
}
+28 -4
View File
@@ -2,17 +2,24 @@ import {
INIT_SOURCEFILE,
UPDATE_SOURCEFILE,
CLEAR_SOURCEFILE,
HIGHLIGHT_NODE,
CLEAR_HIGHLIGHTED_NODES,
SourceFilesState,
SourceFilesActionTypes
HighlightedNodesState,
SourceFilesActionTypes,
HighlightNodeActionTypes
} from "./types";
const initialState: SourceFilesState = {
const initialSourceFileState: SourceFilesState = {
inititalSourceFile: undefined,
currentSourceFile: undefined
};
const initialHighlightedNodesState: HighlightedNodesState = {
nodes: []
};
export function sourceFilesReducer(
state = initialState,
state = initialSourceFileState,
action: SourceFilesActionTypes
): SourceFilesState {
switch (action.type) {
@@ -28,7 +35,24 @@ export function sourceFilesReducer(
currentSourceFile: action.payload.sourceFile
};
case CLEAR_SOURCEFILE:
return initialState;
return initialSourceFileState;
default:
return state;
}
}
export function highlightedNodesReducer(
state = initialHighlightedNodesState,
action: HighlightNodeActionTypes
): HighlightedNodesState {
switch (action.type) {
case HIGHLIGHT_NODE:
return {
...state,
nodes: [...state.nodes, action.payload.node]
};
case CLEAR_HIGHLIGHTED_NODES:
return initialHighlightedNodesState;
default:
return state;
}
+23 -3
View File
@@ -6,26 +6,46 @@ export interface SourceFilesState {
currentSourceFile?: ts.SourceFile;
}
// slice for highlighted nodes
export interface HighlightedNodesState {
nodes: ts.Node[];
}
// Describing the different ACTION NAMES available
export const INIT_SOURCEFILE = "INIT_SOURCEFILE";
export const UPDATE_SOURCEFILE = "UPDATE_SOURCEFILE";
export const CLEAR_SOURCEFILE = "CLEAR_SOURCEFILE";
export const HIGHLIGHT_NODE = "HIGHLIGHT_NODE";
export const CLEAR_HIGHLIGHTED_NODES = "CLEAR_HIGHLIGHTED_NODES";
interface InitSourceFileAction {
export interface InitSourceFileAction {
type: typeof INIT_SOURCEFILE;
payload: { sourceFile: ts.SourceFile };
}
interface UpdateSourceFileAction {
export interface UpdateSourceFileAction {
type: typeof UPDATE_SOURCEFILE;
payload: { sourceFile: ts.SourceFile };
}
interface ClearSourceFileAction {
export interface ClearSourceFileAction {
type: typeof CLEAR_SOURCEFILE;
}
export interface HighlightNodeAction {
type: typeof HIGHLIGHT_NODE;
payload: { node: ts.Node };
}
export interface ClearHighlightedNodesAction {
type: typeof CLEAR_HIGHLIGHTED_NODES;
}
export type SourceFilesActionTypes =
| InitSourceFileAction
| UpdateSourceFileAction
| ClearSourceFileAction;
export type HighlightNodeActionTypes =
| HighlightNodeAction
| ClearHighlightedNodesAction;