mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:39:49 +00:00
[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:
parent
f9355b1bf2
commit
e09493b7bc
|
@ -2,6 +2,8 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// 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
|
/// A set of options related to coding style that apply to the code within a
|
||||||
/// single analysis context.
|
/// single analysis context.
|
||||||
///
|
///
|
||||||
|
@ -14,6 +16,10 @@ abstract class CodeStyleOptions {
|
||||||
/// Return `true` if local variables should be `final` whenever possible.
|
/// Return `true` if local variables should be `final` whenever possible.
|
||||||
bool get makeLocalsFinal;
|
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
|
/// Return `true` if constructors should be sorted first, before other
|
||||||
/// class members.
|
/// class members.
|
||||||
bool get sortConstructorsFirst;
|
bool get sortConstructorsFirst;
|
||||||
|
@ -25,4 +31,8 @@ abstract class CodeStyleOptions {
|
||||||
/// Return `true` if URIs should be "relative", meaning without a scheme,
|
/// Return `true` if URIs should be "relative", meaning without a scheme,
|
||||||
/// whenever possible.
|
/// whenever possible.
|
||||||
bool get useRelativeUris;
|
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/analysis_options.dart';
|
||||||
import 'package:analyzer/dart/analysis/code_style_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].
|
/// The concrete implementation of [CodeStyleOptions].
|
||||||
class CodeStyleOptionsImpl implements CodeStyleOptions {
|
class CodeStyleOptionsImpl implements CodeStyleOptions {
|
||||||
|
@ -22,12 +24,34 @@ class CodeStyleOptionsImpl implements CodeStyleOptions {
|
||||||
@override
|
@override
|
||||||
bool get makeLocalsFinal => _isLintEnabled('prefer_final_locals');
|
bool get makeLocalsFinal => _isLintEnabled('prefer_final_locals');
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get preferredQuoteForStrings => _lintQuote() ?? "'";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get sortConstructorsFirst => _isLintEnabled('sort_constructors_first');
|
bool get sortConstructorsFirst => _isLintEnabled('sort_constructors_first');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get useRelativeUris => _isLintEnabled('prefer_relative_imports');
|
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.
|
/// Return `true` if the lint with the given [name] is enabled.
|
||||||
bool _isLintEnabled(String name) => options.isLintEnabled(name);
|
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();
|
var importList = imports.toList();
|
||||||
importList.sort((a, b) => a.uriText.compareTo(b.uriText));
|
importList.sort((a, b) => a.uriText.compareTo(b.uriText));
|
||||||
|
|
||||||
|
var quote = codeStyleOptions.preferredQuoteForUris(importDirectives);
|
||||||
void writeImport(EditBuilder builder, _LibraryToImport import) {
|
void writeImport(EditBuilder builder, _LibraryToImport import) {
|
||||||
builder.write("import '");
|
builder.write('import $quote');
|
||||||
builder.write(import.uriText);
|
builder.write(import.uriText);
|
||||||
builder.write("'");
|
builder.write(quote);
|
||||||
var prefix = import.prefix;
|
var prefix = import.prefix;
|
||||||
if (prefix != null) {
|
if (prefix != null) {
|
||||||
builder.write(' as ');
|
builder.write(' as ');
|
||||||
|
|
|
@ -20,6 +20,7 @@ dependencies:
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
analyzer_utilities: any
|
analyzer_utilities: any
|
||||||
lints: any
|
lints: any
|
||||||
|
linter: any
|
||||||
meta: any
|
meta: any
|
||||||
path: any
|
path: any
|
||||||
test_reflective_loader: 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/protocol/protocol_common.dart';
|
||||||
import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart'
|
import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart'
|
||||||
show DartLinkedEditBuilderImpl;
|
show DartLinkedEditBuilderImpl;
|
||||||
|
import 'package:linter/src/rules.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'package:test_reflective_loader/test_reflective_loader.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 {
|
Future<void> test_multiple_dart_then_package() async {
|
||||||
await _assertImportLibrary(
|
await _assertImportLibrary(
|
||||||
initialCode: '''
|
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 {
|
Future<void> test_relative_afterDart() async {
|
||||||
await _assertImportLibrary(
|
await _assertImportLibrary(
|
||||||
initialCode: '''
|
initialCode: '''
|
||||||
|
|
|
@ -126,6 +126,25 @@ class AbstractContextTest with ResourceProviderMixin {
|
||||||
newFile(path, config.toContent(toUriStr: toUriStr));
|
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({
|
void writeTestPackageConfig({
|
||||||
PackageConfigFileBuilder? config,
|
PackageConfigFileBuilder? config,
|
||||||
String? languageVersion,
|
String? languageVersion,
|
||||||
|
|
Loading…
Reference in a new issue