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(); |
- } |
-} |