Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
0de69162
Commit
0de69162
authored
Jul 20, 2016
by
John McCutchan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add --hot mode for flutter run
parent
8893e328
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
486 additions
and
220 deletions
+486
-220
android_device.dart
packages/flutter_tools/lib/src/android/android_device.dart
+25
-0
daemon.dart
packages/flutter_tools/lib/src/commands/daemon.dart
+3
-6
run.dart
packages/flutter_tools/lib/src/commands/run.dart
+19
-11
devfs.dart
packages/flutter_tools/lib/src/devfs.dart
+237
-0
device.dart
packages/flutter_tools/lib/src/device.dart
+13
-0
simulators.dart
packages/flutter_tools/lib/src/ios/simulators.dart
+6
-28
observatory.dart
packages/flutter_tools/lib/src/observatory.dart
+7
-25
run.dart
packages/flutter_tools/lib/src/run.dart
+83
-150
devfs_test.dart
packages/flutter_tools/test/devfs_test.dart
+59
-0
mocks.dart
packages/flutter_tools/test/src/mocks.dart
+34
-0
No files found.
packages/flutter_tools/lib/src/android/android_device.dart
View file @
0de69162
...
...
@@ -388,6 +388,31 @@ class AndroidDevice extends Device {
);
}
@override
bool
get
supportsHotMode
=>
true
;
@override
Future
<
bool
>
runFromFile
(
ApplicationPackage
package
,
String
scriptUri
,
String
packagesUri
)
async
{
AndroidApk
apk
=
package
;
List
<
String
>
cmd
=
adbCommandForDevice
(<
String
>[
'shell'
,
'am'
,
'start'
,
'-a'
,
'android.intent.action.RUN'
,
'-d'
,
_deviceBundlePath
,
'-f'
,
'0x20000000'
,
// FLAG_ACTIVITY_SINGLE_TOP
]);
cmd
.
addAll
(<
String
>[
'--es'
,
'file'
,
scriptUri
]);
cmd
.
addAll
(<
String
>[
'--es'
,
'packages'
,
packagesUri
]);
cmd
.
add
(
apk
.
launchActivity
);
String
result
=
runCheckedSync
(
cmd
);
if
(
result
.
contains
(
'Error: '
))
{
printError
(
result
.
trim
());
return
false
;
}
return
true
;
}
@override
bool
get
supportsRestart
=>
true
;
...
...
packages/flutter_tools/lib/src/commands/daemon.dart
View file @
0de69162
...
...
@@ -17,7 +17,6 @@ import '../ios/devices.dart';
import
'../ios/simulators.dart'
;
import
'../run.dart'
;
import
'../runner/flutter_command.dart'
;
import
'run.dart'
as
run
;
const
String
protocolVersion
=
'0.2.0'
;
...
...
@@ -292,7 +291,7 @@ class AppDomain extends Domain {
String
route
=
_getStringArg
(
args
,
'route'
);
String
mode
=
_getStringArg
(
args
,
'mode'
);
String
target
=
_getStringArg
(
args
,
'target'
);
bool
reloadSources
=
_getBoolArg
(
args
,
'reload-sources
'
);
bool
hotMode
=
_getBoolArg
(
args
,
'hot
'
);
Device
device
=
daemon
.
deviceDomain
.
_getDevice
(
deviceId
);
if
(
device
==
null
)
...
...
@@ -301,9 +300,6 @@ class AppDomain extends Domain {
if
(!
FileSystemEntity
.
isDirectorySync
(
projectDirectory
))
throw
"'
$projectDirectory
' does not exist"
;
if
(
reloadSources
!=
null
)
run
.
useReloadSources
=
reloadSources
;
BuildMode
buildMode
=
getBuildModeForName
(
mode
)
??
BuildMode
.
debug
;
DebuggingOptions
options
;
...
...
@@ -327,7 +323,8 @@ class AppDomain extends Domain {
device
,
target:
target
,
debuggingOptions:
options
,
usesTerminalUI:
false
usesTerminalUI:
false
,
hotMode:
hotMode
);
AppInstance
app
=
new
AppInstance
(
_getNextAppId
(),
runner
);
...
...
packages/flutter_tools/lib/src/commands/run.dart
View file @
0de69162
...
...
@@ -19,9 +19,6 @@ import 'build_apk.dart';
import
'install.dart'
;
import
'trace.dart'
;
/// Whether the user has passed the `--reload-sources` command-line option.
bool
useReloadSources
=
false
;
abstract
class
RunCommandBase
extends
FlutterCommand
{
RunCommandBase
()
{
addBuildModeFlags
(
defaultToRelease:
false
);
...
...
@@ -58,16 +55,16 @@ class RunCommand extends RunCommandBase {
argParser
.
addOption
(
'debug-port'
,
help:
'Listen to the given port for a debug connection (defaults to
$kDefaultObservatoryPort
).'
);
usesPubOption
();
argParser
.
addFlag
(
'resident'
,
defaultsTo:
true
,
help:
'Don
\'
t terminate the
\'
flutter run
\'
process after starting the application.'
);
// Hidden option to ship all the sources of the current project over to the
// embedder via the DevFS observatory API.
argParser
.
addFlag
(
'devfs'
,
negatable:
false
,
hide:
true
);
// Send the _reloadSource command to the VM.
argParser
.
addFlag
(
'reload-sources'
,
negatable:
true
,
defaultsTo:
false
,
hide:
true
);
// Option to enable hot reloading.
argParser
.
addFlag
(
'hot'
,
negatable:
false
,
defaultsTo:
false
,
help:
'Run with support for hot reloading.'
);
// Hidden option to enable a benchmarking mode. This will run the given
// application, measure the startup time and the app restart time, write the
...
...
@@ -122,14 +119,25 @@ class RunCommand extends RunCommandBase {
Cache
.
releaseLockEarly
();
useReloadSources
=
argResults
[
'reload-sources'
];
// Do some early error checks for hot mode.
bool
hotMode
=
argResults
[
'hot'
];
if
(
hotMode
)
{
if
(
getBuildMode
()
!=
BuildMode
.
debug
)
{
printError
(
'Hot mode only works with debug builds.'
);
return
1
;
}
if
(!
deviceForCommand
.
supportsHotMode
)
{
printError
(
'Hot mode is not supported by this device.'
);
return
1
;
}
}
if
(
argResults
[
'resident'
])
{
RunAndStayResident
runner
=
new
RunAndStayResident
(
deviceForCommand
,
target:
target
,
debuggingOptions:
options
,
useDevFS:
argResults
[
'devfs
'
]
hotMode:
argResults
[
'hot
'
]
);
return
runner
.
run
(
...
...
packages/flutter_tools/lib/src/devfs.dart
0 → 100644
View file @
0de69162
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:convert'
show
BASE64
,
UTF8
;
import
'dart:io'
;
import
'package:path/path.dart'
as
path
;
import
'dart/package_map.dart'
;
import
'globals.dart'
;
import
'observatory.dart'
;
// A file that has been added to a DevFS.
class
DevFSEntry
{
DevFSEntry
(
this
.
devicePath
,
this
.
file
);
final
String
devicePath
;
final
File
file
;
FileStat
_fileStat
;
DateTime
get
lastModified
=>
_fileStat
?.
modified
;
bool
get
stillExists
{
_stat
();
return
_fileStat
.
type
!=
FileSystemEntityType
.
NOT_FOUND
;
}
bool
get
isModified
{
if
(
_fileStat
==
null
)
{
_stat
();
return
true
;
}
FileStat
_oldFileStat
=
_fileStat
;
_stat
();
return
_fileStat
.
modified
.
isAfter
(
_oldFileStat
.
modified
);
}
void
_stat
()
{
_fileStat
=
file
.
statSync
();
}
}
/// Abstract DevFS operations interface.
abstract
class
DevFSOperations
{
Future
<
Uri
>
create
(
String
fsName
);
Future
<
dynamic
>
destroy
(
String
fsName
);
Future
<
dynamic
>
writeFile
(
String
fsName
,
DevFSEntry
entry
);
Future
<
dynamic
>
writeSource
(
String
fsName
,
String
devicePath
,
String
contents
);
}
/// An implementation of [DevFSOperations] that speaks to the
/// service protocol.
class
ServiceProtocolDevFSOperations
implements
DevFSOperations
{
final
Observatory
serviceProtocol
;
ServiceProtocolDevFSOperations
(
this
.
serviceProtocol
);
@override
Future
<
Uri
>
create
(
String
fsName
)
async
{
Response
response
=
await
serviceProtocol
.
createDevFS
(
fsName
);
return
Uri
.
parse
(
response
[
'uri'
]);
}
@override
Future
<
dynamic
>
destroy
(
String
fsName
)
async
{
await
serviceProtocol
.
sendRequest
(
'_deleteDevFS'
,
<
String
,
dynamic
>
{
'fsName'
:
fsName
});
}
@override
Future
<
dynamic
>
writeFile
(
String
fsName
,
DevFSEntry
entry
)
async
{
List
<
int
>
bytes
;
try
{
bytes
=
await
entry
.
file
.
readAsBytes
();
}
catch
(
e
)
{
return
e
;
}
String
fileContents
=
BASE64
.
encode
(
bytes
);
return
await
serviceProtocol
.
sendRequest
(
'_writeDevFSFile'
,
<
String
,
dynamic
>
{
'fsName'
:
fsName
,
'path'
:
entry
.
devicePath
,
'fileContents'
:
fileContents
});
}
@override
Future
<
dynamic
>
writeSource
(
String
fsName
,
String
devicePath
,
String
contents
)
async
{
String
fileContents
=
BASE64
.
encode
(
UTF8
.
encode
(
contents
));
return
await
serviceProtocol
.
sendRequest
(
'_writeDevFSFile'
,
<
String
,
dynamic
>
{
'fsName'
:
fsName
,
'path'
:
devicePath
,
'fileContents'
:
fileContents
});
}
}
class
DevFS
{
/// Create a [DevFS] named [fsName] for the local files in [directory].
DevFS
(
Observatory
serviceProtocol
,
this
.
fsName
,
this
.
rootDirectory
)
:
_operations
=
new
ServiceProtocolDevFSOperations
(
serviceProtocol
);
DevFS
.
operations
(
this
.
_operations
,
this
.
fsName
,
this
.
rootDirectory
);
final
DevFSOperations
_operations
;
final
String
fsName
;
final
Directory
rootDirectory
;
final
Map
<
String
,
DevFSEntry
>
_entries
=
<
String
,
DevFSEntry
>{};
final
List
<
Future
<
Response
>>
_pendingWrites
=
new
List
<
Future
<
Response
>>();
Uri
_baseUri
;
Uri
get
baseUri
=>
_baseUri
;
Future
<
Uri
>
create
()
async
{
_baseUri
=
await
_operations
.
create
(
fsName
);
printTrace
(
'DevFS: Created new filesystem on the device (
$_baseUri
)'
);
return
_baseUri
;
}
Future
<
dynamic
>
destroy
()
async
{
printTrace
(
'DevFS: Deleted filesystem on the device (
$_baseUri
)'
);
return
await
_operations
.
destroy
(
fsName
);
}
Future
<
dynamic
>
update
()
async
{
printTrace
(
'DevFS: Starting sync from
$rootDirectory
'
);
// Send the root and lib directories.
Directory
directory
=
rootDirectory
;
_syncDirectory
(
directory
,
recursive:
true
);
String
packagesFilePath
=
path
.
join
(
rootDirectory
.
path
,
kPackagesFileName
);
StringBuffer
sb
;
// Send the packages.
if
(
FileSystemEntity
.
isFileSync
(
packagesFilePath
))
{
PackageMap
packageMap
=
new
PackageMap
(
kPackagesFileName
);
for
(
String
packageName
in
packageMap
.
map
.
keys
)
{
Uri
uri
=
packageMap
.
map
[
packageName
];
// Ignore self-references.
if
(
uri
.
toString
()
==
'lib/'
)
continue
;
Directory
directory
=
new
Directory
.
fromUri
(
uri
);
if
(
_syncDirectory
(
directory
,
directoryName:
'packages/
$packageName
'
,
recursive:
true
))
{
if
(
sb
==
null
)
{
sb
=
new
StringBuffer
();
}
sb
.
writeln
(
'
$packageName
:packages/
$packageName
'
);
}
}
}
printTrace
(
'DevFS: Waiting for sync of
${_pendingWrites.length}
files '
'to finish'
);
await
Future
.
wait
(
_pendingWrites
);
_pendingWrites
.
clear
();
if
(
sb
!=
null
)
{
await
_operations
.
writeSource
(
fsName
,
'.packages'
,
sb
.
toString
());
}
printTrace
(
'DevFS: Sync finished'
);
// NB: You must call flush after a printTrace if you want to be printed
// immediately.
logger
.
flush
();
}
void
_syncFile
(
String
devicePath
,
File
file
)
{
DevFSEntry
entry
=
_entries
[
devicePath
];
if
(
entry
==
null
)
{
// New file.
entry
=
new
DevFSEntry
(
devicePath
,
file
);
_entries
[
devicePath
]
=
entry
;
}
bool
needsWrite
=
entry
.
isModified
;
if
(
needsWrite
)
{
Future
<
dynamic
>
pendingWrite
=
_operations
.
writeFile
(
fsName
,
entry
);
if
(
pendingWrite
!=
null
)
{
_pendingWrites
.
add
(
pendingWrite
);
}
else
{
printTrace
(
'DevFS: Failed to sync "
$devicePath
"'
);
}
}
}
bool
_shouldIgnore
(
String
path
)
{
List
<
String
>
ignoredPrefixes
=
<
String
>[
'android/'
,
'build/'
,
'ios/'
,
'packages/analyzer'
];
for
(
String
ignoredPrefix
in
ignoredPrefixes
)
{
if
(
path
.
startsWith
(
ignoredPrefix
))
return
true
;
}
return
false
;
}
bool
_syncDirectory
(
Directory
directory
,
{
String
directoryName
,
bool
recursive:
false
,
bool
ignoreDotFiles:
true
})
{
String
prefix
=
directoryName
;
if
(
prefix
==
null
)
{
prefix
=
path
.
relative
(
directory
.
path
,
from:
rootDirectory
.
path
);
if
(
prefix
==
'.'
)
prefix
=
''
;
}
try
{
List
<
FileSystemEntity
>
files
=
directory
.
listSync
(
recursive:
recursive
,
followLinks:
false
);
for
(
FileSystemEntity
file
in
files
)
{
if
(
file
is
!
File
)
{
// Skip non-files.
continue
;
}
if
(
ignoreDotFiles
&&
path
.
basename
(
file
.
path
).
startsWith
(
'.'
))
{
// Skip dot files.
continue
;
}
final
String
devicePath
=
path
.
join
(
prefix
,
path
.
relative
(
file
.
path
,
from:
directory
.
path
));
if
(!
_shouldIgnore
(
devicePath
))
_syncFile
(
devicePath
,
file
);
}
}
catch
(
e
)
{
// Ignore directory and error.
return
false
;
}
return
true
;
}
}
packages/flutter_tools/lib/src/device.dart
View file @
0de69162
...
...
@@ -189,6 +189,19 @@ abstract class Device {
Map
<
String
,
dynamic
>
platformArgs
});
/// Does this device implement support for hot reloading / restarting?
bool
get
supportsHotMode
=>
false
;
/// Does this device need a DevFS to support hot mode?
bool
get
needsDevFS
=>
true
;
/// Run from a file. Necessary for hot mode.
Future
<
bool
>
runFromFile
(
ApplicationPackage
package
,
String
scriptUri
,
String
packagesUri
)
{
throw
'runFromFile unsupported'
;
}
bool
get
supportsRestart
=>
false
;
bool
get
restartSendsFrameworkInitEvent
=>
true
;
...
...
packages/flutter_tools/lib/src/ios/simulators.dart
View file @
0de69162
...
...
@@ -13,11 +13,9 @@ import '../application_package.dart';
import
'../base/context.dart'
;
import
'../base/process.dart'
;
import
'../build_info.dart'
;
import
'../commands/run.dart'
as
run
;
import
'../device.dart'
;
import
'../flx.dart'
as
flx
;
import
'../globals.dart'
;
import
'../observatory.dart'
;
import
'../protocol_discovery.dart'
;
import
'mac.dart'
;
...
...
@@ -361,6 +359,12 @@ class IOSSimulator extends Device {
@override
bool
get
isLocalEmulator
=>
true
;
@override
bool
get
supportsHotMode
=>
true
;
@override
bool
get
needsDevFS
=>
false
;
_IOSSimulatorLogReader
_logReader
;
_IOSSimulatorDevicePortForwarder
_portForwarder
;
...
...
@@ -575,32 +579,6 @@ class IOSSimulator extends Device {
return
(
await
flx
.
build
(
precompiledSnapshot:
true
))
==
0
;
}
@override
bool
get
supportsRestart
=>
run
.
useReloadSources
;
@override
bool
get
restartSendsFrameworkInitEvent
=>
false
;
@override
Future
<
bool
>
restartApp
(
ApplicationPackage
package
,
LaunchResult
result
,
{
String
mainPath
,
Observatory
observatory
})
async
{
if
(
observatory
.
firstIsolateId
==
null
)
throw
'Application isolate not found'
;
Event
result
=
await
observatory
.
reloadSources
(
observatory
.
firstIsolateId
);
dynamic
error
=
result
.
response
[
'reloadError'
];
if
(
error
!=
null
)
{
printError
(
'Error reloading application sources:
$error
'
);
return
false
;
}
else
{
await
observatory
.
flutterReassemble
(
observatory
.
firstIsolateId
);
return
true
;
}
}
@override
Future
<
bool
>
stopApp
(
ApplicationPackage
app
)
async
{
// Currently we don't have a way to stop an app running on iOS.
...
...
packages/flutter_tools/lib/src/observatory.dart
View file @
0de69162
...
...
@@ -9,6 +9,7 @@ import 'dart:io';
import
'package:json_rpc_2/json_rpc_2.dart'
as
rpc
;
import
'package:web_socket_channel/io.dart'
;
// TODO(johnmccutchan): Rename this class to ServiceProtocol or VmService.
class
Observatory
{
Observatory
.
_
(
this
.
peer
,
this
.
port
)
{
peer
.
registerMethod
(
'streamNotify'
,
(
rpc
.
Parameters
event
)
{
...
...
@@ -169,13 +170,13 @@ class Observatory {
});
}
// Write multiple files into a file system.
Future
<
Response
>
writeDevFSFiles
(
String
fsName
,
{
List
<
DevFSFile
>
files
})
{
assert
(
files
!=
null
);
return
sendRequest
(
'_writeDevFSFiles'
,
<
String
,
dynamic
>
{
// Read one file from a file system.
Future
<
List
<
int
>>
readDevFSFile
(
String
fsName
,
String
path
)
{
return
sendRequest
(
'_readDevFSFile'
,
<
String
,
dynamic
>
{
'fsName'
:
fsName
,
'files'
:
files
.
map
((
DevFSFile
file
)
=>
file
.
toJson
()).
toList
()
'path'
:
path
}).
then
((
Response
response
)
{
return
BASE64
.
decode
(
response
.
response
[
'fileContents'
]);
});
}
...
...
@@ -233,25 +234,6 @@ class Observatory {
}
}
abstract
class
DevFSFile
{
DevFSFile
(
this
.
path
);
final
String
path
;
List
<
int
>
getContents
();
List
<
String
>
toJson
()
=>
<
String
>[
path
,
BASE64
.
encode
(
getContents
())];
}
class
ByteDevFSFile
extends
DevFSFile
{
ByteDevFSFile
(
String
path
,
this
.
contents
):
super
(
path
);
final
List
<
int
>
contents
;
@override
List
<
int
>
getContents
()
=>
contents
;
}
class
Response
{
Response
(
this
.
response
);
...
...
packages/flutter_tools/lib/src/run.dart
View file @
0de69162
This diff is collapsed.
Click to expand it.
packages/flutter_tools/test/devfs_test.dart
0 → 100644
View file @
0de69162
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:io'
;
import
'package:flutter_tools/src/devfs.dart'
;
import
'package:path/path.dart'
as
path
;
import
'package:test/test.dart'
;
import
'src/context.dart'
;
import
'src/mocks.dart'
;
void
main
(
)
{
String
filePath
=
'bar/foo.txt'
;
String
filePath2
=
'foo/bar.txt'
;
Directory
tempDir
;
String
basePath
;
MockDevFSOperations
devFSOperations
=
new
MockDevFSOperations
();
DevFS
devFS
;
group
(
'devfs'
,
()
{
testUsingContext
(
'create local file system'
,
()
async
{
tempDir
=
Directory
.
systemTemp
.
createTempSync
();
basePath
=
tempDir
.
path
;
File
file
=
new
File
(
path
.
join
(
basePath
,
filePath
));
await
file
.
parent
.
create
(
recursive:
true
);
file
.
writeAsBytesSync
(<
int
>[
1
,
2
,
3
]);
});
testUsingContext
(
'create dev file system'
,
()
async
{
devFS
=
new
DevFS
.
operations
(
devFSOperations
,
'test'
,
tempDir
);
await
devFS
.
create
();
expect
(
devFSOperations
.
contains
(
'create test'
),
isTrue
);
});
testUsingContext
(
'populate dev file system'
,
()
async
{
await
devFS
.
update
();
expect
(
devFSOperations
.
contains
(
'writeFile test bar/foo.txt'
),
isTrue
);
});
testUsingContext
(
'modify existing file on local file system'
,
()
async
{
File
file
=
new
File
(
path
.
join
(
basePath
,
filePath
));
file
.
writeAsBytesSync
(<
int
>[
1
,
2
,
3
,
4
,
5
,
6
]);
});
testUsingContext
(
'update dev file system'
,
()
async
{
await
devFS
.
update
();
expect
(
devFSOperations
.
contains
(
'writeFile test bar/foo.txt'
),
isTrue
);
});
testUsingContext
(
'add new file to local file system'
,
()
async
{
File
file
=
new
File
(
path
.
join
(
basePath
,
filePath2
));
await
file
.
parent
.
create
(
recursive:
true
);
file
.
writeAsBytesSync
(<
int
>[
1
,
2
,
3
,
4
,
5
,
6
,
7
]);
});
testUsingContext
(
'update dev file system'
,
()
async
{
await
devFS
.
update
();
expect
(
devFSOperations
.
contains
(
'writeFile test foo/bar.txt'
),
isTrue
);
});
testUsingContext
(
'delete dev file system'
,
()
async
{
await
devFS
.
destroy
();
});
});
}
packages/flutter_tools/test/src/mocks.dart
View file @
0de69162
...
...
@@ -7,6 +7,7 @@ import 'dart:async';
import
'package:flutter_tools/src/android/android_device.dart'
;
import
'package:flutter_tools/src/application_package.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/devfs.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/ios/devices.dart'
;
import
'package:flutter_tools/src/ios/simulators.dart'
;
...
...
@@ -69,3 +70,36 @@ void applyMocksToCommand(FlutterCommand command) {
..
applicationPackages
=
new
MockApplicationPackageStore
()
..
commandValidator
=
()
=>
true
;
}
class
MockDevFSOperations
implements
DevFSOperations
{
final
List
<
String
>
messages
=
new
List
<
String
>();
bool
contains
(
String
match
)
{
bool
result
=
messages
.
contains
(
match
);
messages
.
clear
();
return
result
;
}
@override
Future
<
Uri
>
create
(
String
fsName
)
async
{
messages
.
add
(
'create
$fsName
'
);
return
Uri
.
parse
(
'file:///
$fsName
'
);
}
@override
Future
<
dynamic
>
destroy
(
String
fsName
)
async
{
messages
.
add
(
'destroy
$fsName
'
);
}
@override
Future
<
dynamic
>
writeFile
(
String
fsName
,
DevFSEntry
entry
)
async
{
messages
.
add
(
'writeFile
$fsName
${entry.devicePath}
'
);
}
@override
Future
<
dynamic
>
writeSource
(
String
fsName
,
String
devicePath
,
String
contents
)
async
{
messages
.
add
(
'writeSource
$fsName
$devicePath
'
);
}
}
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