| Index: pkg/analysis_server/lib/src/context_manager.dart
|
| diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
|
| index 3e72ad50054c00c2ed03b97f0e3bea255cc94222..94792f4a0025f90727127183aad2e026cfba1b80 100644
|
| --- a/pkg/analysis_server/lib/src/context_manager.dart
|
| +++ b/pkg/analysis_server/lib/src/context_manager.dart
|
| @@ -9,6 +9,7 @@ import 'dart:collection';
|
| import 'dart:convert';
|
| import 'dart:core' hide Resource;
|
|
|
| +import 'package:analyzer/src/context/context.dart' as context;
|
| import 'package:analysis_server/plugin/analysis/resolver_provider.dart';
|
| import 'package:analysis_server/src/analysis_server.dart';
|
| import 'package:analysis_server/src/server_options.dart';
|
| @@ -311,6 +312,11 @@ abstract class ContextManagerCallbacks {
|
| */
|
| class ContextManagerImpl implements ContextManager {
|
| /**
|
| + * File name of analysis options files.
|
| + */
|
| + static const String ANALYSIS_OPTIONS_FILE = '.analysis_options';
|
| +
|
| + /**
|
| * Temporary flag to hide WIP .packages support (DEP 5).
|
| */
|
| static bool ENABLE_PACKAGESPEC_SUPPORT = serverOptions.isSet(
|
| @@ -466,31 +472,59 @@ class ContextManagerImpl implements ContextManager {
|
| /**
|
| * Process [options] for the given context [info].
|
| */
|
| - void processOptionsForContext(
|
| - ContextInfo info, Map<String, YamlNode> options) {
|
| - if (options == null) {
|
| + void processOptionsForContext(ContextInfo info, Folder folder,
|
| + {bool optionsRemoved: false}) {
|
| + Map<String, YamlNode> options;
|
| + try {
|
| + options = analysisOptionsProvider.getOptions(folder);
|
| + } catch (e, stacktrace) {
|
| + AnalysisEngine.instance.logger.logError(
|
| + 'Error processing .analysis_options',
|
| + new CaughtException(e, stacktrace));
|
| + // TODO(pquitslund): contribute plugin that sends error notification on
|
| + // options file.
|
| + // Related test:
|
| + // context_manager_test.test_analysis_options_parse_failure()
|
| + // AnalysisEngine.instance.optionsPlugin.optionsProcessors
|
| + // .forEach((OptionsProcessor p) => p.onError(e));
|
| + }
|
| +
|
| + if (options == null && !optionsRemoved) {
|
| return;
|
| }
|
|
|
| // Notify options processors.
|
| - AnalysisEngine.instance.optionsPlugin.optionsProcessors.forEach(
|
| - (OptionsProcessor p) => p.optionsProcessed(info.context, options));
|
| + AnalysisEngine.instance.optionsPlugin.optionsProcessors
|
| + .forEach((OptionsProcessor p) {
|
| + try {
|
| + p.optionsProcessed(info.context, options);
|
| + } catch (e, stacktrace) {
|
| + AnalysisEngine.instance.logger.logError(
|
| + 'Error processing .analysis_options',
|
| + new CaughtException(e, stacktrace));
|
| + }
|
| + });
|
| +
|
| + // In case options files are removed, revert to default options.
|
| + if (optionsRemoved) {
|
| + info.context.analysisOptions = new AnalysisOptionsImpl();
|
| + return;
|
| + }
|
|
|
| // Analysis options are processed 'in-line'.
|
| - // TODO(pq): consider pushing exclude handling into a plugin.
|
| YamlMap analyzer = options['analyzer'];
|
| if (analyzer == null) {
|
| // No options for analyzer.
|
| return;
|
| }
|
|
|
| - // Set strong mode.
|
| - var strongMode = analyzer['strong-mode'];
|
| - if (strongMode == true) {
|
| - AnalysisContext context = info.context;
|
| + // Set strong mode (default is false).
|
| + bool strongMode = analyzer['strong-mode'] ?? false;
|
| + AnalysisContext context = info.context;
|
| + if (context.analysisOptions.strongMode != strongMode) {
|
| AnalysisOptionsImpl options =
|
| new AnalysisOptionsImpl.from(context.analysisOptions);
|
| - options.strongMode = true;
|
| + options.strongMode = strongMode;
|
| context.analysisOptions = options;
|
| }
|
|
|
| @@ -844,21 +878,7 @@ class ContextManagerImpl implements ContextManager {
|
| info.context = callbacks.addContext(folder, disposition);
|
| info.context.name = folder.path;
|
|
|
| - try {
|
| - Map<String, YamlNode> options =
|
| - analysisOptionsProvider.getOptions(folder);
|
| - processOptionsForContext(info, options);
|
| - } catch (e, stacktrace) {
|
| - AnalysisEngine.instance.logger.logError(
|
| - 'Error processing .analysis_options',
|
| - new CaughtException(e, stacktrace));
|
| - // TODO(pquitslund): contribute plugin that sends error notification on
|
| - // options file.
|
| - // Related test:
|
| - // context_manager_test.test_analysis_options_parse_failure()
|
| - // AnalysisEngine.instance.optionsPlugin.optionsProcessors
|
| - // .forEach((OptionsProcessor p) => p.onError(e));
|
| - }
|
| + processOptionsForContext(info, folder);
|
|
|
| return info;
|
| }
|
| @@ -1161,9 +1181,21 @@ class ContextManagerImpl implements ContextManager {
|
| }
|
| break;
|
| }
|
| -
|
| - //TODO(pquitslund): find the right place for this
|
| _checkForPackagespecUpdate(path, info, info.folder);
|
| + _checkForAnalysisOptionsUpdate(path, info, event.type);
|
| + }
|
| +
|
| + void _checkForAnalysisOptionsUpdate(
|
| + String path, ContextInfo info, ChangeType changeType) {
|
| + if (pathContext.basename(path) == ANALYSIS_OPTIONS_FILE) {
|
| + var analysisContext = info.context;
|
| + if (analysisContext is context.AnalysisContextImpl) {
|
| + processOptionsForContext(info, info.folder,
|
| + optionsRemoved: changeType == ChangeType.REMOVE);
|
| + analysisContext.invalidateCachedResults();
|
| + callbacks.applyChangesToContext(info.folder, new ChangeSet());
|
| + }
|
| + }
|
| }
|
|
|
| /**
|
|
|