mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 08:44:27 +00:00
Add a byte store that can be shared for use with Cider.
Change-Id: I492aebb476aa7e681eb4d7d5bff995d12917c9b4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150684 Commit-Queue: Keerti Parthasarathy <keertip@google.com> Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
24b33dae89
commit
e62b89c56d
4 changed files with 112 additions and 53 deletions
55
pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
Normal file
55
pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
Normal file
|
@ -0,0 +1,55 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
/**
|
||||
* Store of bytes associated with string keys and a hash.
|
||||
*
|
||||
* Each key must be not longer than 100 characters and consist of only `[a-z]`,
|
||||
* `[0-9]`, `.` and `_` characters. The key cannot be an empty string, the
|
||||
* literal `.`, or contain the sequence `..`.
|
||||
*
|
||||
* Note that associations are not guaranteed to be persistent. The value
|
||||
* associated with a key can change or become `null` at any point in time.
|
||||
*/
|
||||
abstract class CiderByteStore {
|
||||
/**
|
||||
* Return the bytes associated with the errors for given [key] and [signature].
|
||||
* Return `null` if the association does not exist.
|
||||
*/
|
||||
List<int> get(String key, List<int> signature);
|
||||
|
||||
/**
|
||||
* Associate the given [bytes] with the [key] and [digest].
|
||||
*/
|
||||
void put(String key, List<int> signature, List<int> bytes);
|
||||
}
|
||||
|
||||
class CiderMemoryByteStore implements CiderByteStore {
|
||||
final Map<String, _CiderCacheEntry> _map = {};
|
||||
|
||||
@override
|
||||
List<int> get(String key, List<int> signature) {
|
||||
var entry = _map[key];
|
||||
|
||||
if (entry != null &&
|
||||
const ListEquality().equals(entry.signature, signature)) {
|
||||
return entry.bytes;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
void put(String key, List<int> signature, List<int> bytes) {
|
||||
_map[key] = _CiderCacheEntry(signature, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
class _CiderCacheEntry {
|
||||
final List<int> signature;
|
||||
final List<int> bytes;
|
||||
|
||||
_CiderCacheEntry(this.signature, this.bytes);
|
||||
}
|
|
@ -11,10 +11,10 @@ import 'package:analyzer/dart/ast/ast.dart';
|
|||
import 'package:analyzer/dart/ast/token.dart';
|
||||
import 'package:analyzer/error/listener.dart';
|
||||
import 'package:analyzer/file_system/file_system.dart';
|
||||
import 'package:analyzer/src/dart/analysis/byte_store.dart';
|
||||
import 'package:analyzer/src/dart/analysis/feature_set_provider.dart';
|
||||
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
|
||||
import 'package:analyzer/src/dart/analysis/unlinked_api_signature.dart';
|
||||
import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
|
||||
import 'package:analyzer/src/dart/scanner/reader.dart';
|
||||
import 'package:analyzer/src/dart/scanner/scanner.dart';
|
||||
import 'package:analyzer/src/generated/engine.dart';
|
||||
|
@ -27,7 +27,6 @@ import 'package:analyzer/src/summary/idl.dart';
|
|||
import 'package:analyzer/src/summary/link.dart' as graph
|
||||
show DependencyWalker, Node;
|
||||
import 'package:analyzer/src/summary2/informative_data.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:convert/convert.dart';
|
||||
|
||||
/// Ensure that the [FileState.libraryCycle] for the [file] and anything it
|
||||
|
@ -168,16 +167,7 @@ class FileState {
|
|||
// Prepare bytes of the unlinked bundle - existing or new.
|
||||
List<int> bytes;
|
||||
{
|
||||
bytes = _fsState._byteStore.get(unlinkedKey);
|
||||
// unlinked summary should be updated if contents have changed, can be
|
||||
// seen if file digest has changed.
|
||||
if (bytes != null) {
|
||||
var ciderUnlinkedUnit = CiderUnlinkedUnit.fromBuffer(bytes);
|
||||
if (!const ListEquality()
|
||||
.equals(ciderUnlinkedUnit.contentDigest, _digest)) {
|
||||
bytes = null;
|
||||
}
|
||||
}
|
||||
bytes = _fsState._byteStore.get(unlinkedKey, _digest);
|
||||
|
||||
if (bytes == null || bytes.isEmpty) {
|
||||
var content = _fsState.timers.read.run(() {
|
||||
|
@ -189,7 +179,7 @@ class FileState {
|
|||
_fsState.timers.unlinked.run(() {
|
||||
var unlinkedBuilder = serializeAstCiderUnlinked(_digest, unit);
|
||||
bytes = unlinkedBuilder.toBuffer();
|
||||
_fsState._byteStore.put(unlinkedKey, bytes);
|
||||
_fsState._byteStore.put(unlinkedKey, _digest, bytes);
|
||||
});
|
||||
|
||||
_fsState.timers.prefetch.run(() {
|
||||
|
@ -377,7 +367,7 @@ class FileState {
|
|||
class FileSystemState {
|
||||
final PerformanceLog _logger;
|
||||
final ResourceProvider _resourceProvider;
|
||||
final MemoryByteStore _byteStore;
|
||||
final CiderByteStore _byteStore;
|
||||
final SourceFactory _sourceFactory;
|
||||
final AnalysisOptions _analysisOptions;
|
||||
final Uint32List _linkedSalt;
|
||||
|
|
|
@ -19,6 +19,7 @@ import 'package:analyzer/src/dart/analysis/feature_set_provider.dart';
|
|||
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
|
||||
import 'package:analyzer/src/dart/analysis/results.dart';
|
||||
import 'package:analyzer/src/dart/micro/analysis_context.dart';
|
||||
import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
|
||||
import 'package:analyzer/src/dart/micro/library_analyzer.dart';
|
||||
import 'package:analyzer/src/dart/micro/library_graph.dart';
|
||||
import 'package:analyzer/src/generated/engine.dart'
|
||||
|
@ -33,7 +34,6 @@ import 'package:analyzer/src/summary2/linked_element_factory.dart';
|
|||
import 'package:analyzer/src/summary2/reference.dart';
|
||||
import 'package:analyzer/src/task/options.dart';
|
||||
import 'package:analyzer/src/workspace/workspace.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:yaml/yaml.dart';
|
||||
|
||||
|
@ -47,7 +47,7 @@ class FileContext {
|
|||
class FileResolver {
|
||||
final PerformanceLog logger;
|
||||
final ResourceProvider resourceProvider;
|
||||
final MemoryByteStore byteStore;
|
||||
CiderByteStore byteStore;
|
||||
final SourceFactory sourceFactory;
|
||||
|
||||
/*
|
||||
|
@ -76,22 +76,48 @@ class FileResolver {
|
|||
|
||||
_LibraryContext libraryContext;
|
||||
|
||||
FileResolver(
|
||||
this.logger,
|
||||
this.resourceProvider,
|
||||
this.byteStore,
|
||||
this.sourceFactory,
|
||||
this.getFileDigest,
|
||||
this.prefetchFiles, {
|
||||
FileResolver.from({
|
||||
@required PerformanceLog logger,
|
||||
@required ResourceProvider resourceProvider,
|
||||
@required SourceFactory sourceFactory,
|
||||
@required String Function(String path) getFileDigest,
|
||||
@required void Function(List<String> paths) prefetchFiles,
|
||||
@required Workspace workspace,
|
||||
CiderByteStore byteStore,
|
||||
Duration libraryContextResetTimeout = const Duration(seconds: 60),
|
||||
}) : this.workspace = workspace {
|
||||
}) : this.logger = logger,
|
||||
this.sourceFactory = sourceFactory,
|
||||
this.resourceProvider = resourceProvider,
|
||||
this.getFileDigest = getFileDigest,
|
||||
this.prefetchFiles = prefetchFiles,
|
||||
this.workspace = workspace {
|
||||
byteStore ??= CiderMemoryByteStore();
|
||||
this.byteStore = byteStore;
|
||||
_libraryContextReset = _LibraryContextReset(
|
||||
fileResolver: this,
|
||||
resetTimeout: libraryContextResetTimeout,
|
||||
);
|
||||
}
|
||||
|
||||
FileResolver(
|
||||
PerformanceLog logger,
|
||||
ResourceProvider resourceProvider,
|
||||
@deprecated ByteStore byteStore,
|
||||
SourceFactory sourceFactory,
|
||||
String Function(String path) getFileDigest,
|
||||
void Function(List<String> paths) prefetchFiles, {
|
||||
@required Workspace workspace,
|
||||
Duration libraryContextResetTimeout = const Duration(seconds: 60),
|
||||
}) : this.from(
|
||||
logger: logger,
|
||||
resourceProvider: resourceProvider,
|
||||
sourceFactory: sourceFactory,
|
||||
getFileDigest: getFileDigest,
|
||||
prefetchFiles: prefetchFiles,
|
||||
workspace: workspace,
|
||||
libraryContextResetTimeout: libraryContextResetTimeout,
|
||||
);
|
||||
|
||||
FeatureSet get defaultFeatureSet => FeatureSet.fromEnableFlags([]);
|
||||
|
||||
/// Update the resolver to reflect the fact that the file with the given
|
||||
|
@ -134,16 +160,13 @@ class FileResolver {
|
|||
var errorsSignature = errorsSignatureBuilder.toByteList();
|
||||
|
||||
var errorsKey = file.path + '.errors';
|
||||
var bytes = byteStore.get(errorsKey);
|
||||
|
||||
var bytes = byteStore.get(errorsKey, errorsSignature);
|
||||
List<AnalysisError> errors;
|
||||
if (bytes != null) {
|
||||
var data = CiderUnitErrors.fromBuffer(bytes);
|
||||
if (const ListEquality().equals(data.signature, errorsSignature)) {
|
||||
errors = data.errors.map((error) {
|
||||
return ErrorEncoding.decode(file.source, error);
|
||||
}).toList();
|
||||
}
|
||||
errors = data.errors.map((error) {
|
||||
return ErrorEncoding.decode(file.source, error);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
if (errors == null) {
|
||||
|
@ -154,7 +177,7 @@ class FileResolver {
|
|||
signature: errorsSignature,
|
||||
errors: errors.map((ErrorEncoding.encode)).toList(),
|
||||
).toBuffer();
|
||||
byteStore.put(errorsKey, bytes);
|
||||
byteStore.put(errorsKey, errorsSignature, bytes);
|
||||
}
|
||||
|
||||
return ErrorsResultImpl(
|
||||
|
@ -412,7 +435,7 @@ class FileResolverTestView {
|
|||
class _LibraryContext {
|
||||
final PerformanceLog logger;
|
||||
final ResourceProvider resourceProvider;
|
||||
final MemoryByteStore byteStore;
|
||||
final CiderByteStore byteStore;
|
||||
final MicroContextObjects contextObjects;
|
||||
|
||||
LinkedElementFactory elementFactory;
|
||||
|
@ -451,15 +474,7 @@ class _LibraryContext {
|
|||
cycle.directDependencies.forEach(loadBundle);
|
||||
|
||||
var key = cycle.cyclePathsHash;
|
||||
var bytes = byteStore.get(key);
|
||||
|
||||
// check to see if any of the sources have changed
|
||||
if (bytes != null) {
|
||||
var hash = CiderLinkedLibraryCycle.fromBuffer(bytes).signature;
|
||||
if (!const ListEquality().equals(hash, cycle.signature)) {
|
||||
bytes = null;
|
||||
}
|
||||
}
|
||||
var bytes = byteStore.get(key, cycle.signature);
|
||||
|
||||
if (bytes == null) {
|
||||
librariesLinkedTimer.start();
|
||||
|
@ -510,7 +525,7 @@ class _LibraryContext {
|
|||
|
||||
bytes = serializeBundle(cycle.signature, linkResult).toBuffer();
|
||||
|
||||
byteStore.put(key, bytes);
|
||||
byteStore.put(key, cycle.signature, bytes);
|
||||
bytesPut += bytes.length;
|
||||
|
||||
librariesLinkedTimer.stop();
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:analyzer/dart/analysis/results.dart';
|
||||
import 'package:analyzer/src/dart/analysis/byte_store.dart';
|
||||
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
|
||||
import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
|
||||
import 'package:analyzer/src/dart/micro/resolve_file.dart';
|
||||
import 'package:analyzer/src/test_utilities/find_element.dart';
|
||||
import 'package:analyzer/src/test_utilities/find_node.dart';
|
||||
|
@ -22,7 +22,7 @@ import '../resolution/resolution.dart';
|
|||
class FileResolutionTest with ResourceProviderMixin, ResolutionTest {
|
||||
static final String _testFile = '/workspace/dart/test/lib/test.dart';
|
||||
|
||||
final ByteStore byteStore = MemoryByteStore();
|
||||
final CiderByteStore byteStore = CiderMemoryByteStore();
|
||||
|
||||
final StringBuffer logBuffer = StringBuffer();
|
||||
PerformanceLog logger;
|
||||
|
@ -44,15 +44,14 @@ class FileResolutionTest with ResourceProviderMixin, ResolutionTest {
|
|||
convertPath(_testFile),
|
||||
);
|
||||
|
||||
fileResolver = FileResolver(
|
||||
logger,
|
||||
resourceProvider,
|
||||
byteStore,
|
||||
workspace.createSourceFactory(sdk, null),
|
||||
(String path) => _getDigest(path),
|
||||
null,
|
||||
fileResolver = FileResolver.from(
|
||||
logger: logger,
|
||||
resourceProvider: resourceProvider,
|
||||
byteStore: byteStore,
|
||||
sourceFactory: workspace.createSourceFactory(sdk, null),
|
||||
getFileDigest: (String path) => _getDigest(path),
|
||||
workspace: workspace,
|
||||
libraryContextResetTimeout: null,
|
||||
prefetchFiles: null,
|
||||
);
|
||||
fileResolver.testView = FileResolverTestView();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue