blob: c1ffb231e0eadcd4f7470d9d88e861a8950e09ae [file] [log] [blame]
// Copyright (c) 2020, 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/src/protocol_server.dart';
import 'package:analysis_server/src/services/completion/yaml/producer.dart';
import 'package:analysis_server/src/services/completion/yaml/yaml_completion_generator.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/lint/registry.dart';
import 'package:analyzer/src/task/options.dart';
/// A completion generator that can produce completion suggestions for analysis
/// options files.
class AnalysisOptionsGenerator extends YamlCompletionGenerator {
/// The producer representing the known valid structure of an analysis options
/// file.
// TODO(brianwilkerson) We need to support multiple valid formats.
// For example, the lint rules can either be a list or a map, but we only
// suggest list items.
static MapProducer analysisOptionsProducer = MapProducer({
AnalyzerOptions.analyzer: MapProducer({
AnalyzerOptions.enableExperiment: ListProducer(_ExperimentProducer()),
AnalyzerOptions.errors: _ErrorProducer(),
AnalyzerOptions.exclude: EmptyProducer(),
AnalyzerOptions.language: MapProducer({
AnalyzerOptions.strictCasts: EmptyProducer(),
AnalyzerOptions.strictInference: EmptyProducer(),
AnalyzerOptions.strictRawTypes: EmptyProducer(),
}),
AnalyzerOptions.optionalChecks: MapProducer({
AnalyzerOptions.chromeOsManifestChecks: EmptyProducer(),
}),
AnalyzerOptions.plugins: EmptyProducer(),
AnalyzerOptions.propagateLinterExceptions: EmptyProducer(),
AnalyzerOptions.strong_mode: MapProducer({
AnalyzerOptions.declarationCasts: EmptyProducer(),
AnalyzerOptions.implicitCasts: EmptyProducer(),
AnalyzerOptions.implicitDynamic: EmptyProducer(),
}),
}),
AnalyzerOptions.codeStyle: MapProducer({
AnalyzerOptions.format: BooleanProducer(),
}),
// TODO(brianwilkerson) Create a producer to produce `package:` URIs.
AnalyzerOptions.include: EmptyProducer(),
// TODO(brianwilkerson) Create constants for 'linter' and 'rules'.
'linter': MapProducer({
'rules': ListProducer(_LintRuleProducer()),
}),
});
/// Initialize a newly created suggestion generator for analysis options
/// files.
AnalysisOptionsGenerator(ResourceProvider resourceProvider)
: super(resourceProvider, null);
@override
Producer get topLevelProducer => analysisOptionsProducer;
}
class _ErrorProducer extends KeyValueProducer {
static const enumProducer = EnumProducer([
'ignore',
'info',
'warning',
'error',
]);
@override
Producer? producerForKey(String key) => enumProducer;
@override
Iterable<CompletionSuggestion> suggestions(
YamlCompletionRequest request) sync* {
for (var error in errorCodeValues) {
yield identifier('${error.name.toLowerCase()}: ');
}
for (var rule in Registry.ruleRegistry.rules) {
yield identifier('${rule.name}: ');
}
}
}
class _ExperimentProducer extends Producer {
/// Initialize a location whose valid values are the names of the known
/// experimental features.
const _ExperimentProducer();
@override
Iterable<CompletionSuggestion> suggestions(
YamlCompletionRequest request) sync* {
for (var feature in ExperimentStatus.knownFeatures.values) {
if (!feature.isEnabledByDefault) {
yield identifier(feature.enableString);
}
}
}
}
class _LintRuleProducer extends Producer {
/// Initialize a location whose valid values are the names of the registered
/// lint rules.
const _LintRuleProducer();
@override
Iterable<CompletionSuggestion> suggestions(
YamlCompletionRequest request) sync* {
for (var rule in Registry.ruleRegistry.rules) {
yield identifier(rule.name);
}
}
}