blob: 4e227b4184ee6ea98a57dc41720d5e5206423c4f [file] [log] [blame]
// 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 analysis_server.src.plugin.server_plugin;
import 'package:analysis_server/analysis/analysis_domain.dart';
import 'package:analysis_server/analysis/index_core.dart';
import 'package:analysis_server/analysis/navigation_core.dart';
import 'package:analysis_server/analysis/occurrences_core.dart';
import 'package:analysis_server/edit/assist/assist_core.dart';
import 'package:analysis_server/edit/fix/fix_core.dart';
import 'package:analysis_server/plugin/analyzed_files.dart';
import 'package:analysis_server/plugin/assist.dart';
import 'package:analysis_server/plugin/fix.dart';
import 'package:analysis_server/plugin/index.dart';
import 'package:analysis_server/plugin/navigation.dart';
import 'package:analysis_server/plugin/occurrences.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_analysis.dart';
import 'package:analysis_server/src/domain_completion.dart';
import 'package:analysis_server/src/domain_execution.dart';
import 'package:analysis_server/src/domain_server.dart';
import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
import 'package:analysis_server/src/domains/analysis/occurrences_dart.dart';
import 'package:analysis_server/src/edit/edit_domain.dart';
import 'package:analysis_server/src/protocol.dart';
import 'package:analysis_server/src/provisional/completion/completion_core.dart';
import 'package:analysis_server/src/search/search_domain.dart';
import 'package:analysis_server/src/services/correction/assist_internal.dart';
import 'package:analysis_server/src/services/correction/fix_internal.dart';
import 'package:analysis_server/src/services/index/index_contributor.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:plugin/plugin.dart';
/**
* A function that will create a request handler that can be used by the given
* [server].
*/
typedef RequestHandler RequestHandlerFactory(AnalysisServer server);
/**
* A plugin that defines the extension points and extensions that are inherently
* defined by the analysis server.
*/
class ServerPlugin implements Plugin {
/**
* The simple identifier of the extension point that allows plugins to
* register functions that can cause files to be analyzed.
*/
static const String ANALYZE_FILE_EXTENSION_POINT = 'analyzeFile';
/**
* The simple identifier of the extension point that allows plugins to
* register assist contributors.
*/
static const String ASSIST_CONTRIBUTOR_EXTENSION_POINT = 'assistContributor';
/**
* The simple identifier of the extension point that allows plugins to
* register completion contributors.
*/
static const String COMPLETION_CONTRIBUTOR_EXTENSION_POINT =
'completionContributor';
/**
* The simple identifier of the extension point that allows plugins to
* register domains.
*/
static const String DOMAIN_EXTENSION_POINT = 'domain';
/**
* The simple identifier of the extension point that allows plugins to
* register fix contributors.
*/
static const String FIX_CONTRIBUTOR_EXTENSION_POINT = 'fixContributor';
/**
* The simple identifier of the extension point that allows plugins to
* register index contributors.
*/
static const String INDEX_CONTRIBUTOR_EXTENSION_POINT = 'indexContributor';
/**
* The simple identifier of the extension point that allows plugins to
* register navigation contributors.
*/
static const String NAVIGATION_CONTRIBUTOR_EXTENSION_POINT =
'navigationContributor';
/**
* The simple identifier of the extension point that allows plugins to
* register element occurrences.
*/
static const String OCCURRENCES_CONTRIBUTOR_EXTENSION_POINT =
'occurrencesContributor';
/**
* The simple identifier of the extension point that allows plugins to
* register analysis result listeners.
*/
static const String SET_ANALISYS_DOMAIN_EXTENSION_POINT = 'setAnalysisDomain';
/**
* The unique identifier of this plugin.
*/
static const String UNIQUE_IDENTIFIER = 'analysis_server.core';
/**
* The extension point that allows plugins to register functions that can
* cause files to be analyzed.
*/
ExtensionPoint analyzeFileExtensionPoint;
/**
* The extension point that allows plugins to register assist contributors.
*/
ExtensionPoint assistContributorExtensionPoint;
/**
* The extension point that allows plugins to register completion
* contributors.
*/
ExtensionPoint completionContributorExtensionPoint;
/**
* The extension point that allows plugins to register domains with the
* server.
*/
ExtensionPoint domainExtensionPoint;
/**
* The extension point that allows plugins to register fix contributors with
* the server.
*/
ExtensionPoint fixContributorExtensionPoint;
/**
* The extension point that allows plugins to register index contributors.
*/
ExtensionPoint indexContributorExtensionPoint;
/**
* The extension point that allows plugins to register navigation
* contributors.
*/
ExtensionPoint navigationContributorExtensionPoint;
/**
* The extension point that allows plugins to register occurrences
* contributors.
*/
ExtensionPoint occurrencesContributorExtensionPoint;
/**
* The extension point that allows plugins to get access to the `analysis`
* domain.
*/
ExtensionPoint setAnalysisDomainExtensionPoint;
/**
* Initialize a newly created plugin.
*/
ServerPlugin();
/**
* Return a list containing all of the functions that can cause files to be
* analyzed.
*/
List<ShouldAnalyzeFile> get analyzeFileFunctions =>
analyzeFileExtensionPoint.extensions;
/**
* Return a list containing all of the assist contributors that were
* contributed.
*/
List<AssistContributor> get assistContributors =>
assistContributorExtensionPoint.extensions;
/**
* Return a list containing all of the completion contributors that were
* contributed.
*/
List<CompletionContributor> get completionContributors =>
completionContributorExtensionPoint.extensions;
/**
* Return a list containing all of the fix contributors that were contributed.
*/
List<FixContributor> get fixContributors =>
fixContributorExtensionPoint.extensions;
/**
* Return a list containing all of the index contributors that were
* contributed.
*/
List<IndexContributor> get indexContributors =>
indexContributorExtensionPoint.extensions;
/**
* Return a list containing all of the navigation contributors that were
* contributed.
*/
List<NavigationContributor> get navigationContributors =>
navigationContributorExtensionPoint.extensions;
/**
* Return a list containing all of the occurrences contributors that were
* contributed.
*/
List<OccurrencesContributor> get occurrencesContributors =>
occurrencesContributorExtensionPoint.extensions;
/**
* Return a list containing all of the receivers of the `analysis` domain
* instance.
*/
List<SetAnalysisDomain> get setAnalysisDomainFunctions =>
setAnalysisDomainExtensionPoint.extensions;
@override
String get uniqueIdentifier => UNIQUE_IDENTIFIER;
/**
* Use the given [server] to create all of the domains ([RequestHandler]'s)
* that have been registered and return the newly created domains.
*/
List<RequestHandler> createDomains(AnalysisServer server) {
if (domainExtensionPoint == null) {
return <RequestHandler>[];
}
return domainExtensionPoint.extensions
.map((RequestHandlerFactory factory) => factory(server))
.toList();
}
@override
void registerExtensionPoints(RegisterExtensionPoint registerExtensionPoint) {
setAnalysisDomainExtensionPoint = registerExtensionPoint(
SET_ANALISYS_DOMAIN_EXTENSION_POINT,
_validateSetAnalysisDomainFunction);
analyzeFileExtensionPoint = registerExtensionPoint(
ANALYZE_FILE_EXTENSION_POINT, _validateAnalyzeFileExtension);
assistContributorExtensionPoint = registerExtensionPoint(
ASSIST_CONTRIBUTOR_EXTENSION_POINT,
_validateAssistContributorExtension);
completionContributorExtensionPoint = registerExtensionPoint(
COMPLETION_CONTRIBUTOR_EXTENSION_POINT,
_validateCompletionContributorExtension);
domainExtensionPoint = registerExtensionPoint(
DOMAIN_EXTENSION_POINT, _validateDomainExtension);
fixContributorExtensionPoint = registerExtensionPoint(
FIX_CONTRIBUTOR_EXTENSION_POINT, _validateFixContributorExtension);
indexContributorExtensionPoint = registerExtensionPoint(
INDEX_CONTRIBUTOR_EXTENSION_POINT, _validateIndexContributorExtension);
navigationContributorExtensionPoint = registerExtensionPoint(
NAVIGATION_CONTRIBUTOR_EXTENSION_POINT,
_validateNavigationContributorExtension);
occurrencesContributorExtensionPoint = registerExtensionPoint(
OCCURRENCES_CONTRIBUTOR_EXTENSION_POINT,
_validateOccurrencesContributorExtension);
}
@override
void registerExtensions(RegisterExtension registerExtension) {
//
// Register analyze file functions.
//
registerExtension(
ANALYZE_FILE_EXTENSION_POINT_ID,
(File file) => AnalysisEngine.isDartFileName(file.path) ||
AnalysisEngine.isHtmlFileName(file.path));
//
// Register assist contributors.
//
registerExtension(
ASSIST_CONTRIBUTOR_EXTENSION_POINT_ID, new DefaultAssistContributor());
//
// Register completion contributors.
//
// TODO(brianwilkerson) Register the completion contributors.
// registerExtension(COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID, ???);
//
// Register analysis contributors.
//
registerExtension(NAVIGATION_CONTRIBUTOR_EXTENSION_POINT_ID,
new DartNavigationComputer());
registerExtension(OCCURRENCES_CONTRIBUTOR_EXTENSION_POINT_ID,
new DartOccurrencesComputer());
//
// Register domains.
//
String domainId = Plugin.join(UNIQUE_IDENTIFIER, DOMAIN_EXTENSION_POINT);
registerExtension(
domainId, (AnalysisServer server) => new ServerDomainHandler(server));
registerExtension(
domainId, (AnalysisServer server) => new AnalysisDomainHandler(server));
registerExtension(
domainId, (AnalysisServer server) => new EditDomainHandler(server));
registerExtension(
domainId, (AnalysisServer server) => new SearchDomainHandler(server));
registerExtension(domainId,
(AnalysisServer server) => new CompletionDomainHandler(server));
registerExtension(domainId,
(AnalysisServer server) => new ExecutionDomainHandler(server));
//
// Register fix contributors.
//
registerExtension(
FIX_CONTRIBUTOR_EXTENSION_POINT_ID, new DefaultFixContributor());
//
// Register index contributors.
//
registerExtension(
INDEX_CONTRIBUTOR_EXTENSION_POINT_ID, new DartIndexContributor());
}
/**
* Validate the given extension by throwing an [ExtensionError] if it is not a
* valid assist contributor.
*/
void _validateAnalyzeFileExtension(Object extension) {
if (extension is! ShouldAnalyzeFile) {
String id = analyzeFileExtensionPoint.uniqueIdentifier;
throw new ExtensionError(
'Extensions to $id must be a ShouldAnalyzeFile function');
}
}
/**
* Validate the given extension by throwing an [ExtensionError] if it is not a
* valid assist contributor.
*/
void _validateAssistContributorExtension(Object extension) {
if (extension is! AssistContributor) {
String id = assistContributorExtensionPoint.uniqueIdentifier;
throw new ExtensionError(
'Extensions to $id must be an AssistContributor');
}
}
/**
* Validate the given extension by throwing an [ExtensionError] if it is not a
* valid completion contributor.
*/
void _validateCompletionContributorExtension(Object extension) {
if (extension is! CompletionContributor) {
String id = completionContributorExtensionPoint.uniqueIdentifier;
throw new ExtensionError(
'Extensions to $id must be an CompletionContributor');
}
}
/**
* Validate the given extension by throwing an [ExtensionError] if it is not a
* valid domain.
*/
void _validateDomainExtension(Object extension) {
if (extension is! RequestHandlerFactory) {
String id = domainExtensionPoint.uniqueIdentifier;
throw new ExtensionError(
'Extensions to $id must be a RequestHandlerFactory');
}
}
/**
* Validate the given extension by throwing an [ExtensionError] if it is not a
* valid fix contributor.
*/
void _validateFixContributorExtension(Object extension) {
if (extension is! FixContributor) {
String id = fixContributorExtensionPoint.uniqueIdentifier;
throw new ExtensionError('Extensions to $id must be a FixContributor');
}
}
/**
* Validate the given extension by throwing an [ExtensionError] if it is not a
* valid index contributor.
*/
void _validateIndexContributorExtension(Object extension) {
if (extension is! IndexContributor) {
String id = indexContributorExtensionPoint.uniqueIdentifier;
throw new ExtensionError('Extensions to $id must be an IndexContributor');
}
}
/**
* Validate the given extension by throwing an [ExtensionError] if it is not a
* valid navigation contributor.
*/
void _validateNavigationContributorExtension(Object extension) {
if (extension is! NavigationContributor) {
String id = navigationContributorExtensionPoint.uniqueIdentifier;
throw new ExtensionError(
'Extensions to $id must be an NavigationContributor');
}
}
/**
* Validate the given extension by throwing an [ExtensionError] if it is not a
* valid occurrences contributor.
*/
void _validateOccurrencesContributorExtension(Object extension) {
if (extension is! OccurrencesContributor) {
String id = occurrencesContributorExtensionPoint.uniqueIdentifier;
throw new ExtensionError(
'Extensions to $id must be an OccurrencesContributor');
}
}
/**
* Validate the given extension by throwing an [ExtensionError] if it is not a
* valid analysis domain receiver.
*/
void _validateSetAnalysisDomainFunction(Object extension) {
if (extension is! SetAnalysisDomain) {
String id = setAnalysisDomainExtensionPoint.uniqueIdentifier;
throw new ExtensionError(
'Extensions to $id must be a SetAnalysisDomain function');
}
}
}