mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 08:24:39 +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,
|
||||
allowed: [
|
||||
CompletionMetricsOptions.OVERLAY_NONE,
|
||||
CompletionMetricsOptions.OVERLAY_REMOVE_TOKEN,
|
||||
CompletionMetricsOptions.OVERLAY_REMOVE_REST_OF_FILE
|
||||
OverlayMode.none.flag,
|
||||
OverlayMode.removeRestOfFile.flag,
|
||||
OverlayMode.removeToken.flag,
|
||||
],
|
||||
defaultsTo: CompletionMetricsOptions.OVERLAY_NONE,
|
||||
defaultsTo: OverlayMode.none.flag,
|
||||
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 '
|
||||
|
@ -745,17 +745,20 @@ class CompletionQualityMetricsComputer extends CompletionMetricsComputer {
|
|||
ExpectedCompletion expectedCompletion,
|
||||
) async {
|
||||
// If an overlay option is being used, compute the overlay file, and
|
||||
// have the context reanalyze the file
|
||||
if (options.overlay != CompletionMetricsOptions.OVERLAY_NONE) {
|
||||
var overlayContents = CompletionMetricsComputer.getOverlayContents(
|
||||
resolvedUnitResult.content,
|
||||
expectedCompletion,
|
||||
options.overlay,
|
||||
options.prefixLength);
|
||||
// have the context reanalyze the file.
|
||||
if (options.overlay != OverlayMode.none) {
|
||||
final overlayContents = CompletionMetricsComputer.getOverlayContent(
|
||||
resolvedUnitResult.content,
|
||||
expectedCompletion,
|
||||
options.overlay,
|
||||
options.prefixLength,
|
||||
);
|
||||
|
||||
provider.setOverlay(filePath,
|
||||
content: overlayContents,
|
||||
modificationStamp: overlayModificationStamp++);
|
||||
provider.setOverlay(
|
||||
filePath,
|
||||
content: overlayContents,
|
||||
modificationStamp: overlayModificationStamp++,
|
||||
);
|
||||
context.changeFile(filePath);
|
||||
await context.applyPendingFileChanges();
|
||||
resolvedUnitResult = await context.currentSession
|
||||
|
@ -1396,10 +1399,10 @@ class CompletionQualityMetricsComputer extends CompletionMetricsComputer {
|
|||
}
|
||||
|
||||
@override
|
||||
void removeOverlay(String filePath) {
|
||||
Future<void> removeOverlay(String filePath) async {
|
||||
// If an overlay option is being used, remove the overlay applied
|
||||
// earlier.
|
||||
if (options.overlay != CompletionMetricsOptions.OVERLAY_NONE) {
|
||||
if (options.overlay != OverlayMode.none) {
|
||||
provider.removeOverlay(filePath);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ abstract class CompletionMetricsComputer {
|
|||
documentationCache,
|
||||
);
|
||||
|
||||
removeOverlay(filePath);
|
||||
await removeOverlay(filePath);
|
||||
}
|
||||
progress.tick();
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ abstract class CompletionMetricsComputer {
|
|||
);
|
||||
|
||||
/// Removes the overlay which has been applied to [filePath].
|
||||
void removeOverlay(String filePath);
|
||||
Future<void> removeOverlay(String filePath);
|
||||
|
||||
/// Resolves all analyzed files within [context].
|
||||
Future<List<ResolvedUnitResult>> resolveAnalyzedFiles({
|
||||
|
@ -171,17 +171,16 @@ abstract class CompletionMetricsComputer {
|
|||
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
|
||||
/// the [CompletionMetricsOptions].
|
||||
static String getOverlayContents(
|
||||
String contents,
|
||||
static String getOverlayContent(
|
||||
String content,
|
||||
ExpectedCompletion expectedCompletion,
|
||||
// TODO(srawlins): Replace this with an enum.
|
||||
String overlay,
|
||||
OverlayMode overlay,
|
||||
int prefixLength,
|
||||
) {
|
||||
assert(contents.isNotEmpty);
|
||||
assert(content.isNotEmpty);
|
||||
var offset = expectedCompletion.offset;
|
||||
final length = expectedCompletion.syntacticEntity.length;
|
||||
assert(offset >= 0);
|
||||
|
@ -192,16 +191,12 @@ abstract class CompletionMetricsComputer {
|
|||
// the given prefix length.
|
||||
offset += prefixLength;
|
||||
}
|
||||
if (overlay == CompletionMetricsOptions.OVERLAY_REMOVE_TOKEN) {
|
||||
return contents.substring(0, offset) + contents.substring(tokenEndOffset);
|
||||
} else if (overlay ==
|
||||
CompletionMetricsOptions.OVERLAY_REMOVE_REST_OF_FILE) {
|
||||
return contents.substring(0, offset);
|
||||
if (overlay == OverlayMode.removeToken) {
|
||||
return content.substring(0, offset) + content.substring(tokenEndOffset);
|
||||
} else if (overlay == OverlayMode.removeRestOfFile) {
|
||||
return content.substring(0, offset);
|
||||
} else {
|
||||
final removeToken = CompletionMetricsOptions.OVERLAY_REMOVE_TOKEN;
|
||||
final removeRest = CompletionMetricsOptions.OVERLAY_REMOVE_REST_OF_FILE;
|
||||
throw Exception('\'getOverlayContents\' called with option other than'
|
||||
'$removeToken and $removeRest: $overlay');
|
||||
throw ArgumentError.value(overlay, 'overlay');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,18 +206,6 @@ class CompletionMetricsOptions {
|
|||
/// An option to control whether and how overlays should be produced.
|
||||
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.
|
||||
///
|
||||
/// 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';
|
||||
|
||||
/// The overlay mode that should be used.
|
||||
/// TODO(srawlins): Replace this with an enum.
|
||||
final String overlay;
|
||||
final OverlayMode overlay;
|
||||
|
||||
final int prefixLength;
|
||||
|
||||
|
@ -244,12 +226,34 @@ class CompletionMetricsOptions {
|
|||
final bool printSlowestResults;
|
||||
|
||||
CompletionMetricsOptions(ArgResults results)
|
||||
: overlay = results[OVERLAY] as String,
|
||||
: overlay = OverlayMode.parseFlag(results[OVERLAY] as String),
|
||||
prefixLength = int.parse(results[PREFIX_LENGTH] as String),
|
||||
printSlowestResults = results[PRINT_SLOWEST_RESULTS] as bool {
|
||||
assert(overlay == OVERLAY_NONE ||
|
||||
overlay == OVERLAY_REMOVE_TOKEN ||
|
||||
overlay == OVERLAY_REMOVE_REST_OF_FILE);
|
||||
printSlowestResults = results[PRINT_SLOWEST_RESULTS] as bool;
|
||||
}
|
||||
|
||||
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(
|
||||
CompletionMetricsOptions.OVERLAY,
|
||||
allowed: [
|
||||
CompletionMetricsOptions.OVERLAY_NONE,
|
||||
CompletionMetricsOptions.OVERLAY_REMOVE_TOKEN,
|
||||
CompletionMetricsOptions.OVERLAY_REMOVE_REST_OF_FILE,
|
||||
OverlayMode.none.flag,
|
||||
OverlayMode.removeRestOfFile.flag,
|
||||
OverlayMode.removeToken.flag,
|
||||
],
|
||||
defaultsTo: CompletionMetricsOptions.OVERLAY_NONE,
|
||||
defaultsTo: OverlayMode.none.flag,
|
||||
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 '
|
||||
'test code completion with diverse methods. The default mode is to '
|
||||
|
@ -143,7 +143,21 @@ class CompletionClientMetricsComputer extends CompletionMetricsComputer {
|
|||
String filePath,
|
||||
ExpectedCompletion expectedCompletion,
|
||||
) 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
|
||||
|
@ -193,8 +207,10 @@ class CompletionClientMetricsComputer extends CompletionMetricsComputer {
|
|||
}
|
||||
|
||||
@override
|
||||
void removeOverlay(String filePath) {
|
||||
// TODO(srawlins): Support overlays.
|
||||
Future<void> removeOverlay(String filePath) async {
|
||||
if (options.overlay != OverlayMode.none) {
|
||||
await client.removeOverlay(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -275,19 +291,55 @@ class _AnalysisServerClient {
|
|||
|
||||
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 {
|
||||
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].
|
||||
Future<_SuggestionsData> requestCompletion(
|
||||
String file, int offset, int maxResults) async {
|
||||
final response = await _sendCommand('completion.getSuggestions2',
|
||||
params: <String, dynamic>{
|
||||
'file': file,
|
||||
'offset': offset,
|
||||
'maxResults': maxResults,
|
||||
});
|
||||
final response = await _sendCommand('completion.getSuggestions2', params: {
|
||||
'file': file,
|
||||
'offset': offset,
|
||||
'maxResults': maxResults,
|
||||
});
|
||||
final result = response['result'] as Map<String, dynamic>;
|
||||
final metadata = _requestMetadata[response['id']]!;
|
||||
|
||||
|
@ -440,10 +492,7 @@ class _AnalysisServerClient {
|
|||
.remove(id)
|
||||
?.completeError(_RequestError.parse(error));
|
||||
} else {
|
||||
_requestCompleters.remove(id)?.complete(
|
||||
//response['result'] as Map<String, dynamic>? ??
|
||||
// <String, dynamic>{});
|
||||
response);
|
||||
_requestCompleters.remove(id)?.complete(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue