mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:29:48 +00:00
Support overlays in completion_metrics_client.dart
Change-Id: Idedb38193ed80be0fa10e8e6be3fa04f8f30b100 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/243649 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
parent
78f218eb4c
commit
84ca405b35
|
@ -155,11 +155,11 @@ ArgParser createArgParser() {
|
||||||
)
|
)
|
||||||
..addOption(CompletionMetricsOptions.OVERLAY,
|
..addOption(CompletionMetricsOptions.OVERLAY,
|
||||||
allowed: [
|
allowed: [
|
||||||
CompletionMetricsOptions.OVERLAY_NONE,
|
OverlayMode.none.flag,
|
||||||
CompletionMetricsOptions.OVERLAY_REMOVE_TOKEN,
|
OverlayMode.removeRestOfFile.flag,
|
||||||
CompletionMetricsOptions.OVERLAY_REMOVE_REST_OF_FILE
|
OverlayMode.removeToken.flag,
|
||||||
],
|
],
|
||||||
defaultsTo: CompletionMetricsOptions.OVERLAY_NONE,
|
defaultsTo: OverlayMode.none.flag,
|
||||||
help:
|
help:
|
||||||
'Before attempting a completion at the location of each token, the '
|
'Before attempting a completion at the location of each token, the '
|
||||||
'token can be removed, or the rest of the file can be removed to '
|
'token can be removed, or the rest of the file can be removed to '
|
||||||
|
@ -745,17 +745,20 @@ class CompletionQualityMetricsComputer extends CompletionMetricsComputer {
|
||||||
ExpectedCompletion expectedCompletion,
|
ExpectedCompletion expectedCompletion,
|
||||||
) async {
|
) async {
|
||||||
// If an overlay option is being used, compute the overlay file, and
|
// If an overlay option is being used, compute the overlay file, and
|
||||||
// have the context reanalyze the file
|
// have the context reanalyze the file.
|
||||||
if (options.overlay != CompletionMetricsOptions.OVERLAY_NONE) {
|
if (options.overlay != OverlayMode.none) {
|
||||||
var overlayContents = CompletionMetricsComputer.getOverlayContents(
|
final overlayContents = CompletionMetricsComputer.getOverlayContent(
|
||||||
resolvedUnitResult.content,
|
resolvedUnitResult.content,
|
||||||
expectedCompletion,
|
expectedCompletion,
|
||||||
options.overlay,
|
options.overlay,
|
||||||
options.prefixLength);
|
options.prefixLength,
|
||||||
|
);
|
||||||
|
|
||||||
provider.setOverlay(filePath,
|
provider.setOverlay(
|
||||||
content: overlayContents,
|
filePath,
|
||||||
modificationStamp: overlayModificationStamp++);
|
content: overlayContents,
|
||||||
|
modificationStamp: overlayModificationStamp++,
|
||||||
|
);
|
||||||
context.changeFile(filePath);
|
context.changeFile(filePath);
|
||||||
await context.applyPendingFileChanges();
|
await context.applyPendingFileChanges();
|
||||||
resolvedUnitResult = await context.currentSession
|
resolvedUnitResult = await context.currentSession
|
||||||
|
@ -1396,10 +1399,10 @@ class CompletionQualityMetricsComputer extends CompletionMetricsComputer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void removeOverlay(String filePath) {
|
Future<void> removeOverlay(String filePath) async {
|
||||||
// If an overlay option is being used, remove the overlay applied
|
// If an overlay option is being used, remove the overlay applied
|
||||||
// earlier.
|
// earlier.
|
||||||
if (options.overlay != CompletionMetricsOptions.OVERLAY_NONE) {
|
if (options.overlay != OverlayMode.none) {
|
||||||
provider.removeOverlay(filePath);
|
provider.removeOverlay(filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ abstract class CompletionMetricsComputer {
|
||||||
documentationCache,
|
documentationCache,
|
||||||
);
|
);
|
||||||
|
|
||||||
removeOverlay(filePath);
|
await removeOverlay(filePath);
|
||||||
}
|
}
|
||||||
progress.tick();
|
progress.tick();
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ abstract class CompletionMetricsComputer {
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Removes the overlay which has been applied to [filePath].
|
/// Removes the overlay which has been applied to [filePath].
|
||||||
void removeOverlay(String filePath);
|
Future<void> removeOverlay(String filePath);
|
||||||
|
|
||||||
/// Resolves all analyzed files within [context].
|
/// Resolves all analyzed files within [context].
|
||||||
Future<List<ResolvedUnitResult>> resolveAnalyzedFiles({
|
Future<List<ResolvedUnitResult>> resolveAnalyzedFiles({
|
||||||
|
@ -171,17 +171,16 @@ abstract class CompletionMetricsComputer {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets overlay contents for [contents], applying a change at
|
/// Gets overlay content for [content], applying a change at
|
||||||
/// [expectedCompletion] with [prefixLength], according to [overlay], one of
|
/// [expectedCompletion] with [prefixLength], according to [overlay], one of
|
||||||
/// the [CompletionMetricsOptions].
|
/// the [CompletionMetricsOptions].
|
||||||
static String getOverlayContents(
|
static String getOverlayContent(
|
||||||
String contents,
|
String content,
|
||||||
ExpectedCompletion expectedCompletion,
|
ExpectedCompletion expectedCompletion,
|
||||||
// TODO(srawlins): Replace this with an enum.
|
OverlayMode overlay,
|
||||||
String overlay,
|
|
||||||
int prefixLength,
|
int prefixLength,
|
||||||
) {
|
) {
|
||||||
assert(contents.isNotEmpty);
|
assert(content.isNotEmpty);
|
||||||
var offset = expectedCompletion.offset;
|
var offset = expectedCompletion.offset;
|
||||||
final length = expectedCompletion.syntacticEntity.length;
|
final length = expectedCompletion.syntacticEntity.length;
|
||||||
assert(offset >= 0);
|
assert(offset >= 0);
|
||||||
|
@ -192,16 +191,12 @@ abstract class CompletionMetricsComputer {
|
||||||
// the given prefix length.
|
// the given prefix length.
|
||||||
offset += prefixLength;
|
offset += prefixLength;
|
||||||
}
|
}
|
||||||
if (overlay == CompletionMetricsOptions.OVERLAY_REMOVE_TOKEN) {
|
if (overlay == OverlayMode.removeToken) {
|
||||||
return contents.substring(0, offset) + contents.substring(tokenEndOffset);
|
return content.substring(0, offset) + content.substring(tokenEndOffset);
|
||||||
} else if (overlay ==
|
} else if (overlay == OverlayMode.removeRestOfFile) {
|
||||||
CompletionMetricsOptions.OVERLAY_REMOVE_REST_OF_FILE) {
|
return content.substring(0, offset);
|
||||||
return contents.substring(0, offset);
|
|
||||||
} else {
|
} else {
|
||||||
final removeToken = CompletionMetricsOptions.OVERLAY_REMOVE_TOKEN;
|
throw ArgumentError.value(overlay, 'overlay');
|
||||||
final removeRest = CompletionMetricsOptions.OVERLAY_REMOVE_REST_OF_FILE;
|
|
||||||
throw Exception('\'getOverlayContents\' called with option other than'
|
|
||||||
'$removeToken and $removeRest: $overlay');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,18 +206,6 @@ class CompletionMetricsOptions {
|
||||||
/// An option to control whether and how overlays should be produced.
|
/// An option to control whether and how overlays should be produced.
|
||||||
static const String OVERLAY = 'overlay';
|
static const String OVERLAY = 'overlay';
|
||||||
|
|
||||||
/// A mode indicating that no overlays should be produced.
|
|
||||||
/// TODO(srawlins): Replace this and the other two overlay values with enums.
|
|
||||||
static const String OVERLAY_NONE = 'none';
|
|
||||||
|
|
||||||
/// A mode indicating that everything from the completion offset to the end of
|
|
||||||
/// the file should be removed.
|
|
||||||
static const String OVERLAY_REMOVE_REST_OF_FILE = 'remove-rest-of-file';
|
|
||||||
|
|
||||||
/// A mode indicating that the token whose offset is the same as the
|
|
||||||
/// completion offset should be removed.
|
|
||||||
static const String OVERLAY_REMOVE_TOKEN = 'remove-token';
|
|
||||||
|
|
||||||
/// An option controlling how long of a prefix should be used.
|
/// An option controlling how long of a prefix should be used.
|
||||||
///
|
///
|
||||||
/// This affects the offset of the completion request, and how much content is
|
/// This affects the offset of the completion request, and how much content is
|
||||||
|
@ -234,8 +217,7 @@ class CompletionMetricsOptions {
|
||||||
static const String PRINT_SLOWEST_RESULTS = 'print-slowest-results';
|
static const String PRINT_SLOWEST_RESULTS = 'print-slowest-results';
|
||||||
|
|
||||||
/// The overlay mode that should be used.
|
/// The overlay mode that should be used.
|
||||||
/// TODO(srawlins): Replace this with an enum.
|
final OverlayMode overlay;
|
||||||
final String overlay;
|
|
||||||
|
|
||||||
final int prefixLength;
|
final int prefixLength;
|
||||||
|
|
||||||
|
@ -244,12 +226,34 @@ class CompletionMetricsOptions {
|
||||||
final bool printSlowestResults;
|
final bool printSlowestResults;
|
||||||
|
|
||||||
CompletionMetricsOptions(ArgResults results)
|
CompletionMetricsOptions(ArgResults results)
|
||||||
: overlay = results[OVERLAY] as String,
|
: overlay = OverlayMode.parseFlag(results[OVERLAY] as String),
|
||||||
prefixLength = int.parse(results[PREFIX_LENGTH] as String),
|
prefixLength = int.parse(results[PREFIX_LENGTH] as String),
|
||||||
printSlowestResults = results[PRINT_SLOWEST_RESULTS] as bool {
|
printSlowestResults = results[PRINT_SLOWEST_RESULTS] as bool;
|
||||||
assert(overlay == OVERLAY_NONE ||
|
}
|
||||||
overlay == OVERLAY_REMOVE_TOKEN ||
|
|
||||||
overlay == OVERLAY_REMOVE_REST_OF_FILE);
|
enum OverlayMode {
|
||||||
|
/// A mode indicating that no overlays should be produced.
|
||||||
|
none('none'),
|
||||||
|
|
||||||
|
/// A mode indicating that everything from the completion offset to the end of
|
||||||
|
/// the file should be removed.
|
||||||
|
removeRestOfFile('remove-rest-of-file'),
|
||||||
|
|
||||||
|
/// A mode indicating that the token whose offset is the same as the
|
||||||
|
/// completion offset should be removed.
|
||||||
|
removeToken('remove-token');
|
||||||
|
|
||||||
|
final String flag;
|
||||||
|
|
||||||
|
const OverlayMode(this.flag);
|
||||||
|
|
||||||
|
static OverlayMode parseFlag(String flag) {
|
||||||
|
for (final mode in values) {
|
||||||
|
if (flag == mode.flag) {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw ArgumentError.value(flag, 'overlay');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,11 +68,11 @@ ArgParser _createArgParser() {
|
||||||
..addOption(
|
..addOption(
|
||||||
CompletionMetricsOptions.OVERLAY,
|
CompletionMetricsOptions.OVERLAY,
|
||||||
allowed: [
|
allowed: [
|
||||||
CompletionMetricsOptions.OVERLAY_NONE,
|
OverlayMode.none.flag,
|
||||||
CompletionMetricsOptions.OVERLAY_REMOVE_TOKEN,
|
OverlayMode.removeRestOfFile.flag,
|
||||||
CompletionMetricsOptions.OVERLAY_REMOVE_REST_OF_FILE,
|
OverlayMode.removeToken.flag,
|
||||||
],
|
],
|
||||||
defaultsTo: CompletionMetricsOptions.OVERLAY_NONE,
|
defaultsTo: OverlayMode.none.flag,
|
||||||
help: 'Before attempting a completion at the location of each token, the '
|
help: 'Before attempting a completion at the location of each token, the '
|
||||||
'token can be removed, or the rest of the file can be removed to '
|
'token can be removed, or the rest of the file can be removed to '
|
||||||
'test code completion with diverse methods. The default mode is to '
|
'test code completion with diverse methods. The default mode is to '
|
||||||
|
@ -143,7 +143,21 @@ class CompletionClientMetricsComputer extends CompletionMetricsComputer {
|
||||||
String filePath,
|
String filePath,
|
||||||
ExpectedCompletion expectedCompletion,
|
ExpectedCompletion expectedCompletion,
|
||||||
) async {
|
) async {
|
||||||
// TODO(srawlins): Support overlays.
|
if (options.overlay != OverlayMode.none) {
|
||||||
|
final overlayContent = CompletionMetricsComputer.getOverlayContent(
|
||||||
|
resolvedUnitResult.content,
|
||||||
|
expectedCompletion,
|
||||||
|
options.overlay,
|
||||||
|
options.prefixLength,
|
||||||
|
);
|
||||||
|
|
||||||
|
provider.setOverlay(
|
||||||
|
filePath,
|
||||||
|
content: overlayContent,
|
||||||
|
modificationStamp: overlayModificationStamp++,
|
||||||
|
);
|
||||||
|
await client.addOverlay(filePath, overlayContent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -193,8 +207,10 @@ class CompletionClientMetricsComputer extends CompletionMetricsComputer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void removeOverlay(String filePath) {
|
Future<void> removeOverlay(String filePath) async {
|
||||||
// TODO(srawlins): Support overlays.
|
if (options.overlay != OverlayMode.none) {
|
||||||
|
await client.removeOverlay(filePath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -275,19 +291,55 @@ class _AnalysisServerClient {
|
||||||
|
|
||||||
Future<int> get onExit => _process!.exitCode;
|
Future<int> get onExit => _process!.exitCode;
|
||||||
|
|
||||||
|
Future<AnalysisUpdateContentResult> addOverlay(
|
||||||
|
String file, String content) async {
|
||||||
|
final response = await _sendCommand(
|
||||||
|
'analysis.updateContent',
|
||||||
|
params: {
|
||||||
|
'files': {
|
||||||
|
file: {'type': 'add', 'content': content},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
final result = response['result'] as Map<String, dynamic>;
|
||||||
|
|
||||||
|
return AnalysisUpdateContentResult.fromJson(
|
||||||
|
ResponseDecoder(null),
|
||||||
|
'result',
|
||||||
|
result,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<bool> dispose() async {
|
Future<bool> dispose() async {
|
||||||
return _process?.kill() ?? true;
|
return _process?.kill() ?? true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<AnalysisUpdateContentResult> removeOverlay(String file) async {
|
||||||
|
final response = await _sendCommand(
|
||||||
|
'analysis.updateContent',
|
||||||
|
params: {
|
||||||
|
'files': {
|
||||||
|
file: {'type': 'remove'},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
final result = response['result'] as Map<String, dynamic>;
|
||||||
|
|
||||||
|
return AnalysisUpdateContentResult.fromJson(
|
||||||
|
ResponseDecoder(null),
|
||||||
|
'result',
|
||||||
|
result,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Requests a completion for [file] at [offset].
|
/// Requests a completion for [file] at [offset].
|
||||||
Future<_SuggestionsData> requestCompletion(
|
Future<_SuggestionsData> requestCompletion(
|
||||||
String file, int offset, int maxResults) async {
|
String file, int offset, int maxResults) async {
|
||||||
final response = await _sendCommand('completion.getSuggestions2',
|
final response = await _sendCommand('completion.getSuggestions2', params: {
|
||||||
params: <String, dynamic>{
|
'file': file,
|
||||||
'file': file,
|
'offset': offset,
|
||||||
'offset': offset,
|
'maxResults': maxResults,
|
||||||
'maxResults': maxResults,
|
});
|
||||||
});
|
|
||||||
final result = response['result'] as Map<String, dynamic>;
|
final result = response['result'] as Map<String, dynamic>;
|
||||||
final metadata = _requestMetadata[response['id']]!;
|
final metadata = _requestMetadata[response['id']]!;
|
||||||
|
|
||||||
|
@ -440,10 +492,7 @@ class _AnalysisServerClient {
|
||||||
.remove(id)
|
.remove(id)
|
||||||
?.completeError(_RequestError.parse(error));
|
?.completeError(_RequestError.parse(error));
|
||||||
} else {
|
} else {
|
||||||
_requestCompleters.remove(id)?.complete(
|
_requestCompleters.remove(id)?.complete(response);
|
||||||
//response['result'] as Map<String, dynamic>? ??
|
|
||||||
// <String, dynamic>{});
|
|
||||||
response);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue