Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
baas-ide
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
guxukai
baas-ide
Commits
80b87ef2
Commit
80b87ef2
authored
Dec 14, 2020
by
aniket-engg
Committed by
Aniket
Dec 21, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
traceManager and traceStepManager updated
parent
d2161740
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
260 additions
and
249 deletions
+260
-249
traceManager.ts
libs/remix-debug/src/trace/traceManager.ts
+220
-212
traceStepManager.ts
libs/remix-debug/src/trace/traceStepManager.ts
+40
-37
No files found.
libs/remix-debug/src/trace/traceManager.ts
View file @
80b87ef2
...
...
@@ -7,269 +7,277 @@ const traceHelper = require('./traceHelper')
const
remixLib
=
require
(
'@remix-project/remix-lib'
)
const
util
=
remixLib
.
util
function
TraceManager
(
options
)
{
this
.
web3
=
options
.
web3
this
.
isLoading
=
false
this
.
trace
=
null
this
.
traceCache
=
new
TraceCache
()
this
.
traceAnalyser
=
new
TraceAnalyser
(
this
.
traceCache
)
this
.
traceStepManager
=
new
TraceStepManager
(
this
.
traceAnalyser
)
this
.
tx
}
// init section
TraceManager
.
prototype
.
resolveTrace
=
async
function
(
tx
)
{
this
.
tx
=
tx
this
.
init
()
if
(
!
this
.
web3
)
throw
new
Error
(
'web3 not loaded'
)
this
.
isLoading
=
true
try
{
const
result
=
await
this
.
getTrace
(
tx
.
hash
)
if
(
result
.
structLogs
.
length
>
0
)
{
this
.
trace
=
result
.
structLogs
export
class
TraceManager
{
web3
isLoading
:
boolean
trace
traceCache
traceAnalyser
traceStepManager
tx
constructor
(
options
)
{
this
.
web3
=
options
.
web3
this
.
isLoading
=
false
this
.
trace
=
null
this
.
traceCache
=
new
TraceCache
()
this
.
traceAnalyser
=
new
TraceAnalyser
(
this
.
traceCache
)
this
.
traceStepManager
=
new
TraceStepManager
(
this
.
traceAnalyser
)
}
this
.
traceAnalyser
.
analyse
(
result
.
structLogs
,
tx
)
// init section
async
resolveTrace
(
tx
)
{
this
.
tx
=
tx
this
.
init
()
if
(
!
this
.
web3
)
throw
new
Error
(
'web3 not loaded'
)
this
.
isLoading
=
true
try
{
const
result
=
await
this
.
getTrace
(
tx
.
hash
)
if
(
result
[
'structLogs'
].
length
>
0
)
{
this
.
trace
=
result
[
'structLogs'
]
this
.
traceAnalyser
.
analyse
(
result
[
'structLogs'
],
tx
)
this
.
isLoading
=
false
return
true
}
var
mes
=
tx
.
hash
+
' is not a contract invocation or contract creation.'
console
.
log
(
mes
)
this
.
isLoading
=
false
throw
new
Error
(
mes
)
}
catch
(
error
)
{
console
.
log
(
error
)
this
.
isLoading
=
false
return
true
throw
new
Error
(
error
)
}
var
mes
=
tx
.
hash
+
' is not a contract invocation or contract creation.'
console
.
log
(
mes
)
this
.
isLoading
=
false
throw
new
Error
(
mes
)
}
catch
(
error
)
{
console
.
log
(
error
)
this
.
isLoading
=
false
throw
new
Error
(
error
)
}
}
TraceManager
.
prototype
.
getTrace
=
function
(
txHash
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
const
options
=
{
disableStorage
:
true
,
disableMemory
:
false
,
disableStack
:
false
,
fullStorage
:
false
}
this
.
web3
.
debug
.
traceTransaction
(
txHash
,
options
,
function
(
error
,
result
)
{
if
(
error
)
return
reject
(
error
)
resolve
(
result
)
getTrace
(
txHash
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
const
options
=
{
disableStorage
:
true
,
disableMemory
:
false
,
disableStack
:
false
,
fullStorage
:
false
}
this
.
web3
.
debug
.
traceTransaction
(
txHash
,
options
,
function
(
error
,
result
)
{
if
(
error
)
return
reject
(
error
)
resolve
(
result
)
})
})
})
}
TraceManager
.
prototype
.
init
=
function
()
{
this
.
trace
=
null
this
.
traceCache
.
init
()
}
// API section
TraceManager
.
prototype
.
inRange
=
function
(
step
)
{
return
this
.
isLoaded
()
&&
step
>=
0
&&
step
<
this
.
trace
.
length
}
TraceManager
.
prototype
.
isLoaded
=
function
()
{
return
!
this
.
isLoading
&&
this
.
trace
!==
null
}
}
TraceManager
.
prototype
.
getLength
=
function
(
callback
)
{
if
(
!
this
.
trace
)
{
callback
(
'no trace available'
,
null
)
}
else
{
callback
(
null
,
this
.
trace
.
length
)
init
()
{
this
.
trace
=
null
this
.
traceCache
.
init
()
}
}
TraceManager
.
prototype
.
accumulateStorageChanges
=
function
(
index
,
address
,
storageOrigin
)
{
return
this
.
traceCache
.
accumulateStorageChanges
(
index
,
address
,
storageOrigin
)
}
// API section
inRange
(
step
)
{
return
this
.
isLoaded
()
&&
step
>=
0
&&
step
<
this
.
trace
.
length
}
TraceManager
.
prototype
.
getAddresses
=
function
()
{
return
this
.
traceCache
.
addresses
}
isLoaded
()
{
return
!
this
.
isLoading
&&
this
.
trace
!==
null
}
TraceManager
.
prototype
.
getCallDataAt
=
function
(
stepIndex
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
getLength
(
callback
)
{
if
(
!
this
.
trace
)
{
callback
(
'no trace available'
,
null
)
}
else
{
callback
(
null
,
this
.
trace
.
length
)
}
}
const
callDataChange
=
util
.
findLowerBoundValue
(
stepIndex
,
this
.
traceCache
.
callDataChanges
)
if
(
callDataChange
===
null
)
{
throw
new
Error
(
'no calldata found'
)
accumulateStorageChanges
(
index
,
address
,
storageOrigin
)
{
return
this
.
traceCache
.
accumulateStorageChanges
(
index
,
address
,
storageOrigin
)
}
return
[
this
.
traceCache
.
callsData
[
callDataChange
]]
}
TraceManager
.
prototype
.
buildCallPath
=
async
function
(
stepIndex
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
getAddresses
()
{
return
this
.
traceCache
.
addresses
}
const
callsPath
=
util
.
buildCallPath
(
stepIndex
,
this
.
traceCache
.
callsTree
.
call
)
if
(
callsPath
===
null
)
throw
new
Error
(
'no call path built'
)
return
callsPath
}
TraceManager
.
prototype
.
getCallStackAt
=
function
(
stepIndex
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
getCallDataAt
(
stepIndex
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
}
const
callDataChange
=
util
.
findLowerBoundValue
(
stepIndex
,
this
.
traceCache
.
callDataChanges
)
if
(
callDataChange
===
null
)
{
throw
new
Error
(
'no calldata found'
)
}
return
[
this
.
traceCache
.
callsData
[
callDataChange
]]
}
const
call
=
util
.
findCall
(
stepIndex
,
this
.
traceCache
.
callsTree
.
call
)
if
(
call
===
null
)
{
throw
new
Error
(
'no callstack found'
)
async
buildCallPath
(
stepIndex
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
}
const
callsPath
=
util
.
buildCallPath
(
stepIndex
,
this
.
traceCache
.
callsTree
.
call
)
if
(
callsPath
===
null
)
throw
new
Error
(
'no call path built'
)
return
callsPath
}
return
call
.
callStack
}
TraceManager
.
prototype
.
getStackAt
=
function
(
stepIndex
)
{
this
.
checkRequestedStep
(
stepIndex
)
if
(
this
.
trace
[
stepIndex
]
&&
this
.
trace
[
stepIndex
].
stack
)
{
// there's always a stack
let
stack
=
this
.
trace
[
stepIndex
].
stack
.
slice
(
0
)
stack
.
reverse
()
return
stack
}
else
{
throw
new
Error
(
'no stack found'
)
getCallStackAt
(
stepIndex
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
}
const
call
=
util
.
findCall
(
stepIndex
,
this
.
traceCache
.
callsTree
.
call
)
if
(
call
===
null
)
{
throw
new
Error
(
'no callstack found'
)
}
return
call
.
callStack
}
}
TraceManager
.
prototype
.
getLastCallChangeSince
=
function
(
stepIndex
)
{
try
{
getStackAt
(
stepIndex
)
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
if
(
this
.
trace
[
stepIndex
]
&&
this
.
trace
[
stepIndex
].
stack
)
{
// there's always a stack
let
stack
=
this
.
trace
[
stepIndex
].
stack
.
slice
(
0
)
stack
.
reverse
()
return
stack
}
else
{
throw
new
Error
(
'no stack found'
)
}
}
const
callChange
=
util
.
findCall
(
stepIndex
,
this
.
traceCache
.
callsTree
.
call
)
if
(
callChange
===
null
)
{
return
0
}
return
callChange
}
getLastCallChangeSince
(
stepIndex
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
}
TraceManager
.
prototype
.
getCurrentCalledAddressAt
=
function
(
stepIndex
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
const
resp
=
this
.
getLastCallChangeSince
(
stepIndex
)
if
(
!
resp
)
{
throw
new
Error
(
'unable to get current called address. '
+
stepIndex
+
' does not match with a CALL'
)
const
callChange
=
util
.
findCall
(
stepIndex
,
this
.
traceCache
.
callsTree
.
call
)
if
(
callChange
===
null
)
{
return
0
}
return
resp
.
address
}
catch
(
error
)
{
throw
new
Error
(
error
)
return
callChange
}
}
TraceManager
.
prototype
.
getContractCreationCode
=
function
(
token
)
{
if
(
!
this
.
traceCache
.
contractCreation
[
token
])
{
throw
new
Error
(
'no contract creation named '
+
token
)
getCurrentCalledAddressAt
(
stepIndex
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
const
resp
=
this
.
getLastCallChangeSince
(
stepIndex
)
if
(
!
resp
)
{
throw
new
Error
(
'unable to get current called address. '
+
stepIndex
+
' does not match with a CALL'
)
}
return
resp
.
address
}
catch
(
error
)
{
throw
new
Error
(
error
)
}
}
return
this
.
traceCache
.
contractCreation
[
token
]
}
TraceManager
.
prototype
.
getMemoryAt
=
function
(
stepIndex
)
{
this
.
checkRequestedStep
(
stepIndex
)
const
lastChanges
=
util
.
findLowerBoundValue
(
stepIndex
,
this
.
traceCache
.
memoryChanges
)
if
(
lastChanges
===
null
)
{
throw
new
Error
(
'no memory found'
)
getContractCreationCode
(
token
)
{
if
(
!
this
.
traceCache
.
contractCreation
[
token
])
{
throw
new
Error
(
'no contract creation named '
+
token
)
}
return
this
.
traceCache
.
contractCreation
[
token
]
}
return
this
.
trace
[
lastChanges
].
memory
}
TraceManager
.
prototype
.
getCurrentPC
=
function
(
stepIndex
)
{
try
{
getMemoryAt
(
stepIndex
)
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
const
lastChanges
=
util
.
findLowerBoundValue
(
stepIndex
,
this
.
traceCache
.
memoryChanges
)
if
(
lastChanges
===
null
)
{
throw
new
Error
(
'no memory found'
)
}
return
this
.
trace
[
lastChanges
].
memory
}
return
this
.
trace
[
stepIndex
].
pc
}
TraceManager
.
prototype
.
getReturnValue
=
function
(
stepIndex
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
getCurrentPC
(
stepIndex
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
}
return
this
.
trace
[
stepIndex
].
pc
}
if
(
!
this
.
traceCache
.
returnValues
[
stepIndex
])
{
throw
new
Error
(
'current step is not a return step'
)
getReturnValue
(
stepIndex
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
}
if
(
!
this
.
traceCache
.
returnValues
[
stepIndex
])
{
throw
new
Error
(
'current step is not a return step'
)
}
return
this
.
traceCache
.
returnValues
[
stepIndex
]
}
return
this
.
traceCache
.
returnValues
[
stepIndex
]
}
TraceManager
.
prototype
.
getCurrentStep
=
function
(
stepIndex
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
getCurrentStep
(
stepIndex
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
}
return
this
.
traceCache
.
steps
[
stepIndex
]
}
return
this
.
traceCache
.
steps
[
stepIndex
]
}
TraceManager
.
prototype
.
getMemExpand
=
function
(
stepIndex
)
{
return
(
this
.
getStepProperty
(
stepIndex
,
'memexpand'
)
||
''
)
}
getMemExpand
(
stepIndex
)
{
return
(
this
.
getStepProperty
(
stepIndex
,
'memexpand'
)
||
''
)
}
TraceManager
.
prototype
.
getStepCost
=
function
(
stepIndex
)
{
return
this
.
getStepProperty
(
stepIndex
,
'gasCost'
)
}
getStepCost
(
stepIndex
)
{
return
this
.
getStepProperty
(
stepIndex
,
'gasCost'
)
}
TraceManager
.
prototype
.
getRemainingGas
=
function
(
stepIndex
)
{
return
this
.
getStepProperty
(
stepIndex
,
'gas'
)
}
getRemainingGas
(
stepIndex
)
{
return
this
.
getStepProperty
(
stepIndex
,
'gas'
)
}
TraceManager
.
prototype
.
getStepProperty
=
function
(
stepIndex
,
property
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
getStepProperty
(
stepIndex
,
property
)
{
try
{
this
.
checkRequestedStep
(
stepIndex
)
}
catch
(
check
)
{
throw
new
Error
(
check
)
}
return
this
.
trace
[
stepIndex
][
property
]
}
return
this
.
trace
[
stepIndex
][
property
]
}
TraceManager
.
prototype
.
isCreationStep
=
function
(
stepIndex
)
{
return
traceHelper
.
isCreateInstruction
(
this
.
trace
[
stepIndex
])
}
isCreationStep
(
stepIndex
)
{
return
traceHelper
.
isCreateInstruction
(
this
.
trace
[
stepIndex
])
}
// step section
TraceManager
.
prototype
.
findStepOverBack
=
function
(
currentStep
)
{
return
this
.
traceStepManager
.
findStepOverBack
(
currentStep
)
}
// step section
findStepOverBack
(
currentStep
)
{
return
this
.
traceStepManager
.
findStepOverBack
(
currentStep
)
}
TraceManager
.
prototype
.
findStepOverForward
=
function
(
currentStep
)
{
return
this
.
traceStepManager
.
findStepOverForward
(
currentStep
)
}
findStepOverForward
(
currentStep
)
{
return
this
.
traceStepManager
.
findStepOverForward
(
currentStep
)
}
TraceManager
.
prototype
.
findNextCall
=
function
(
currentStep
)
{
return
this
.
traceStepManager
.
findNextCall
(
currentStep
)
}
findNextCall
(
currentStep
)
{
return
this
.
traceStepManager
.
findNextCall
(
currentStep
)
}
TraceManager
.
prototype
.
findStepOut
=
function
(
currentStep
)
{
return
this
.
traceStepManager
.
findStepOut
(
currentStep
)
}
findStepOut
(
currentStep
)
{
return
this
.
traceStepManager
.
findStepOut
(
currentStep
)
}
TraceManager
.
prototype
.
checkRequestedStep
=
function
(
stepIndex
)
{
if
(
!
this
.
trace
)
{
throw
new
Error
(
'trace not loaded'
)
}
else
if
(
stepIndex
>=
this
.
trace
.
length
)
{
throw
new
Error
(
'trace smaller than requested'
)
checkRequestedStep
(
stepIndex
)
{
if
(
!
this
.
trace
)
{
throw
new
Error
(
'trace not loaded'
)
}
else
if
(
stepIndex
>=
this
.
trace
.
length
)
{
throw
new
Error
(
'trace smaller than requested'
)
}
}
}
TraceManager
.
prototype
.
waterfall
=
function
(
calls
,
stepindex
,
cb
)
{
let
ret
=
[]
let
retError
=
null
for
(
var
call
in
calls
)
{
calls
[
call
].
apply
(
this
,
[
stepindex
,
function
(
error
,
result
)
{
retError
=
error
ret
.
push
({
error
:
error
,
value
:
result
})
}])
waterfall
(
calls
,
stepindex
,
cb
)
{
let
ret
=
[]
let
retError
=
null
for
(
var
call
in
calls
)
{
calls
[
call
].
apply
(
this
,
[
stepindex
,
function
(
error
,
result
)
{
retError
=
error
ret
.
push
({
error
:
error
,
value
:
result
})
}])
}
cb
(
retError
,
ret
)
}
cb
(
retError
,
ret
)
}
module
.
exports
=
TraceManager
libs/remix-debug/src/trace/traceStepManager.ts
View file @
80b87ef2
...
...
@@ -4,52 +4,55 @@ const traceHelper = require('./traceHelper')
const
remixLib
=
require
(
'@remix-project/remix-lib'
)
const
util
=
remixLib
.
util
function
TraceStepManager
(
_traceAnalyser
)
{
this
.
traceAnalyser
=
_traceAnalyser
}
export
class
TraceStepManager
{
TraceStepManager
.
prototype
.
isCallInstruction
=
function
(
index
)
{
const
state
=
this
.
traceAnalyser
.
trace
[
index
]
return
traceHelper
.
isCallInstruction
(
state
)
&&
!
traceHelper
.
isCallToPrecompiledContract
(
index
,
this
.
traceAnalyser
.
trace
)
}
traceAnalyser
TraceStepManager
.
prototype
.
isReturnInstruction
=
function
(
index
)
{
const
state
=
this
.
traceAnalyser
.
trace
[
index
]
return
traceHelper
.
isReturnInstruction
(
state
)
}
constructor
(
_traceAnalyser
)
{
this
.
traceAnalyser
=
_traceAnalyser
}
TraceStepManager
.
prototype
.
findStepOverBack
=
function
(
currentStep
)
{
if
(
this
.
isReturnInstruction
(
currentStep
))
{
const
call
=
util
.
findCall
(
currentStep
,
this
.
traceAnalyser
.
traceCache
.
callsTree
.
call
)
return
call
.
start
>
0
?
call
.
start
-
1
:
0
isCallInstruction
(
index
)
{
const
state
=
this
.
traceAnalyser
.
trace
[
index
]
return
traceHelper
.
isCallInstruction
(
state
)
&&
!
traceHelper
.
isCallToPrecompiledContract
(
index
,
this
.
traceAnalyser
.
trace
)
}
return
currentStep
>
0
?
currentStep
-
1
:
0
}
TraceStepManager
.
prototype
.
findStepOverForward
=
function
(
currentStep
)
{
if
(
this
.
isCallInstruction
(
currentStep
))
{
const
call
=
util
.
findCall
(
currentStep
+
1
,
this
.
traceAnalyser
.
traceCache
.
callsTree
.
call
)
return
call
.
return
+
1
<
this
.
traceAnalyser
.
trace
.
length
?
call
.
return
+
1
:
this
.
traceAnalyser
.
trace
.
length
-
1
isReturnInstruction
(
index
)
{
const
state
=
this
.
traceAnalyser
.
trace
[
index
]
return
traceHelper
.
isReturnInstruction
(
state
)
}
findStepOverBack
(
currentStep
)
{
if
(
this
.
isReturnInstruction
(
currentStep
))
{
const
call
=
util
.
findCall
(
currentStep
,
this
.
traceAnalyser
.
traceCache
.
callsTree
.
call
)
return
call
.
start
>
0
?
call
.
start
-
1
:
0
}
return
currentStep
>
0
?
currentStep
-
1
:
0
}
return
this
.
traceAnalyser
.
trace
.
length
>=
currentStep
+
1
?
currentStep
+
1
:
currentStep
}
TraceStepManager
.
prototype
.
findNextCall
=
function
(
currentStep
)
{
const
call
=
util
.
findCall
(
currentStep
,
this
.
traceAnalyser
.
traceCache
.
callsTree
.
call
)
const
subCalls
=
Object
.
keys
(
call
.
calls
)
if
(
subCalls
.
length
)
{
var
callStart
=
util
.
findLowerBound
(
currentStep
,
subCalls
)
+
1
if
(
subCalls
.
length
>
callStart
)
{
return
subCalls
[
callStart
]
-
1
findStepOverForward
(
currentStep
)
{
if
(
this
.
isCallInstruction
(
currentStep
))
{
const
call
=
util
.
findCall
(
currentStep
+
1
,
this
.
traceAnalyser
.
traceCache
.
callsTree
.
call
)
return
call
.
return
+
1
<
this
.
traceAnalyser
.
trace
.
length
?
call
.
return
+
1
:
this
.
traceAnalyser
.
trace
.
length
-
1
}
return
this
.
traceAnalyser
.
trace
.
length
>=
currentStep
+
1
?
currentStep
+
1
:
currentStep
}
findNextCall
(
currentStep
)
{
const
call
=
util
.
findCall
(
currentStep
,
this
.
traceAnalyser
.
traceCache
.
callsTree
.
call
)
const
subCalls
=
Object
.
keys
(
call
.
calls
)
if
(
subCalls
.
length
)
{
var
callStart
=
util
.
findLowerBound
(
currentStep
,
subCalls
)
+
1
if
(
subCalls
.
length
>
callStart
)
{
return
parseInt
(
subCalls
[
callStart
])
-
1
}
return
currentStep
}
return
currentStep
}
return
currentStep
}
TraceStepManager
.
prototype
.
findStepOut
=
function
(
currentStep
)
{
const
call
=
util
.
findCall
(
currentStep
,
this
.
traceAnalyser
.
traceCache
.
callsTree
.
call
)
return
call
.
return
findStepOut
(
currentStep
)
{
const
call
=
util
.
findCall
(
currentStep
,
this
.
traceAnalyser
.
traceCache
.
callsTree
.
call
)
return
call
.
return
}
}
module
.
exports
=
TraceStepManager
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment