Skip to content

Commit

Permalink
Add stub implementation for analysis server edit.dartfix
Browse files Browse the repository at this point in the history
Change-Id: Iefaec93366c5a6910e3c2e7dfebc91e8905922c2
Reviewed-on: https://dart-review.googlesource.com/76520
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Dan Rubel <danrubel@google.com>
  • Loading branch information
Dan Rubel authored and commit-bot@chromium.org committed Sep 26, 2018
1 parent 0808d29 commit a0ff5f8
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 46 deletions.
2 changes: 1 addition & 1 deletion pkg/analysis_server/lib/protocol/protocol.dart
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ class Response {
Response.formatInvalidFile(Request request)
: this(request.id,
error: new RequestError(RequestErrorCode.FORMAT_INVALID_FILE,
'Error during `edit.format`: invalid file.'));
'Error during `${request.method}`: invalid file.'));

/**
* Initialize a newly created instance to represent the FORMAT_WITH_ERROR
Expand Down
15 changes: 15 additions & 0 deletions pkg/analysis_server/lib/src/edit/edit_dartfix.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) 2014, 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:analysis_server/protocol/protocol.dart';

class EditDartFix {
final Request request;

EditDartFix(this.request);

Future<Response> compute() async {
return new Response.formatInvalidFile(request);
}
}
19 changes: 19 additions & 0 deletions pkg/analysis_server/lib/src/edit/edit_domain.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/collections.dart';
import 'package:analysis_server/src/computer/import_elements_computer.dart';
import 'package:analysis_server/src/domain_abstract.dart';
import 'package:analysis_server/src/edit/edit_dartfix.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analysis_server/src/plugin/result_converter.dart';
import 'package:analysis_server/src/protocol_server.dart' hide Element;
Expand Down Expand Up @@ -260,6 +261,21 @@ class EditDomainHandler extends AbstractRequestHandler {
new EditGetFixesResult(errorFixesList).toResponse(request.id));
}

Future dartfix(Request request) async {
// TODO(danrubel): Fix only the included sources
//EditDartfixParams params = new EditDartfixParams.fromRequest(request);

// TODO(danrubel): Add support for dartfix plugins

//
// Compute fixes
//
var dartFix = new EditDartFix(request);
Response response = await dartFix.compute();

server.sendResponse(response);
}

Future getPostfixCompletion(Request request) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
Expand Down Expand Up @@ -346,6 +362,9 @@ class EditDomainHandler extends AbstractRequestHandler {
} else if (requestName == EDIT_REQUEST_GET_FIXES) {
getFixes(request);
return Response.DELAYED_RESPONSE;
} else if (requestName == EDIT_REQUEST_DARTFIX) {
dartfix(request);
return Response.DELAYED_RESPONSE;
} else if (requestName == EDIT_REQUEST_GET_REFACTORING) {
return _getRefactoring(request);
} else if (requestName == EDIT_REQUEST_IMPORT_ELEMENTS) {
Expand Down
105 changes: 65 additions & 40 deletions pkg/analyzer_cli/lib/src/fix/driver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';

import 'package:analysis_server/protocol/protocol_constants.dart';
import 'package:analyzer_cli/src/fix/options.dart';
import 'package:analyzer_cli/src/fix/server.dart';
import 'package:analysis_server/src/protocol/protocol_internal.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';

class Driver {
static const timeout = const Duration(seconds: 5);
// For development
const runAnalysisServerFromSource = false;

class Driver {
final Server server = new Server();

Completer serverConnected;
Completer analysisComplete;
int errorCount;
bool verbose;

Future start(List<String> args) async {
Expand All @@ -27,49 +30,68 @@ class Driver {
}
verbose = options.verbose;

serverConnected = new Completer();
analysisComplete = new Completer();

await startServer(options);
outSink.writeln('Analyzing...');
await setupAnalysis(options);

// TODO(danrubel): Request fixes rather than waiting for analysis complete
await analysisComplete.future;

outSink.writeln('Analysis complete.');
await stopServer(server);
bool normalShutdown = false;
try {
await performAnalysis(options);
await requestFixes(options);
normalShutdown = true;
} finally {
try {
await stopServer(server);
} catch (_) {
if (normalShutdown) {
rethrow;
}
}
}
}

Future startServer(Options options) async {
const connectTimeout = const Duration(seconds: 15);
serverConnected = new Completer();
if (options.verbose) {
server.debugStdio();
}
verboseOut('Starting...');
await server.start(sdkPath: options.sdkPath);
await server.start(
sdkPath: options.sdkPath, useSnapshot: !runAnalysisServerFromSource);
server.listenToOutput(dispatchNotification);
return serverConnected.future.timeout(timeout, onTimeout: () {
return serverConnected.future.timeout(connectTimeout, onTimeout: () {
printAndFail('Failed to connect to server');
});
}

Future setupAnalysis(Options options) async {
Future performAnalysis(Options options) async {
analysisComplete = new Completer();
errorCount = 0;
outSink.writeln('Analyzing...');
verboseOut('Setup analysis');

await server.send("server.setSubscriptions",
await server.send(SERVER_REQUEST_SET_SUBSCRIPTIONS,
new ServerSetSubscriptionsParams([ServerService.STATUS]).toJson());

await server.send(
"analysis.setAnalysisRoots",
ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS,
new AnalysisSetAnalysisRootsParams(
options.analysisRoots,
const [],
).toJson());
await analysisComplete.future;
verboseOut('Analysis complete.');
if (errorCount > 0) {
// TODO: Ask "Do you want to continue given # of errors?"
}
}

Future requestFixes(Options options) async {
outSink.writeln('Calculating fixes...');
Map<String, dynamic> response = await server.send(EDIT_REQUEST_DARTFIX,
new EditDartfixParams(options.analysisRoots).toJson());
print(response);
}

Future stopServer(Server server) async {
verboseOut('Stopping...');
await server.send("server.shutdown", null);
await server.send(SERVER_REQUEST_SHUTDOWN, null);
await server.exitCode.timeout(const Duration(seconds: 5), onTimeout: () {
return server.kill('server failed to exit');
});
Expand All @@ -82,94 +104,94 @@ class Driver {
void dispatchNotification(String event, params) {
ResponseDecoder decoder = new ResponseDecoder(null);
switch (event) {
case "server.connected":
case SERVER_NOTIFICATION_CONNECTED:
onServerConnected(
new ServerConnectedParams.fromJson(decoder, 'params', params));
break;
// case "server.error":
// case SERVER_NOTIFICATION_ERROR:
// outOfTestExpect(params, isServerErrorParams);
// _onServerError
// .add(new ServerErrorParams.fromJson(decoder, 'params', params));
// break;
case "server.status":
case SERVER_NOTIFICATION_STATUS:
onServerStatus(
new ServerStatusParams.fromJson(decoder, 'params', params));
break;
// case "analysis.analyzedFiles":
// case ANALYSIS_NOTIFICATION_ANALYZED_FILES:
// outOfTestExpect(params, isAnalysisAnalyzedFilesParams);
// _onAnalysisAnalyzedFiles.add(new AnalysisAnalyzedFilesParams.fromJson(
// decoder, 'params', params));
// break;
// case "analysis.closingLabels":
// case ANALYSIS_NOTIFICATION_CLOSING_LABELS:
// outOfTestExpect(params, isAnalysisClosingLabelsParams);
// _onAnalysisClosingLabels.add(new AnalysisClosingLabelsParams.fromJson(
// decoder, 'params', params));
// break;
case "analysis.errors":
case ANALYSIS_NOTIFICATION_ERRORS:
onAnalysisErrors(
new AnalysisErrorsParams.fromJson(decoder, 'params', params));
break;
// case "analysis.flushResults":
// case ANALYSIS_NOTIFICATION_FLUSH_RESULTS:
// outOfTestExpect(params, isAnalysisFlushResultsParams);
// _onAnalysisFlushResults.add(
// new AnalysisFlushResultsParams.fromJson(decoder, 'params', params));
// break;
// case "analysis.folding":
// case ANALYSIS_NOTIFICATION_FOLDING:
// outOfTestExpect(params, isAnalysisFoldingParams);
// _onAnalysisFolding
// .add(new AnalysisFoldingParams.fromJson(decoder, 'params', params));
// break;
// case "analysis.highlights":
// case ANALYSIS_NOTIFICATION_HIGHLIGHTS:
// outOfTestExpect(params, isAnalysisHighlightsParams);
// _onAnalysisHighlights.add(
// new AnalysisHighlightsParams.fromJson(decoder, 'params', params));
// break;
// case "analysis.implemented":
// case ANALYSIS_NOTIFICATION_IMPLEMENTED:
// outOfTestExpect(params, isAnalysisImplementedParams);
// _onAnalysisImplemented.add(
// new AnalysisImplementedParams.fromJson(decoder, 'params', params));
// break;
// case "analysis.invalidate":
// case ANALYSIS_NOTIFICATION_INVALIDATE:
// outOfTestExpect(params, isAnalysisInvalidateParams);
// _onAnalysisInvalidate.add(
// new AnalysisInvalidateParams.fromJson(decoder, 'params', params));
// break;
// case "analysis.navigation":
// case ANALYSIS_NOTIFICATION_NAVIGATION:
// outOfTestExpect(params, isAnalysisNavigationParams);
// _onAnalysisNavigation.add(
// new AnalysisNavigationParams.fromJson(decoder, 'params', params));
// break;
// case "analysis.occurrences":
// case ANALYSIS_NOTIFICATION_OCCURRENCES:
// outOfTestExpect(params, isAnalysisOccurrencesParams);
// _onAnalysisOccurrences.add(
// new AnalysisOccurrencesParams.fromJson(decoder, 'params', params));
// break;
// case "analysis.outline":
// case ANALYSIS_NOTIFICATION_OUTLINE:
// outOfTestExpect(params, isAnalysisOutlineParams);
// _onAnalysisOutline
// .add(new AnalysisOutlineParams.fromJson(decoder, 'params', params));
// break;
// case "analysis.overrides":
// case ANALYSIS_NOTIFICATION_OVERRIDES:
// outOfTestExpect(params, isAnalysisOverridesParams);
// _onAnalysisOverrides.add(
// new AnalysisOverridesParams.fromJson(decoder, 'params', params));
// break;
// case "completion.results":
// case COMPLETION_NOTIFICATION_RESULTS:
// outOfTestExpect(params, isCompletionResultsParams);
// _onCompletionResults.add(
// new CompletionResultsParams.fromJson(decoder, 'params', params));
// break;
// case "search.results":
// case SEARCH_NOTIFICATION_RESULTS:
// outOfTestExpect(params, isSearchResultsParams);
// _onSearchResults
// .add(new SearchResultsParams.fromJson(decoder, 'params', params));
// break;
// case "execution.launchData":
// case EXECUTION_NOTIFICATION_LAUNCH_DATA:
// outOfTestExpect(params, isExecutionLaunchDataParams);
// _onExecutionLaunchData.add(
// new ExecutionLaunchDataParams.fromJson(decoder, 'params', params));
// break;
// case "flutter.outline":
// case FLUTTER_NOTIFICATION_OUTLINE:
// outOfTestExpect(params, isFlutterOutlineParams);
// _onFlutterOutline
// .add(new FlutterOutlineParams.fromJson(decoder, 'params', params));
Expand All @@ -185,6 +207,9 @@ class Driver {
if (errors.isNotEmpty) {
outSink.writeln(params.file);
for (AnalysisError error in errors) {
if (error.severity == AnalysisErrorSeverity.ERROR) {
++errorCount;
}
Location loc = error.location;
outSink.writeln(' ${error.message}'
' at ${loc.startLine}:${loc.startColumn}');
Expand Down
16 changes: 11 additions & 5 deletions pkg/analyzer_cli/lib/src/fix/server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,20 @@ class Server {
* upward to the 'test' dir, and then going up one more directory.
*/
String findRoot(String pathname) {
while (!['benchmark', 'test'].contains(basename(pathname))) {
while (true) {
String parent = dirname(pathname);
if (parent.length >= pathname.length) {
throw new Exception("Can't find root directory");
}
String name = basename(pathname);
if (['benchmark', 'test'].contains(name)) {
return parent;
}
if (name == 'pkg') {
return join(pathname, 'analysis_server');
}
pathname = parent;
}
return dirname(pathname);
}

/**
Expand Down Expand Up @@ -223,18 +229,18 @@ class Server {
String sdkPath,
int servicesPort,
bool useAnalysisHighlight2: false,
bool useSnapshot: true,
}) async {
if (_process != null) {
throw new Exception('Process already started');
}
_time.start();
String dartBinary = Platform.executable;

// The integration tests run 3x faster when run from snapshots (you need to
// run test.py with --use-sdk).
final bool useSnapshot = true;
String serverPath;

// The integration tests run 3x faster when run from snapshots (you need to
// run test.py with --use-sdk).
if (useSnapshot) {
// Look for snapshots/analysis_server.dart.snapshot.
serverPath = normalize(join(dirname(Platform.resolvedExecutable),
Expand Down

0 comments on commit a0ff5f8

Please sign in to comment.