| Index: pkg/analysis_server/test/performance/input_converter.dart
|
| diff --git a/pkg/analysis_server/test/performance/input_converter.dart b/pkg/analysis_server/test/performance/input_converter.dart
|
| deleted file mode 100644
|
| index ef90131cb56835fecfeb5ca9caaa692a6bc0ae53..0000000000000000000000000000000000000000
|
| --- a/pkg/analysis_server/test/performance/input_converter.dart
|
| +++ /dev/null
|
| @@ -1,371 +0,0 @@
|
| -// Copyright (c) 2015, 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.
|
| -
|
| -library input.transformer;
|
| -
|
| -import 'dart:async';
|
| -import 'dart:convert';
|
| -import 'dart:io';
|
| -
|
| -import 'package:analysis_server/src/constants.dart';
|
| -import 'package:analysis_server/src/protocol.dart';
|
| -import 'package:logging/logging.dart';
|
| -import 'package:path/path.dart' as path;
|
| -
|
| -import 'instrumentation_input_converter.dart';
|
| -import 'log_file_input_converter.dart';
|
| -import 'operation.dart';
|
| -
|
| -/**
|
| - * Common input converter superclass for sharing implementation.
|
| - */
|
| -abstract class CommonInputConverter extends Converter<String, Operation> {
|
| - static final ERROR_PREFIX = 'Server responded with an error: ';
|
| - final Logger logger = new Logger('InstrumentationInputConverter');
|
| - final Set<String> eventsSeen = new Set<String>();
|
| -
|
| - /**
|
| - * A mapping from request/response id to request json
|
| - * for those requests for which a response has not been processed.
|
| - */
|
| - final Map<String, dynamic> requestMap = {};
|
| -
|
| - /**
|
| - * A mapping from request/response id to a completer
|
| - * for those requests for which a response has not been processed.
|
| - * The completer is called with the actual json response
|
| - * when it becomes available.
|
| - */
|
| - final Map<String, Completer> responseCompleters = {};
|
| -
|
| - /**
|
| - * A mapping from request/response id to the actual response result
|
| - * for those responses that have not been processed.
|
| - */
|
| - final Map<String, dynamic> responseMap = {};
|
| -
|
| - /**
|
| - * A mapping of current overlay content
|
| - * parallel to what is in the analysis server
|
| - * so that we can update the file system.
|
| - */
|
| - final Map<String, String> overlays = {};
|
| -
|
| - /**
|
| - * The prefix used to determine if a request parameter is a file path.
|
| - */
|
| - final String rootPrefix = path.rootPrefix(path.current);
|
| -
|
| - /**
|
| - * A mapping of source path prefixes
|
| - * from location where instrumentation or log file was generated
|
| - * to the target location of the source using during performance measurement.
|
| - */
|
| - final Map<String, String> srcPathMap;
|
| -
|
| - /**
|
| - * The root directory for all source being modified
|
| - * during performance measurement.
|
| - */
|
| - final String tmpSrcDirPath;
|
| -
|
| - /**
|
| - * The diagnostic port for Analysis Server or `null` if none.
|
| - */
|
| - final int diagnosticPort;
|
| -
|
| - CommonInputConverter(this.tmpSrcDirPath, this.srcPathMap,
|
| - {this.diagnosticPort});
|
| -
|
| - /**
|
| - * Return an operation for the notification or `null` if none.
|
| - */
|
| - Operation convertNotification(Map<String, dynamic> json) {
|
| - String event = json['event'];
|
| - if (event == SERVER_STATUS) {
|
| - // {"event":"server.status","params":{"analysis":{"isAnalyzing":false}}}
|
| - Map<String, dynamic> params = json['params'];
|
| - if (params != null) {
|
| - Map<String, dynamic> analysis = params['analysis'];
|
| - if (analysis != null && analysis['isAnalyzing'] == false) {
|
| - return new WaitForAnalysisCompleteOperation();
|
| - }
|
| - }
|
| - }
|
| - if (event == SERVER_CONNECTED) {
|
| - // {"event":"server.connected","params":{"version":"1.7.0"}}
|
| - return new StartServerOperation(diagnosticPort: diagnosticPort);
|
| - }
|
| - if (eventsSeen.add(event)) {
|
| - logger.log(Level.INFO, 'Ignored notification: $event\n $json');
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - /**
|
| - * Return an operation for the request or `null` if none.
|
| - */
|
| - Operation convertRequest(Map<String, dynamic> origJson) {
|
| - Map<String, dynamic> json = translateSrcPaths(origJson);
|
| - requestMap[json['id']] = json;
|
| - String method = json['method'];
|
| - // Sanity check operations that modify source
|
| - // to ensure that the operation is on source in temp space
|
| - if (method == ANALYSIS_UPDATE_CONTENT) {
|
| - // Track overlays in parallel with the analysis server
|
| - // so that when an overlay is removed, the file can be updated on disk
|
| - Request request = new Request.fromJson(json);
|
| - var params = new AnalysisUpdateContentParams.fromRequest(request);
|
| - params.files.forEach((String filePath, change) {
|
| - if (change is AddContentOverlay) {
|
| - String content = change.content;
|
| - if (content == null) {
|
| - throw 'expected new overlay content\n$json';
|
| - }
|
| - overlays[filePath] = content;
|
| - } else if (change is ChangeContentOverlay) {
|
| - String content = overlays[filePath];
|
| - if (content == null) {
|
| - throw 'expected cached overlay content\n$json';
|
| - }
|
| - overlays[filePath] = SourceEdit.applySequence(content, change.edits);
|
| - } else if (change is RemoveContentOverlay) {
|
| - String content = overlays.remove(filePath);
|
| - if (content == null) {
|
| - throw 'expected cached overlay content\n$json';
|
| - }
|
| - if (!path.isWithin(tmpSrcDirPath, filePath)) {
|
| - throw 'found path referencing source outside temp space\n$filePath\n$json';
|
| - }
|
| - new File(filePath).writeAsStringSync(content);
|
| - } else {
|
| - throw 'unknown overlay change $change\n$json';
|
| - }
|
| - });
|
| - return new RequestOperation(this, json);
|
| - }
|
| - // Track performance for completion notifications
|
| - if (method == COMPLETION_GET_SUGGESTIONS) {
|
| - return new CompletionRequestOperation(this, json);
|
| - }
|
| - // TODO(danrubel) replace this with code
|
| - // that just forwards the translated request
|
| - if (method == ANALYSIS_GET_HOVER ||
|
| - method == ANALYSIS_SET_ANALYSIS_ROOTS ||
|
| - method == ANALYSIS_SET_PRIORITY_FILES ||
|
| - method == ANALYSIS_SET_SUBSCRIPTIONS ||
|
| - method == ANALYSIS_UPDATE_OPTIONS ||
|
| - method == EDIT_GET_ASSISTS ||
|
| - method == EDIT_GET_AVAILABLE_REFACTORINGS ||
|
| - method == EDIT_GET_FIXES ||
|
| - method == EDIT_GET_REFACTORING ||
|
| - method == EDIT_SORT_MEMBERS ||
|
| - method == EXECUTION_CREATE_CONTEXT ||
|
| - method == EXECUTION_DELETE_CONTEXT ||
|
| - method == EXECUTION_MAP_URI ||
|
| - method == EXECUTION_SET_SUBSCRIPTIONS ||
|
| - method == SEARCH_FIND_ELEMENT_REFERENCES ||
|
| - method == SEARCH_FIND_MEMBER_DECLARATIONS ||
|
| - method == SERVER_GET_VERSION ||
|
| - method == SERVER_SET_SUBSCRIPTIONS) {
|
| - return new RequestOperation(this, json);
|
| - }
|
| - throw 'unknown request: $method\n $json';
|
| - }
|
| -
|
| - /**
|
| - * Return an operation for the recorded/expected response.
|
| - */
|
| - Operation convertResponse(Map<String, dynamic> json) {
|
| - return new ResponseOperation(
|
| - this, requestMap.remove(json['id']), translateSrcPaths(json));
|
| - }
|
| -
|
| - /**
|
| - * Process an error response from the server by either
|
| - * completing the associated completer in the [responseCompleters]
|
| - * or stashing it in [responseMap] if no completer exists.
|
| - */
|
| - void processErrorResponse(String id, exception) {
|
| - var result = exception;
|
| - if (exception is UnimplementedError) {
|
| - if (exception.message.startsWith(ERROR_PREFIX)) {
|
| - result = JSON.decode(exception.message.substring(ERROR_PREFIX.length));
|
| - }
|
| - }
|
| - processResponseResult(id, result);
|
| - }
|
| -
|
| - /**
|
| - * Process the expected response by completing the given completer
|
| - * with the result if it has alredy been received,
|
| - * or caching the completer to be completed when the server
|
| - * returns the associated result.
|
| - * Return a future that completes when the response is received
|
| - * or `null` if the response has already been received
|
| - * and the completer completed.
|
| - */
|
| - Future processExpectedResponse(String id, Completer completer) {
|
| - if (responseMap.containsKey(id)) {
|
| - logger.log(Level.INFO, 'processing cached response $id');
|
| - completer.complete(responseMap.remove(id));
|
| - return null;
|
| - } else {
|
| - logger.log(Level.INFO, 'waiting for response $id');
|
| - responseCompleters[id] = completer;
|
| - return completer.future;
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Process a success response result from the server by either
|
| - * completing the associated completer in the [responseCompleters]
|
| - * or stashing it in [responseMap] if no completer exists.
|
| - * The response result may be `null`.
|
| - */
|
| - void processResponseResult(String id, result) {
|
| - Completer completer = responseCompleters[id];
|
| - if (completer != null) {
|
| - logger.log(Level.INFO, 'processing response $id');
|
| - completer.complete(result);
|
| - } else {
|
| - logger.log(Level.INFO, 'caching response $id');
|
| - responseMap[id] = result;
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Recursively translate source paths in the specified JSON to reference
|
| - * the temporary source used during performance measurement rather than
|
| - * the original source when the instrumentation or log file was generated.
|
| - */
|
| - translateSrcPaths(json) {
|
| - if (json is String) {
|
| - String result = json;
|
| - srcPathMap.forEach((String oldPrefix, String newPrefix) {
|
| - if (json.startsWith(oldPrefix)) {
|
| - result = '$newPrefix${json.substring(oldPrefix.length)}';
|
| - }
|
| - });
|
| - return result;
|
| - }
|
| - if (json is List) {
|
| - List result = [];
|
| - for (int i = 0; i < json.length; ++i) {
|
| - result.add(translateSrcPaths(json[i]));
|
| - }
|
| - return result;
|
| - }
|
| - if (json is Map) {
|
| - Map<String, dynamic> result = new Map<String, dynamic>();
|
| - json.forEach((String origKey, value) {
|
| - result[translateSrcPaths(origKey)] = translateSrcPaths(value);
|
| - });
|
| - return result;
|
| - }
|
| - return json;
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * [InputConverter] converts an input stream
|
| - * into a series of operations to be sent to the analysis server.
|
| - * The input stream can be either an instrumenation or log file.
|
| - */
|
| -class InputConverter extends Converter<String, Operation> {
|
| - final Logger logger = new Logger('InputConverter');
|
| -
|
| - /**
|
| - * A mapping of source path prefixes
|
| - * from location where instrumentation or log file was generated
|
| - * to the target location of the source using during performance measurement.
|
| - */
|
| - final Map<String, String> srcPathMap;
|
| -
|
| - /**
|
| - * The root directory for all source being modified
|
| - * during performance measurement.
|
| - */
|
| - final String tmpSrcDirPath;
|
| -
|
| - /**
|
| - * The diagnostic port for Analysis Server or `null` if none.
|
| - */
|
| - final int diagnosticPort;
|
| -
|
| - /**
|
| - * The number of lines read before the underlying converter was determined
|
| - * or the end of file was reached.
|
| - */
|
| - int headerLineCount = 0;
|
| -
|
| - /**
|
| - * The underlying converter used to translate lines into operations
|
| - * or `null` if it has not yet been determined.
|
| - */
|
| - Converter<String, Operation> converter;
|
| -
|
| - /**
|
| - * [active] is `true` if converting lines to operations
|
| - * or `false` if an exception has occurred.
|
| - */
|
| - bool active = true;
|
| -
|
| - InputConverter(this.tmpSrcDirPath, this.srcPathMap, {this.diagnosticPort});
|
| -
|
| - @override
|
| - Operation convert(String line) {
|
| - if (!active) {
|
| - return null;
|
| - }
|
| - if (converter != null) {
|
| - try {
|
| - return converter.convert(line);
|
| - } catch (e) {
|
| - active = false;
|
| - rethrow;
|
| - }
|
| - }
|
| - if (headerLineCount == 20) {
|
| - throw 'Failed to determine input file format';
|
| - }
|
| - if (InstrumentationInputConverter.isFormat(line)) {
|
| - converter = new InstrumentationInputConverter(tmpSrcDirPath, srcPathMap,
|
| - diagnosticPort: diagnosticPort);
|
| - } else if (LogFileInputConverter.isFormat(line)) {
|
| - converter = new LogFileInputConverter(tmpSrcDirPath, srcPathMap,
|
| - diagnosticPort: diagnosticPort);
|
| - }
|
| - if (converter != null) {
|
| - return converter.convert(line);
|
| - }
|
| - logger.log(Level.INFO, 'skipped input line: $line');
|
| - return null;
|
| - }
|
| -
|
| - @override
|
| - _InputSink startChunkedConversion(outSink) {
|
| - return new _InputSink(this, outSink);
|
| - }
|
| -}
|
| -
|
| -class _InputSink extends ChunkedConversionSink<String> {
|
| - final Converter<String, Operation> converter;
|
| - final outSink;
|
| -
|
| - _InputSink(this.converter, this.outSink);
|
| -
|
| - @override
|
| - void add(String line) {
|
| - Operation op = converter.convert(line);
|
| - if (op != null) {
|
| - outSink.add(op);
|
| - }
|
| - }
|
| -
|
| - @override
|
| - void close() {
|
| - outSink.close();
|
| - }
|
| -}
|
|
|