diff --git a/libs/remix-ui/debugger-ui/src/hooks/extract-data.tsx b/libs/remix-ui/debugger-ui/src/hooks/extract-data.tsx
index 06e653a801..3966329e4e 100644
--- a/libs/remix-ui/debugger-ui/src/hooks/extract-data.tsx
+++ b/libs/remix-ui/debugger-ui/src/hooks/extract-data.tsx
@@ -1,9 +1,32 @@
import React, { useState, useEffect } from 'react'
import { ExtractData, ExtractFunc } from '../types'
-export const useExtractData = (json, extractFunc?): Array<{ [key: string]: ExtractData }> => {
+export const useExtractData = (json, extractFunc?: ExtractFunc): Array<{ key: string, data: ExtractData }> => {
const [data, setData] = useState(null)
- const extractDataDefault = (item, parent?) => {
+
+ useEffect(() => {
+ const data: Array<{ key: string, data: ExtractData }> = Object.keys(json).map((innerKey) => {
+ if (extractFunc) {
+ return {
+ key: innerKey,
+ data : extractFunc(json[innerKey], json)
+ }
+ } else {
+ return {
+ key: innerKey,
+ data: extractDataDefault(json[innerKey], json)
+ }
+ }
+ })
+
+ setData(data)
+
+ return () => {
+ setData(null)
+ }
+ }, [json, extractFunc])
+
+ const extractDataDefault: ExtractFunc = (item, parent?) => {
const ret: ExtractData = {}
if (item instanceof Array) {
@@ -29,22 +52,6 @@ export const useExtractData = (json, extractFunc?): Array<{ [key: string]: Extra
return ret
}
- useEffect(() => {
- const data: Array<{ [key: string]: ExtractData }> = Object.keys(json).map((innerKey) => {
- if (extractFunc) {
- return { [innerKey]: extractFunc(json[innerKey], json) }
- } else {
- return { [innerKey]: extractDataDefault(json[innerKey], json) }
- }
- })
-
- setData(data)
-
- return () => {
- setData(null)
- }
- }, [json, extractFunc])
-
return data
}
diff --git a/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx b/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx
index 7340e4d2d4..bbd52fcabe 100644
--- a/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx
+++ b/libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx
@@ -1,4 +1,6 @@
import React from 'react'
+import StepManager from './step-manager/step-manager'
+import
const DebuggerUI = () => {
return (
diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/code-list-view.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/code-list-view.tsx
index c6b578431d..77cdc70b52 100644
--- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/code-list-view.tsx
+++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/code-list-view.tsx
@@ -1,16 +1,23 @@
-import React, { useState, useRef } from 'react'
+import React, { useState, useEffect } from 'react'
import DropdownPanel from './dropdown-panel'
-import EventManager from '../../../../../apps/remix-ide/src/lib/events'
+/* eslint-disable-next-line */
+import EventManager from '../../../../../../apps/remix-ide/src/lib/events'
-export const CodeListView = ({ vmDebuggerLogic }) => {
+export const CodeListView = ({ vmDebuggerLogic, asm }) => {
const event = new EventManager()
const [state, setState] = useState({
- code: '',
+ code: [],
address: '',
itemSelected: null,
index: null
})
+ useEffect(() => {
+ const { code, address, index } = asm
+
+ changed(code, address, index)
+ }, [asm])
+
const indexChanged = (index) => {
if(index < 0) return
setState(prevState => {
@@ -21,10 +28,6 @@ export const CodeListView = ({ vmDebuggerLogic }) => {
})
}
- const reset = () => {
- changed([], '', -1)
- }
-
const changed = (code, address, index) => {
if (state.address === address) {
return indexChanged(index)
@@ -36,7 +39,6 @@ export const CodeListView = ({ vmDebuggerLogic }) => {
address
}
})
- this.basicPanel.setContent(this.renderAssemblyItems())
indexChanged(index)
}
diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx
index 66af8a6a92..a5b090b2a1 100644
--- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx
+++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/dropdown-panel.tsx
@@ -3,15 +3,17 @@ import AssemblyItems from './assembly-items'
/* eslint-disable-next-line */
import { TreeView, TreeViewItem } from '../../../../tree-view/src/index'
import useExtractData from '../../hooks/extract-data'
-import { ExtractData, ExtractFunc, DropdownPanelProps } from '../../types'
+import { DropdownPanelProps, ExtractData } from '../../types'
import './styles/dropdown-panel.css'
-import EventManager from '../../../../../apps/remix-ide/src/lib/events'
-import copyToClipboard from '../../../../../apps/remix-ide/src/app/ui/copy-to-clipboard'
+/* eslint-disable-next-line */
+import EventManager from '../../../../../../apps/remix-ide/src/lib/events'
+/* eslint-disable-next-line */
+import copyToClipboard from '../../../../../../apps/remix-ide/src/app/ui/copy-to-clipboard'
export const DropdownPanel = (props: DropdownPanelProps) => {
- const { dropdownName, opts, codeView, index, calldata, header, extractFunc } = props
+ const { dropdownName, opts, codeView, index, calldata, header, extractFunc, formatSelfFunc } = props
const data = useExtractData(calldata, extractFunc)
const event = new EventManager()
const dropdownRawEl = useRef(null)
@@ -150,9 +152,46 @@ export const DropdownPanel = (props: DropdownPanelProps) => {
event.trigger('show', [])
}
- let content =
Empty
+ const formatSelfDefault = (key: string, data: ExtractData) => {
+ return (
+
+
+
+
+ )
+ }
+
+ const renderData = (item: ExtractData, key: string) => {
+ const children = (item.children || []).map((child) => {
+ const childKey = key + '/' + child.key
+
+ return (
+
+ { renderData(child.value, childKey) }
+
+ )
+ })
+
+ if (children && children.length > 0 ) {
+ return (
+
+ { children }
+
+ )
+ } else {
+ return
+ }
+ }
+
+ let content: JSX.Element | JSX.Element[] = Empty
if (state.json) {
- content = treeView.render({}, null)
+ content = data.map(item => {
+ return (
+
+ { renderData(item.data, item.key) }
+
+ )
+ })
}
const title = !state.displayContentOnly ?
diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/solidity-locals.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/solidity-locals.tsx
new file mode 100644
index 0000000000..e6f222da19
--- /dev/null
+++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/solidity-locals.tsx
@@ -0,0 +1,44 @@
+import React from 'react'
+import DropdownPanel from './dropdown-panel'
+import { extractData } from '../../utils/solidityTypeFormatter'
+import { ExtractData } from '../../types'
+
+export const SolidityLocals = () => {
+
+ const formatSelf = (key: string, data: ExtractData) => {
+ let color = 'var(--primary)'
+ if (data.isArray || data.isStruct || data.isMapping) {
+ color = 'var(--info)'
+ } else if (
+ data.type.indexOf('uint') === 0 ||
+ data.type.indexOf('int') === 0 ||
+ data.type.indexOf('bool') === 0 ||
+ data.type.indexOf('enum') === 0
+ ) {
+ color = 'var(--green)'
+ } else if (data.type === 'string') {
+ color = 'var(--teal)'
+ } else if (data.self == 0x0) { // eslint-disable-line
+ color = 'var(--gray)'
+ }
+ return (
+
+ )
+ }
+
+ return (
+
+
+
+ )
+}
+
+export default SolidityLocals
\ No newline at end of file
diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/solidity-state.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/solidity-state.tsx
index c67d061da3..9fdade9f4b 100644
--- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/solidity-state.tsx
+++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/solidity-state.tsx
@@ -1,11 +1,44 @@
import React from 'react'
import DropdownPanel from './dropdown-panel'
+import { extractData } from '../../utils/solidityTypeFormatter'
+import { ExtractData } from '../../types'
export const SolidityState = () => {
+ const formatSelf = (key: string, data: ExtractData) => {
+ let color = 'var(--primary)'
+ if (data.isArray || data.isStruct || data.isMapping) {
+ color = 'var(--info)'
+ } else if (
+ data.type.indexOf('uint') === 0 ||
+ data.type.indexOf('int') === 0 ||
+ data.type.indexOf('bool') === 0 ||
+ data.type.indexOf('enum') === 0
+ ) {
+ color = 'var(--green)'
+ } else if (data.type === 'string') {
+ color = 'var(--teal)'
+ } else if (data.self == 0x0) { // eslint-disable-line
+ color = 'var(--gray)'
+ }
+ return (
+
+ {' ' + key}:
+
+ {' ' + data.self}
+
+
+ {data.isProperty || !data.type ? '' : ' ' + data.type}
+
+
+ )
+ }
+
return (
-
+
+ {
+
+ }
+
)
}
diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/utils/solidity-type-formatter.ts b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/utils/solidity-type-formatter.ts
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/vm-debugger.tsx b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/vm-debugger.tsx
index 42da693ba8..4114afbb5d 100644
--- a/libs/remix-ui/debugger-ui/src/lib/vm-debugger/vm-debugger.tsx
+++ b/libs/remix-ui/debugger-ui/src/lib/vm-debugger/vm-debugger.tsx
@@ -1,15 +1,97 @@
-import React, { useState } from 'react'
+import React, { useState, useEffect } from 'react'
import CodeListView from './code-list-view'
+import CalldataPanel from './calldata-panel'
+import MemoryPanel from './memory-panel'
+import CallstackPanel from './callstack-panel'
+import FunctionPanel from './function-panel'
+import StackPanel from './stack-panel'
+import StoragePanel from './storage-panel'
+import StepDetail from './step-detail'
+import SolidityState from './solidity-state'
+import SolidityLocals from './solidity-locals'
+import FullStoragesChangesPanel from './full-storages-changes'
+import DropdownPanel from './dropdown-panel'
import './vm-debugger.css';
export const VmDebugger = ({ vmDebuggerLogic }) => {
const [state, setState] = useState({
-
})
+ const [asm, setAsm] = useState({
+ code: null,
+ address: null,
+ index: null
+ })
+ const [calldataPanel, setCalldataPanel] = useState(null)
+ const [memoryPanel, setMemoryPanel] = useState(null)
+ const [callStackPanel, setCallStackPanel] = useState(null)
+
+ useEffect(() => {
+ vmDebuggerLogic.event.register('codeManagerChanged', updateAsm)
+ vmDebuggerLogic.event.register('traceUnloaded', resetAsm)
+ vmDebuggerLogic.event.register('traceManagerCallDataUpdate', updateCalldataPanel)
+ vmDebuggerLogic.event.register('traceManagerMemoryUpdate', updateMemoryPanel)
+ vmDebuggerLogic.event.register('traceManagerCallStackUpdate', updateCallStackPanel)
+ }, [])
+
+ const updateAsm = (code, address, index) => {
+ setAsm({
+ code,
+ address,
+ index
+ })
+ }
+
+ const resetAsm = () => {
+ setAsm({
+ code: [],
+ address: '',
+ index: -1
+ })
+ }
+
+ const updateCalldataPanel = (calldata) => {
+ setCalldataPanel(calldata)
+ }
+
+ const updateMemoryPanel = (calldata) => {
+ setMemoryPanel(calldata)
+ }
+
+ const updateCallStackPanel = (calldata) => {
+ setCallStackPanel(calldata)
+ }
+
+ useEffect(() => {
+ vmDebuggerLogic.event.register('codeManagerChanged', )
+ }, [])
+
+ const renderHead = () => {
+ return (
+
+
+
+ {this.functionPanel.render()}
+ {this.solidityLocals.render()}
+ {this.solidityState.render()}
+
+
{this.asmCode.render()}
+
{this.stepDetail.render()}
+
+
+ )
+ }
return (
-
-
Welcome to vmDebugger!
+
+
+ {this.stackPanel.render()}
+ {this.memoryPanel.render()}
+ {this.storagePanel.render()}
+ {this.callstackPanel.render()}
+ {this.calldataPanel.render()}
+ {this.returnValuesPanel.render()}
+ {this.fullStoragesChangesPanel.render()}
+
);
};
diff --git a/libs/remix-ui/debugger-ui/src/types/index.ts b/libs/remix-ui/debugger-ui/src/types/index.ts
index 331c2af838..b8e02d3fb3 100644
--- a/libs/remix-ui/debugger-ui/src/types/index.ts
+++ b/libs/remix-ui/debugger-ui/src/types/index.ts
@@ -1,12 +1,13 @@
export interface ExtractData {
- children?: Array<{key: number | string, value: string}> | { key: number | string, value: string }
- self?: string,
+ children?: Array<{key: number | string, value: ExtractData}>
+ self?: string | number,
isNode?: boolean,
isLeaf?: boolean,
isArray?: boolean,
isStruct?: boolean,
isMapping?: boolean,
- type?: string
+ type?: string,
+ isProperty?: boolean
}
export type ExtractFunc = (json: any, parent?: any) => ExtractData
@@ -26,5 +27,8 @@ export interface DropdownPanelProps {
[key: string]: string
},
header?: string,
- extractFunc?: ExtractFunc
-}
\ No newline at end of file
+ extractFunc?: ExtractFunc,
+ formatSelfFunc?: FormatSelfFunc
+}
+
+export type FormatSelfFunc = (key: string, data: ExtractData) => JSX.Element
\ No newline at end of file
diff --git a/libs/remix-ui/debugger-ui/src/utils/solidityTypeFormatter.ts b/libs/remix-ui/debugger-ui/src/utils/solidityTypeFormatter.ts
new file mode 100644
index 0000000000..eb3637c2f4
--- /dev/null
+++ b/libs/remix-ui/debugger-ui/src/utils/solidityTypeFormatter.ts
@@ -0,0 +1,42 @@
+import { BN } from 'ethereumjs-util'
+import { ExtractData } from '../types'
+
+export function extractData (item, parent): ExtractData {
+ const ret: ExtractData = {}
+
+ if (item.isProperty) {
+ return item
+ }
+ if (item.type.lastIndexOf(']') === item.type.length - 1) {
+ ret.children = (item.value || []).map(function (item, index) {
+ return {key: index, value: item}
+ })
+ ret.children.unshift({
+ key: 'length',
+ value: {
+ self: (new BN(item.length.replace('0x', ''), 16)).toString(10),
+ type: 'uint',
+ isProperty: true
+ }
+ })
+ ret.isArray = true
+ ret.self = parent.isArray ? '' : item.type
+ } else if (item.type.indexOf('struct') === 0) {
+ ret.children = Object.keys((item.value || {})).map(function (key) {
+ return {key: key, value: item.value[key]}
+ })
+ ret.self = item.type
+ ret.isStruct = true
+ } else if (item.type.indexOf('mapping') === 0) {
+ ret.children = Object.keys((item.value || {})).map(function (key) {
+ return {key: key, value: item.value[key]}
+ })
+ ret.isMapping = true
+ ret.self = item.type
+ } else {
+ ret.children = null
+ ret.self = item.value
+ ret.type = item.type
+ }
+ return ret
+}
\ No newline at end of file
diff --git a/libs/remix-ui/tree-view/src/lib/tree-view-item/tree-view-item.tsx b/libs/remix-ui/tree-view/src/lib/tree-view-item/tree-view-item.tsx
index 796a8c6a04..a5b1de95da 100644
--- a/libs/remix-ui/tree-view/src/lib/tree-view-item/tree-view-item.tsx
+++ b/libs/remix-ui/tree-view/src/lib/tree-view-item/tree-view-item.tsx
@@ -1,8 +1,10 @@
import React, { useState } from 'react'
+import { TreeViewItemProps } from '../../types'
import './tree-view-item.css'
-export const TreeViewItem = ({ key, children, label, ...otherProps }) => {
+export const TreeViewItem = (props: TreeViewItemProps) => {
+ const { key, children, label, ...otherProps } = props
const [isExpanded, setIsExpanded] = useState(false)
return (
@@ -15,7 +17,7 @@ export const TreeViewItem = ({ key, children, label, ...otherProps }) => {
{ isExpanded ? children : null }
- );
-};
+ )
+}
-export default TreeViewItem;
+export default TreeViewItem
diff --git a/libs/remix-ui/tree-view/src/types/index.ts b/libs/remix-ui/tree-view/src/types/index.ts
index 800d92d40d..6e36ec108b 100644
--- a/libs/remix-ui/tree-view/src/types/index.ts
+++ b/libs/remix-ui/tree-view/src/types/index.ts
@@ -1,4 +1,10 @@
export interface TreeViewProps {
children?: React.ReactNode,
key: string
+}
+
+export interface TreeViewItemProps {
+ children?: React.ReactNode,
+ key: string,
+ label: string | number | React.ReactNode
}
\ No newline at end of file