diff --git a/pkg/analysis_server/bin/dartdeps.dart b/pkg/analysis_server/bin/dartdeps.dart deleted file mode 100644 index 8b6ad68601c..00000000000 --- a/pkg/analysis_server/bin/dartdeps.dart +++ /dev/null @@ -1,183 +0,0 @@ -// 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 'dart:async'; -import 'dart:io'; - -import 'package:analysis_server/src/analysis_manager.dart'; -import 'package:args/args.dart'; - -/** - * Start analysis server as a separate process and use the websocket protocol - * to analyze the application specified on the command line. - */ -void main(List args) { - new _DartDependencyAnalyzer(args).run().catchError((error, stack) { - print('Analysis failed: $error'); - if (stack != null) { - print(stack); - } - }); -} - -/** - * Instances of [_DartDependencyAnalyzer] launch an analysis server and use - * that server to analyze the dependencies of an application. - */ -class _DartDependencyAnalyzer { - /** - * The name of the application that is used to start the dependency analyzer. - */ - static const BINARY_NAME = 'dartdeps'; - - /** - * The name of the option used to specify the Dart SDK. - */ - static const String DART_SDK_OPTION = 'dart-sdk'; - - /** - * The name of the option used to print usage information. - */ - static const String HELP_OPTION = 'help'; - - /** - * The name of the option used to specify an already running server. - */ - static const String SERVER_OPTION = 'server'; - - /** - * The command line arguments. - */ - final List args; - - /** - * The path to the Dart SDK used during analysis. - */ - String sdkPath; - - /** - * The manager for the analysis server. - */ - AnalysisManager manager; - - _DartDependencyAnalyzer(this.args); - - /** - * Use the given manager to perform the analysis. - */ - void analyze(AnalysisManager manager) { - if (manager == null) { - return; - } - this.manager = manager; - print('Analyzing...'); - } - - /** - * Print information about how to use the server. - */ - void printUsage(ArgParser parser) { - print('Usage: $BINARY_NAME [flags] '); - print(''); - print('Supported flags are:'); - print(parser.usage); - } - - /** - * Parse the command line arguments to determine the application to be - * analyzed, then launch and manage an analysis server to do the work. - */ - Future run() { - return new Future(start).then(analyze).whenComplete(stop); - } - - /** - * Parse the command line arguments to determine the application to be - * analyzed, then launch an analysis server. - * Return `null` if the command line arguments are invalid. - */ - Future start() { - ArgParser parser = new ArgParser(); - parser.addOption(DART_SDK_OPTION, help: '[sdkPath] path to Dart SDK'); - parser.addFlag( - HELP_OPTION, - help: 'print this help message without starting analysis', - defaultsTo: false, - negatable: false); - parser.addOption( - SERVER_OPTION, - help: '[serverUrl] use an analysis server thats already running'); - - // Parse arguments - ArgResults results; - try { - results = parser.parse(args); - } on FormatException catch (e) { - print(e.message); - print(''); - printUsage(parser); - exitCode = 1; - return null; - } - if (results[HELP_OPTION]) { - printUsage(parser); - return null; - } - sdkPath = results[DART_SDK_OPTION]; - if (sdkPath is! String) { - print('Missing path to Dart SDK'); - printUsage(parser); - return null; - } - Directory sdkDir = new Directory(sdkPath); - if (!sdkDir.existsSync()) { - print('Specified Dart SDK does not exist: $sdkPath'); - printUsage(parser); - return null; - } - if (results.rest.length == 0) { - printUsage(parser); - exitCode = 1; - return null; - } - Directory appDir = new Directory(results.rest[0]); - if (!appDir.existsSync()) { - print('Specified application directory does not exist: $appDir'); - print(''); - printUsage(parser); - exitCode = 1; - return null; - } - if (results.rest.length > 1) { - print('Unexpected arguments after $appDir'); - print(''); - printUsage(parser); - exitCode = 1; - return null; - } - - // Connect to an already running analysis server - String serverUrl = results[SERVER_OPTION]; - if (serverUrl != null) { - return AnalysisManager.connect(serverUrl); - } - - // Launch and connect to a new analysis server - // Assume that the analysis server entry point is in the same directory - StringBuffer path = new StringBuffer(); - path.write(FileSystemEntity.parentOf(Platform.script.toFilePath())); - path.write(Platform.pathSeparator); - path.write('server.dart'); - return AnalysisManager.start(path.toString()); - } - - /** - * Stop the analysis server. - */ - void stop() { - if (manager != null) { - manager.stop(); - } - } -} diff --git a/pkg/analysis_server/bin/fuzz.dart b/pkg/analysis_server/bin/fuzz.dart deleted file mode 100644 index 49bdd1d6ad8..00000000000 --- a/pkg/analysis_server/bin/fuzz.dart +++ /dev/null @@ -1,171 +0,0 @@ -// 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 'dart:async'; -import 'dart:io'; - -import 'package:args/args.dart'; -import 'package:matcher/matcher.dart'; -import 'package:path/path.dart' as path; - -import 'fuzz/server_manager.dart'; - -/** - * Start analysis server as a separate process and use the stdio to communicate - * with the server. - */ -void main(List args) { - new _FuzzTest().run(args); -} - -/** - * Instances of [_FuzzTest] launch and test an analysis server. - * You must specify the location of the Dart SDK and the directory - * containing sources to be analyzed. - */ -class _FuzzTest { - /** - * The name of the application that is used to start the fuzz tester. - */ - static const BINARY_NAME = 'fuzz'; - - //TODO (danrubel) extract common behavior for use in multiple test scenarios - //TODO (danrubel) cleanup test to use async/await for better readability - // VM flag --enable_async - - static const String DART_SDK_OPTION = 'dart-sdk'; - static const String HELP_OPTION = 'help'; - - File serverSnapshot; - Directory appDir; - - /// Parse the arguments and initialize the receiver - /// Return `true` if proper arguments were provided - bool parseArgs(List args) { - ArgParser parser = new ArgParser(); - - void error(String errMsg) { - stderr.writeln(errMsg); - print(''); - _printUsage(parser); - exitCode = 11; - } - - parser.addOption(DART_SDK_OPTION, help: '[sdkPath] path to Dart SDK'); - parser.addFlag( - HELP_OPTION, - help: 'print this help message without starting analysis', - defaultsTo: false, - negatable: false); - - ArgResults results; - try { - results = parser.parse(args); - } on FormatException catch (e) { - error(e.message); - return false; - } - if (results[HELP_OPTION]) { - _printUsage(parser); - return false; - } - String sdkPath = results[DART_SDK_OPTION]; - if (sdkPath is! String) { - error('Missing path to Dart SDK'); - return false; - } - Directory sdkDir = new Directory(sdkPath); - if (!sdkDir.existsSync()) { - error('Specified Dart SDK does not exist: $sdkPath'); - return false; - } - if (results.rest.length == 0) { - error('Expected directory to analyze'); - return false; - } - appDir = new Directory(results.rest[0]); - if (!appDir.existsSync()) { - error('Specified application directory does not exist: $appDir'); - return false; - } - if (results.rest.length > 1) { - error('Unexpected arguments after $appDir'); - return false; - } - serverSnapshot = new File( - path.join(sdkDir.path, 'bin', 'snapshots', 'analysis_server.dart.snapshot')); - if (!serverSnapshot.existsSync()) { - error('Analysis Server snapshot not found: $serverSnapshot'); - return false; - } - return true; - } - - /// Main entry point for launching, testing, and shutting down the server - void run(List args) { - if (!parseArgs(args)) return; - ServerManager.start(serverSnapshot.path).then((ServerManager manager) { - runZoned(() { - test(manager).then(manager.stop).then((_) { - expect(manager.errorOccurred, isFalse); - print('Test completed successfully'); - }); - }, onError: (error, stack) { - stderr.writeln(error); - print(stack); - exitCode = 12; - manager.stop(); - }); - }); - } - - /// Use manager to exercise the analysis server - Future test(ServerManager manager) { - - // perform initial analysis - return manager.analyze(appDir).then((AnalysisResults analysisResults) { - print( - 'Found ${analysisResults.errorCount} errors,' - ' ${analysisResults.warningCount} warnings,' - ' and ${analysisResults.hintCount} hints in ${analysisResults.elapsed}'); - - // edit a method body - return manager.openFileNamed( - 'domain_completion.dart').then((Editor editor) { - return editor.moveAfter('Response processRequest(Request request) {'); - }).then((Editor editor) { - return editor.replace(0, '\nOb'); - }).then((Editor editor) { - - // request code completion and assert results - return editor.getSuggestions().then((List list) { - expect(list, isNotNull); - expect(list.length, equals(0)); - list.forEach((CompletionResults results) { - print( - '${results.elapsed} received ${results.suggestionCount} suggestions'); - }); - return editor; - }); - - }).then((Editor editor) { - print('tests complete'); - }); - }); - } - -// void _printAnalysisSummary(AnalysisResults results) { -// print( -// 'Found ${results.errorCount} errors, ${results.warningCount} warnings,' -// ' and ${results.hintCount} hints in $results.elapsed'); -// } - - /// Print information about how to use the server. - void _printUsage(ArgParser parser) { - print('Usage: $BINARY_NAME [flags] '); - print(''); - print('Supported flags are:'); - print(parser.usage); - } -} diff --git a/pkg/analysis_server/bin/fuzz/README.txt b/pkg/analysis_server/bin/fuzz/README.txt deleted file mode 100644 index f8d8a44c277..00000000000 --- a/pkg/analysis_server/bin/fuzz/README.txt +++ /dev/null @@ -1,9 +0,0 @@ -This directory contains code for fuzz testing the analysis server -and for generating timing information for tracking server performance. - -Run: -Launch fuzz.dart located in the parent directory. - -Overview: -fuzz.dart - main entry point and simple example of exercizing server -server_manager.dart - provides high level API for launching and driving server diff --git a/pkg/analysis_server/bin/fuzz/logging_client_channel.dart b/pkg/analysis_server/bin/fuzz/logging_client_channel.dart deleted file mode 100644 index 941646dc43b..00000000000 --- a/pkg/analysis_server/bin/fuzz/logging_client_channel.dart +++ /dev/null @@ -1,85 +0,0 @@ -// 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. - -part of server.manager; - -/** - * A client channel that logs communication to stdout - * and handles errors received from the server. - */ -class LoggingClientChannel implements ClientCommunicationChannel { - final ClientCommunicationChannel channel; - int serverErrorCount = 0; - - LoggingClientChannel(this.channel) { - channel.notificationStream.listen((Notification notification) { - _logNotification(notification); - if (notification.event == 'server.error') { - ServerErrorParams error = - new ServerErrorParams.fromNotification(notification); - _handleError( - 'Server reported error: ${error.message}', - error.stackTrace); - } - }); - } - - @override - Stream get notificationStream => channel.notificationStream; - - @override - void set notificationStream(Stream _notificationStream) { - throw 'invalid operation'; - } - - @override - Stream get responseStream => channel.responseStream; - - @override - void set responseStream(Stream _responseStream) { - throw 'invalid operation'; - } - - @override - Future close() { - print('Requesting client channel be closed'); - return channel.close().then((_) { - print('Client channel closed'); - }); - } - - @override - Future sendRequest(Request request) { - _logOperation('=>', request); - return channel.sendRequest(request).then((Response response) { - RequestError error = response.error; - if (error != null) { - error.code; - stderr.write('Server Error ${error.code}: ${error.message}'); - print(error.stackTrace); - exitCode = 31; - } - _logOperation('<=', request); - return response; - }); - } - - void _handleError(String errMsg, String stackTrace) { - //error.isFatal; - stderr.writeln('>>> Server reported exception'); - stderr.writeln(errMsg); - print(stackTrace); - serverErrorCount++; - } - - void _logNotification(Notification notification) { - print('<= ${notification.event}'); - } - - void _logOperation(String direction, Request request) { - String id = request.id.padLeft(5); - String method = request.method.padRight(20); - print('$direction $id $method'); - } -} diff --git a/pkg/analysis_server/bin/fuzz/server_manager.dart b/pkg/analysis_server/bin/fuzz/server_manager.dart deleted file mode 100644 index e9dcf24d810..00000000000 --- a/pkg/analysis_server/bin/fuzz/server_manager.dart +++ /dev/null @@ -1,365 +0,0 @@ -// 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. - -library server.manager; - -import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; - -import 'package:matcher/matcher.dart'; -import 'package:analysis_server/src/protocol.dart'; -import 'package:analysis_server/src/channel/channel.dart'; -import 'package:analysis_server/src/channel/byte_stream_channel.dart'; - -part 'logging_client_channel.dart'; - -/** - * The results returned by [ServerManager].analyze(...) once analysis - * has finished. - */ -class AnalysisResults { - Duration elapsed; - int errorCount = 0; - int hintCount = 0; - int warningCount = 0; -} - - -/** - * [CompletionResults] contains the completion results returned by the server - * along with the elapse time to receive those completions. - */ -class CompletionResults { - final Duration elapsed; - final CompletionResultsParams params; - - CompletionResults(this.elapsed, this.params); - - int get suggestionCount => params.results.length; -} - -/** - * [Editor] is a virtual editor for inspecting and modifying a file's content - * and updating the server with those modifications. - */ -class Editor { - final ServerManager manager; - final File file; - int offset = 0; - String _content = null; - - Editor(this.manager, this.file); - - /// Return a future that returns the file content - Future get content { - if (_content != null) { - return new Future.value(_content); - } - return file.readAsString().then((String content) { - _content = content; - return _content; - }); - } - - /** - * Request completion suggestions from the server. - * Return a future that completes with the completions sent. - */ - Future> getSuggestions() { - Request request = new CompletionGetSuggestionsParams( - file.path, - offset).toRequest(manager._nextRequestId); - Stopwatch stopwatch = new Stopwatch()..start(); - return manager.channel.sendRequest(request).then((Response response) { - String completionId = - new CompletionGetSuggestionsResult.fromResponse(response).id; - var completer = new Completer>(); - List results = []; - - // Listen for completion suggestions - StreamSubscription subscription; - subscription = - manager.channel.notificationStream.listen((Notification notification) { - if (notification.event == 'completion.results') { - CompletionResultsParams params = - new CompletionResultsParams.fromNotification(notification); - if (params.id == completionId) { - results.add(new CompletionResults(stopwatch.elapsed, params)); - if (params.isLast) { - stopwatch.stop(); - subscription.cancel(); - completer.complete(results); - } - } - } - }); - - return completer.future; - }); - } - - /** - * Move the virtual cursor after the given pattern in the source. - * Return a future that completes once the cursor has been moved. - */ - Future moveAfter(String pattern) { - return content.then((String content) { - offset = content.indexOf(pattern); - return this; - }); - } - - /** - * Replace the specified number of characters at the current cursor location - * with the given text, but do not save that content to disk. - * Return a future that completes once the server has been notified. - */ - Future replace(int replacementLength, String text) { - return content.then((String oldContent) { - StringBuffer sb = new StringBuffer(); - sb.write(oldContent.substring(0, offset)); - sb.write(text); - sb.write(oldContent.substring(offset)); - _content = sb.toString(); - SourceEdit sourceEdit = new SourceEdit(offset, replacementLength, text); - Request request = new AnalysisUpdateContentParams({ - file.path: new ChangeContentOverlay([sourceEdit]) - }).toRequest(manager._nextRequestId); - offset += text.length; - return manager.channel.sendRequest(request).then((Response response) { - return this; - }); - }); - } -} - -/** - * [ServerManager] is used to launch and manage an analysis server - * running in a separate process. - */ -class ServerManager { - - /** - * The analysis server process being managed or `null` if not started. - */ - Process process; - - /** - * The root directory containing the Dart source files to be analyzed. - */ - Directory appDir; - - /** - * The channel used to communicate with the analysis server. - */ - LoggingClientChannel _channel; - - /** - * The identifier used in the most recent request to the server. - * See [_nextRequestId]. - */ - int _lastRequestId = 0; - - /** - * `true` if a server exception was detected on stderr as opposed to an - * exception that the server reported via the server.error notification. - */ - bool _unreportedServerException = false; - - /** - * `true` if the [stop] method has been called. - */ - bool _stopRequested = false; - - /** - * Return the channel used to communicate with the analysis server. - */ - ClientCommunicationChannel get channel => _channel; - - /** - * Return `true` if a server error occurred. - */ - bool get errorOccurred => - _unreportedServerException || (_channel.serverErrorCount > 0); - - String get _nextRequestId => (++_lastRequestId).toString(); - - /** - * Direct the server to analyze all sources in the given directory, - * all sub directories recursively, and any source referenced sources - * outside this directory hierarch such as referenced packages. - * Return a future that completes when the analysis is finished. - */ - Future analyze(Directory appDir) { - this.appDir = appDir; - Stopwatch stopwatch = new Stopwatch()..start(); - Request request = new AnalysisSetAnalysisRootsParams( - [appDir.path], - []).toRequest(_nextRequestId); - - // Request analysis - return channel.sendRequest(request).then((Response response) { - AnalysisResults results = new AnalysisResults(); - StreamSubscription subscription; - Completer completer = new Completer(); - subscription = - channel.notificationStream.listen((Notification notification) { - - // Gather analysis results - if (notification.event == 'analysis.errors') { - AnalysisErrorsParams params = - new AnalysisErrorsParams.fromNotification(notification); - params.errors.forEach((AnalysisError error) { - AnalysisErrorSeverity severity = error.severity; - if (severity == AnalysisErrorSeverity.ERROR) { - results.errorCount += 1; - } else if (severity == AnalysisErrorSeverity.WARNING) { - results.warningCount += 1; - } else if (severity == AnalysisErrorSeverity.INFO) { - results.hintCount += 1; - } else { - print('Unknown error severity: ${severity.name}'); - } - }); - } - - // Stop gathering once analysis is complete - if (notification.event == 'server.status') { - ServerStatusParams status = - new ServerStatusParams.fromNotification(notification); - AnalysisStatus analysis = status.analysis; - if (analysis != null && !analysis.isAnalyzing) { - stopwatch.stop(); - results.elapsed = stopwatch.elapsed; - subscription.cancel(); - completer.complete(results); - } - } - }); - return completer.future; - }); - } - - /** - * Send a request to the server for its version information - * and return a future that completes with the result. - */ - Future getVersion() { - Request request = new ServerGetVersionParams().toRequest(_nextRequestId); - return channel.sendRequest(request).then((Response response) { - return new ServerGetVersionResult.fromResponse(response); - }); - } - - /** - * Notify the server that the given file will be edited. - * Return a virtual editor for inspecting and modifying the file's content. - */ - Future openFileNamed(String fileName) { - return _findFile(fileName, appDir).then((File file) { - if (file == null) { - throw 'Failed to find file named $fileName in ${appDir.path}'; - } - file = file.absolute; - Request request = - new AnalysisSetPriorityFilesParams([file.path]).toRequest(_nextRequestId); - return channel.sendRequest(request).then((Response response) { - return new Editor(this, file); - }); - }); - } - - /** - * Send a request for notifications. - * Return when the server has acknowledged that request. - */ - Future setSubscriptions() { - Request request = new ServerSetSubscriptionsParams( - [ServerService.STATUS]).toRequest(_nextRequestId); - return channel.sendRequest(request); - } - - /** - * Stop the analysis server. - * Return a future that completes when the server is terminated. - */ - Future stop([_]) { - _stopRequested = true; - print("Requesting server shutdown"); - Request request = new ServerShutdownParams().toRequest(_nextRequestId); - Duration waitTime = new Duration(seconds: 5); - return channel.sendRequest(request).timeout(waitTime, onTimeout: () { - print('Expected shutdown response'); - }).then((Response response) { - return channel.close().then((_) => process.exitCode); - }).timeout(new Duration(seconds: 2), onTimeout: () { - print('Expected server to shutdown'); - process.kill(); - }); - } - - /** - * Locate the given file in the directory tree. - */ - Future _findFile(String fileName, Directory appDir) { - return appDir.list(recursive: true).firstWhere((FileSystemEntity entity) { - return entity is File && entity.path.endsWith(fileName); - }); - } - - /** - * Launch an analysis server and open a connection to that server. - */ - Future _launchServer(String pathToServer) { - List serverArgs = [pathToServer]; - return Process.start(Platform.executable, serverArgs).catchError((error) { - exitCode = 21; - throw 'Failed to launch analysis server: $error'; - }).then((Process process) { - this.process = process; - _channel = new LoggingClientChannel( - new ByteStreamClientChannel(process.stdout, process.stdin)); - - // simple out of band exception handling - process.stderr.transform( - new Utf8Codec().decoder).transform(new LineSplitter()).listen((String line) { - if (!_unreportedServerException) { - _unreportedServerException = true; - stderr.writeln('>>> Unreported server exception'); - } - stderr.writeln('server.stderr: $line'); - }); - - // watch for unexpected process termination and catch the exit code - process.exitCode.then((int code) { - if (!_stopRequested) { - fail('Unexpected server termination: $code'); - } - if (code != null && code != 0) { - exitCode = code; - } - print('Server stopped: $code'); - }); - - return channel.notificationStream.first.then((Notification notification) { - print('Server connection established'); - return setSubscriptions().then((_) { - return getVersion().then((ServerGetVersionResult result) { - print('Server version ${result.version}'); - return this; - }); - }); - }); - }); - } - - /** - * Launch analysis server in a separate process - * and return a future with a manager for that analysis server. - */ - static Future start(String serverPath) { - return new ServerManager()._launchServer(serverPath); - } -} diff --git a/pkg/analysis_server/bin/server.dart b/pkg/analysis_server/bin/server.dart index 84b770210cc..f0d075f6f8d 100644 --- a/pkg/analysis_server/bin/server.dart +++ b/pkg/analysis_server/bin/server.dart @@ -2,12 +2,12 @@ // 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/driver.dart'; +import 'package:analysis_server/starter.dart'; /** - * Create and run an HTTP-based analysis server. + * Create and run an analysis server. */ void main(List args) { - Driver driver = new Driver(); - driver.start(args); + ServerStarter starter = new ServerStarter(); + starter.start(args); } diff --git a/pkg/analysis_server/lib/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart similarity index 94% rename from pkg/analysis_server/lib/driver.dart rename to pkg/analysis_server/lib/src/server/driver.dart index 9018541abb8..18e1cefbfea 100644 --- a/pkg/analysis_server/lib/driver.dart +++ b/pkg/analysis_server/lib/src/server/driver.dart @@ -7,13 +7,14 @@ library driver; import 'dart:async'; import 'dart:io'; -import 'package:analysis_server/http_server.dart'; import 'package:analysis_server/plugin/plugin.dart'; import 'package:analysis_server/src/analysis_server.dart'; import 'package:analysis_server/src/plugin/plugin_impl.dart'; import 'package:analysis_server/src/plugin/server_plugin.dart'; +import 'package:analysis_server/src/server/http_server.dart'; +import 'package:analysis_server/src/server/stdio_server.dart'; import 'package:analysis_server/src/socket_server.dart'; -import 'package:analysis_server/stdio_server.dart'; +import 'package:analysis_server/starter.dart'; import 'package:analyzer/instrumentation/instrumentation.dart'; import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/generated/incremental_logger.dart'; @@ -54,7 +55,7 @@ void _initIncrementalLogger(String spec) { * server application. It is responsible for parsing command line options * and starting the HTTP and/or stdio servers. */ -class Driver { +class Driver implements ServerStarter { /** * The name of the application that is used to start a server. */ @@ -144,53 +145,11 @@ class Driver { } /** - * Use the given command-line arguments to start this server. + * Use the given command-line [arguments] to start this server. */ - void start(List args) { - ArgParser parser = new ArgParser(); - parser.addOption( - CLIENT_ID, - help: "an identifier used to identify the client"); - parser.addFlag( - ENABLE_INCREMENTAL_RESOLUTION_API, - help: "enable using incremental resolution for API changes", - defaultsTo: false, - negatable: false); - parser.addFlag( - ENABLE_INSTRUMENTATION_OPTION, - help: "enable sending instrumentation information to a server", - defaultsTo: false, - negatable: false); - parser.addFlag( - HELP_OPTION, - help: "print this help message without starting a server", - defaultsTo: false, - negatable: false); - parser.addOption( - INCREMENTAL_RESOLUTION_LOG, - help: "the description of the incremental resolution log"); - parser.addFlag( - INCREMENTAL_RESOLUTION_VALIDATION, - help: "enable validation of incremental resolution results (slow)", - defaultsTo: false, - negatable: false); - parser.addFlag( - INTERNAL_PRINT_TO_CONSOLE, - help: "enable sending `print` output to the console", - defaultsTo: false, - negatable: false); - parser.addOption( - PORT_OPTION, - help: "[port] the port on which the server will listen"); - parser.addOption(SDK_OPTION, help: "[path] the path to the sdk"); - parser.addFlag( - NO_ERROR_NOTIFICATION, - help: - "disable sending all analysis error notifications to the server (not yet implemented)", - defaultsTo: false, - negatable: false); - - ArgResults results = parser.parse(args); + void start(List arguments) { + ArgParser parser = _createArgParser(); + ArgResults results = parser.parse(arguments); if (results[HELP_OPTION]) { _printUsage(parser); return; @@ -309,6 +268,56 @@ class Driver { return runZoned(callback, zoneSpecification: zoneSpecification); } + /** + * Create and return the parser used to parse the command-line arguments. + */ + ArgParser _createArgParser() { + ArgParser parser = new ArgParser(); + parser.addOption( + CLIENT_ID, + help: "an identifier used to identify the client"); + parser.addFlag( + ENABLE_INCREMENTAL_RESOLUTION_API, + help: "enable using incremental resolution for API changes", + defaultsTo: false, + negatable: false); + parser.addFlag( + ENABLE_INSTRUMENTATION_OPTION, + help: "enable sending instrumentation information to a server", + defaultsTo: false, + negatable: false); + parser.addFlag( + HELP_OPTION, + help: "print this help message without starting a server", + defaultsTo: false, + negatable: false); + parser.addOption( + INCREMENTAL_RESOLUTION_LOG, + help: "the description of the incremental resolution log"); + parser.addFlag( + INCREMENTAL_RESOLUTION_VALIDATION, + help: "enable validation of incremental resolution results (slow)", + defaultsTo: false, + negatable: false); + parser.addFlag( + INTERNAL_PRINT_TO_CONSOLE, + help: "enable sending `print` output to the console", + defaultsTo: false, + negatable: false); + parser.addOption( + PORT_OPTION, + help: "[port] the port on which the server will listen"); + parser.addOption(SDK_OPTION, help: "[path] the path to the sdk"); + parser.addFlag( + NO_ERROR_NOTIFICATION, + help: + "disable sending all analysis error notifications to the server (not yet implemented)", + defaultsTo: false, + negatable: false); + + return parser; + } + /** * Print information about how to use the server. */ diff --git a/pkg/analysis_server/lib/http_server.dart b/pkg/analysis_server/lib/src/server/http_server.dart similarity index 100% rename from pkg/analysis_server/lib/http_server.dart rename to pkg/analysis_server/lib/src/server/http_server.dart diff --git a/pkg/analysis_server/lib/stdio_server.dart b/pkg/analysis_server/lib/src/server/stdio_server.dart similarity index 100% rename from pkg/analysis_server/lib/stdio_server.dart rename to pkg/analysis_server/lib/src/server/stdio_server.dart diff --git a/pkg/analysis_server/lib/starter.dart b/pkg/analysis_server/lib/starter.dart new file mode 100644 index 00000000000..9483fffa122 --- /dev/null +++ b/pkg/analysis_server/lib/starter.dart @@ -0,0 +1,34 @@ +// 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 driver; + +import 'package:analysis_server/plugin/plugin.dart'; +import 'package:analysis_server/src/server/driver.dart'; +import 'package:analyzer/instrumentation/instrumentation.dart'; + +/** + * An object that can be used to start an analysis server. + */ +abstract class ServerStarter { + /** + * Initialize a newly created starter to start up an analysis server. + */ + factory ServerStarter() = Driver; + + /** + * Set the instrumentation [server] that is to be used by the analysis server. + */ + void set instrumentationServer(InstrumentationServer server); + + /** + * Set the [plugins] that are defined outside the analysis_server package. + */ + void set userDefinedPlugins(List plugins); + + /** + * Use the given command-line [arguments] to start this server. + */ + void start(List arguments); +}