[analyzer] use preferred quote-style when generating imports
Bug #49559 Change-Id: Ib77ea67bb1ea15bfabb1c717cfb5abf13fd6d3cb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/259720 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
// 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/dart/ast/ast.dart';
|
||||
|
||||
/// A set of options related to coding style that apply to the code within a
|
||||
/// single analysis context.
|
||||
///
|
||||
@@ -14,6 +16,10 @@ abstract class CodeStyleOptions {
|
||||
/// Return `true` if local variables should be `final` whenever possible.
|
||||
bool get makeLocalsFinal;
|
||||
|
||||
/// Return the preferred quote based on the enabled lints,otherwise a single
|
||||
/// quote.
|
||||
String get preferredQuoteForStrings;
|
||||
|
||||
/// Return `true` if constructors should be sorted first, before other
|
||||
/// class members.
|
||||
bool get sortConstructorsFirst;
|
||||
@@ -25,4 +31,8 @@ abstract class CodeStyleOptions {
|
||||
/// Return `true` if URIs should be "relative", meaning without a scheme,
|
||||
/// whenever possible.
|
||||
bool get useRelativeUris;
|
||||
|
||||
/// Return the preferred quote based on the enabled lints, otherwise based
|
||||
/// on the first directive, otherwise a single quote.
|
||||
String preferredQuoteForUris(List<ImportDirective> directives);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
import 'package:analyzer/dart/analysis/analysis_options.dart';
|
||||
import 'package:analyzer/dart/analysis/code_style_options.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
/// The concrete implementation of [CodeStyleOptions].
|
||||
class CodeStyleOptionsImpl implements CodeStyleOptions {
|
||||
@@ -22,12 +24,34 @@ class CodeStyleOptionsImpl implements CodeStyleOptions {
|
||||
@override
|
||||
bool get makeLocalsFinal => _isLintEnabled('prefer_final_locals');
|
||||
|
||||
@override
|
||||
String get preferredQuoteForStrings => _lintQuote() ?? "'";
|
||||
|
||||
@override
|
||||
bool get sortConstructorsFirst => _isLintEnabled('sort_constructors_first');
|
||||
|
||||
@override
|
||||
bool get useRelativeUris => _isLintEnabled('prefer_relative_imports');
|
||||
|
||||
@override
|
||||
String preferredQuoteForUris(List<ImportDirective> directives) {
|
||||
var lintQuote = _lintQuote();
|
||||
if (lintQuote != null) {
|
||||
return lintQuote;
|
||||
}
|
||||
var uri = directives.firstOrNull?.uri;
|
||||
var doubleQuote = uri is SimpleStringLiteral &&
|
||||
uri.literal.value().toString().startsWith('"');
|
||||
return doubleQuote ? '"' : "'";
|
||||
}
|
||||
|
||||
/// Return `true` if the lint with the given [name] is enabled.
|
||||
bool _isLintEnabled(String name) => options.isLintEnabled(name);
|
||||
|
||||
/// Return the preferred lint quote, otherwise `null`.
|
||||
String? _lintQuote() => _isLintEnabled("prefer_single_quotes")
|
||||
? "'"
|
||||
: _isLintEnabled("prefer_double_quotes")
|
||||
? '"'
|
||||
: null;
|
||||
}
|
||||
|
||||
@@ -1600,10 +1600,11 @@ class DartFileEditBuilderImpl extends FileEditBuilderImpl
|
||||
var importList = imports.toList();
|
||||
importList.sort((a, b) => a.uriText.compareTo(b.uriText));
|
||||
|
||||
var quote = codeStyleOptions.preferredQuoteForUris(importDirectives);
|
||||
void writeImport(EditBuilder builder, _LibraryToImport import) {
|
||||
builder.write("import '");
|
||||
builder.write('import $quote');
|
||||
builder.write(import.uriText);
|
||||
builder.write("'");
|
||||
builder.write(quote);
|
||||
var prefix = import.prefix;
|
||||
if (prefix != null) {
|
||||
builder.write(' as ');
|
||||
|
||||
@@ -20,6 +20,7 @@ dependencies:
|
||||
dev_dependencies:
|
||||
analyzer_utilities: any
|
||||
lints: any
|
||||
linter: any
|
||||
meta: any
|
||||
path: any
|
||||
test_reflective_loader: any
|
||||
|
||||
@@ -15,6 +15,7 @@ import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
|
||||
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
||||
import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart'
|
||||
show DartLinkedEditBuilderImpl;
|
||||
import 'package:linter/src/rules.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
@@ -2088,6 +2089,43 @@ import 'package:foo/foo.dart';
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> test_default_quote() async {
|
||||
await _assertImportLibrary(
|
||||
initialCode: '''
|
||||
''',
|
||||
uriList: ['dart:aaa'],
|
||||
expectedCode: '''
|
||||
import 'dart:aaa';
|
||||
''',
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> test_directive_double_quote() async {
|
||||
await _assertImportLibrary(
|
||||
initialCode: '''
|
||||
import "dart:bbb";
|
||||
''',
|
||||
uriList: ['dart:aaa'],
|
||||
expectedCode: '''
|
||||
import "dart:aaa";
|
||||
import "dart:bbb";
|
||||
''',
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> test_directive_single_quote() async {
|
||||
await _assertImportLibrary(
|
||||
initialCode: '''
|
||||
import 'dart:bbb';
|
||||
''',
|
||||
uriList: ['dart:aaa'],
|
||||
expectedCode: '''
|
||||
import 'dart:aaa';
|
||||
import 'dart:bbb';
|
||||
''',
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> test_multiple_dart_then_package() async {
|
||||
await _assertImportLibrary(
|
||||
initialCode: '''
|
||||
@@ -2395,6 +2433,36 @@ import 'foo.dart';
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> test_prefer_double_quotes() async {
|
||||
registerLintRules();
|
||||
writeTestPackageAnalysisOptionsFile(lints: ['prefer_double_quotes']);
|
||||
await _assertImportLibrary(
|
||||
initialCode: '''
|
||||
import 'dart:bbb';
|
||||
''',
|
||||
uriList: ['dart:aaa'],
|
||||
expectedCode: '''
|
||||
import "dart:aaa";
|
||||
import 'dart:bbb';
|
||||
''',
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> test_prefer_single_quotes() async {
|
||||
registerLintRules();
|
||||
writeTestPackageAnalysisOptionsFile(lints: ['prefer_single_quotes']);
|
||||
await _assertImportLibrary(
|
||||
initialCode: '''
|
||||
import "dart:bbb";
|
||||
''',
|
||||
uriList: ['dart:aaa'],
|
||||
expectedCode: '''
|
||||
import 'dart:aaa';
|
||||
import "dart:bbb";
|
||||
''',
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> test_relative_afterDart() async {
|
||||
await _assertImportLibrary(
|
||||
initialCode: '''
|
||||
|
||||
@@ -126,6 +126,25 @@ class AbstractContextTest with ResourceProviderMixin {
|
||||
newFile(path, config.toContent(toUriStr: toUriStr));
|
||||
}
|
||||
|
||||
/// Write an analysis options file based on the given arguments.
|
||||
/// TODO(asashour) Use AnalysisOptionsFileConfig
|
||||
void writeTestPackageAnalysisOptionsFile({
|
||||
List<String>? lints,
|
||||
}) {
|
||||
var buffer = StringBuffer();
|
||||
|
||||
if (lints != null) {
|
||||
buffer.writeln('linter:');
|
||||
buffer.writeln(' rules:');
|
||||
for (var lint in lints) {
|
||||
buffer.writeln(' - $lint');
|
||||
}
|
||||
}
|
||||
|
||||
print(buffer);
|
||||
newFile('$testPackageRootPath/analysis_options.yaml', buffer.toString());
|
||||
}
|
||||
|
||||
void writeTestPackageConfig({
|
||||
PackageConfigFileBuilder? config,
|
||||
String? languageVersion,
|
||||
|
||||
Reference in New Issue
Block a user