[flutter_tool] Cache the path context in the flutter tool (#48250)
recomputing the path context in the getter violates flutter repo style guide and adds a small but measurable overhead to all path operations
This commit is contained in:
parent
53f98c98d9
commit
2221a9f514
@ -7,6 +7,7 @@ import 'dart:io' as io show Directory, File, Link;
|
|||||||
|
|
||||||
import 'package:file/file.dart';
|
import 'package:file/file.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:path/path.dart' as p; // ignore: package_path_import
|
||||||
|
|
||||||
import '../globals.dart' as globals;
|
import '../globals.dart' as globals;
|
||||||
import 'common.dart' show throwToolExit;
|
import 'common.dart' show throwToolExit;
|
||||||
@ -36,6 +37,21 @@ class ErrorHandlingFileSystem extends ForwardingFileSystem {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
File file(dynamic path) => ErrorHandlingFile(delegate, delegate.file(path));
|
File file(dynamic path) => ErrorHandlingFile(delegate, delegate.file(path));
|
||||||
|
|
||||||
|
// Caching the path context here and clearing when the currentDirectory setter
|
||||||
|
// is updated works since the flutter tool restricts usage of dart:io directly
|
||||||
|
// via the forbidden import tests. Otherwise, the path context's current
|
||||||
|
// working directory might get out of sync, leading to unexpected results from
|
||||||
|
// methods like `path.relative`.
|
||||||
|
@override
|
||||||
|
p.Context get path => _cachedPath ??= delegate.path;
|
||||||
|
p.Context _cachedPath;
|
||||||
|
|
||||||
|
@override
|
||||||
|
set currentDirectory(dynamic path) {
|
||||||
|
_cachedPath = null;
|
||||||
|
delegate.currentDirectory = path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ErrorHandlingFile
|
class ErrorHandlingFile
|
||||||
|
@ -6,6 +6,7 @@ import 'package:file/file.dart';
|
|||||||
import 'package:flutter_tools/src/base/error_handling_file_system.dart';
|
import 'package:flutter_tools/src/base/error_handling_file_system.dart';
|
||||||
import 'package:mockito/mockito.dart';
|
import 'package:mockito/mockito.dart';
|
||||||
import 'package:platform/platform.dart';
|
import 'package:platform/platform.dart';
|
||||||
|
import 'package:path/path.dart' as path; // ignore: package_path_import
|
||||||
|
|
||||||
import '../../src/common.dart';
|
import '../../src/common.dart';
|
||||||
import '../../src/context.dart';
|
import '../../src/context.dart';
|
||||||
@ -14,6 +15,7 @@ import '../../src/testbed.dart';
|
|||||||
class MockFile extends Mock implements File {}
|
class MockFile extends Mock implements File {}
|
||||||
class MockFileSystem extends Mock implements FileSystem {}
|
class MockFileSystem extends Mock implements FileSystem {}
|
||||||
class MockPlatform extends Mock implements Platform {}
|
class MockPlatform extends Mock implements Platform {}
|
||||||
|
class MockPathContext extends Mock implements path.Context {}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('throws ToolExit on Windows', () {
|
group('throws ToolExit on Windows', () {
|
||||||
@ -32,6 +34,7 @@ void main() {
|
|||||||
when(windowsPlatform.isWindows).thenReturn(true);
|
when(windowsPlatform.isWindows).thenReturn(true);
|
||||||
when(windowsPlatform.isLinux).thenReturn(false);
|
when(windowsPlatform.isLinux).thenReturn(false);
|
||||||
when(windowsPlatform.isMacOS).thenReturn(false);
|
when(windowsPlatform.isMacOS).thenReturn(false);
|
||||||
|
when(mockFileSystem.path).thenReturn(MockPathContext());
|
||||||
testbed = Testbed(overrides: <Type, Generator>{
|
testbed = Testbed(overrides: <Type, Generator>{
|
||||||
Platform: () => windowsPlatform,
|
Platform: () => windowsPlatform,
|
||||||
});
|
});
|
||||||
@ -96,4 +99,23 @@ void main() {
|
|||||||
expectedMessage: 'The file is being used by another program',
|
expectedMessage: 'The file is being used by another program',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Caches path context correctly', () {
|
||||||
|
final MockFileSystem mockFileSystem = MockFileSystem();
|
||||||
|
final FileSystem fs = ErrorHandlingFileSystem(mockFileSystem);
|
||||||
|
|
||||||
|
expect(identical(fs.path, fs.path), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Clears cache when CWD changes', () {
|
||||||
|
final MockFileSystem mockFileSystem = MockFileSystem();
|
||||||
|
final FileSystem fs = ErrorHandlingFileSystem(mockFileSystem);
|
||||||
|
|
||||||
|
final Object firstPath = fs.path;
|
||||||
|
|
||||||
|
fs.currentDirectory = null;
|
||||||
|
when(mockFileSystem.path).thenReturn(MockPathContext());
|
||||||
|
|
||||||
|
expect(identical(firstPath, fs.path), false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user