870aa5e4f4
Provides support for pubspec-specified analysis configurations. Context: https://github.com/dart-lang/sdk/issues/26359 TODO: * docs * CLI support BUG= R=brianwilkerson@google.com Review URL: https://codereview.chromium.org/1923973004 .
108 lines
3.8 KiB
Dart
108 lines
3.8 KiB
Dart
// Copyright (c) 2016, 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:analyzer/file_system/file_system.dart';
|
|
import 'package:analyzer/source/analysis_options_provider.dart';
|
|
import 'package:analyzer/src/generated/engine.dart';
|
|
import 'package:analyzer/src/task/model.dart';
|
|
import 'package:analyzer/task/model.dart';
|
|
import 'package:package_config/packages.dart';
|
|
import 'package:yaml/src/yaml_node.dart';
|
|
import 'package:yaml/yaml.dart';
|
|
|
|
/// The descriptor used to associate analysis configuration with analysis
|
|
/// contexts in configuration data.
|
|
final ResultDescriptor<AnalysisConfiguration> ANALYSIS_CONFIGURATION =
|
|
new ResultDescriptorImpl('analysis.config', null);
|
|
|
|
/// Return configuration associated with this [context], or `null` if there is
|
|
/// none.
|
|
AnalysisConfiguration getConfiguration(AnalysisContext context) =>
|
|
context.getConfigurationData(ANALYSIS_CONFIGURATION)
|
|
as AnalysisConfiguration;
|
|
|
|
/// Associate this [config] with the given [context].
|
|
void setConfiguration(AnalysisContext context, AnalysisConfiguration config) {
|
|
context.setConfigurationData(ANALYSIS_CONFIGURATION, config);
|
|
}
|
|
|
|
/// Analysis configuration.
|
|
abstract class AnalysisConfiguration {
|
|
final AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();
|
|
final Packages packages;
|
|
final ResourceProvider resourceProvider;
|
|
AnalysisConfiguration(this.resourceProvider, this.packages);
|
|
|
|
factory AnalysisConfiguration.fromPubspec(
|
|
File pubspec, ResourceProvider resourceProvider, Packages packages) =>
|
|
new PubspecConfiguration(pubspec, resourceProvider, packages);
|
|
|
|
/// Get a map of options defined by this configuration (or `null` if none
|
|
/// are specified).
|
|
Map get options;
|
|
}
|
|
|
|
/// Describes an analysis configuration.
|
|
class AnalysisConfigurationDescriptor {
|
|
/// The name of the package hosting the configuration.
|
|
String package;
|
|
/// The name of the configuration "pragma".
|
|
String pragma;
|
|
|
|
AnalysisConfigurationDescriptor.fromAnalyzerOptions(Map analyzerOptions) {
|
|
Object config = analyzerOptions['configuration'];
|
|
if (config is String) {
|
|
List<String> items = config.split('/');
|
|
if (items.length == 2) {
|
|
package = items[0].trim();
|
|
pragma = items[1].trim();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Return true if this descriptor is valid.
|
|
bool get isValid => package != null && pragma != null;
|
|
}
|
|
|
|
/// Pubspec-specified analysis configuration.
|
|
class PubspecConfiguration extends AnalysisConfiguration {
|
|
final File pubspec;
|
|
PubspecConfiguration(
|
|
this.pubspec, ResourceProvider resourceProvider, Packages packages)
|
|
: super(resourceProvider, packages);
|
|
|
|
@override
|
|
Map get options {
|
|
//Safest not to cache (requested infrequently).
|
|
if (pubspec.exists) {
|
|
try {
|
|
String contents = pubspec.readAsStringSync();
|
|
YamlNode map = loadYamlNode(contents);
|
|
if (map is YamlMap) {
|
|
YamlNode config = map['analyzer'];
|
|
if (config is YamlMap) {
|
|
AnalysisConfigurationDescriptor descriptor =
|
|
new AnalysisConfigurationDescriptor.fromAnalyzerOptions(config);
|
|
|
|
if (descriptor.isValid) {
|
|
//Create a path, given descriptor and packagemap
|
|
Uri uri = packages.asMap()[descriptor.package];
|
|
Uri pragma = new Uri.file('config/${descriptor.pragma}.yaml',
|
|
windows: false);
|
|
Uri optionsUri = uri.resolveUri(pragma);
|
|
File file = resourceProvider.getFile(optionsUri.toFilePath());
|
|
if (file.exists) {
|
|
return optionsProvider.getOptionsFromFile(file);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch (_) {
|
|
// Skip exceptional configurations.
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|