mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
Add support for sort imports to BulkFixProcessor, add prefer_generic_function_type_aliases
to list of lints for lightweight mode.
Change-Id: Ic8a1afde5f35a65065dd8439a11c4d99846c2905 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319240 Commit-Queue: Keerti Parthasarathy <keertip@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
1948b0a9fe
commit
155bfc973b
|
@ -2,6 +2,7 @@
|
|||
// 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:_fe_analyzer_shared/src/scanner/errors.dart';
|
||||
import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
|
||||
import 'package:analysis_server/protocol/protocol_generated.dart'
|
||||
hide AnalysisOptions;
|
||||
|
@ -24,8 +25,10 @@ import 'package:analyzer/exception/exception.dart';
|
|||
import 'package:analyzer/file_system/file_system.dart';
|
||||
import 'package:analyzer/instrumentation/service.dart';
|
||||
import 'package:analyzer/source/error_processor.dart';
|
||||
import 'package:analyzer/source/source_range.dart';
|
||||
import 'package:analyzer/src/clients/build_resolvers/build_resolvers.dart';
|
||||
import 'package:analyzer/src/dart/ast/utilities.dart';
|
||||
import 'package:analyzer/src/dart/error/syntactic_errors.g.dart';
|
||||
import 'package:analyzer/src/error/codes.dart';
|
||||
import 'package:analyzer/src/lint/linter.dart';
|
||||
import 'package:analyzer/src/lint/linter_visitor.dart';
|
||||
|
@ -42,6 +45,8 @@ import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dar
|
|||
import 'package:analyzer_plugin/utilities/change_builder/conflicting_edit_exception.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
import 'organize_imports.dart';
|
||||
|
||||
/// A fix producer that produces changes that will fix multiple diagnostics in
|
||||
/// one or more files.
|
||||
///
|
||||
|
@ -55,10 +60,12 @@ class BulkFixProcessor {
|
|||
/// A list of lint codes that can be run on parsed code. These lints will all
|
||||
/// be run when the `--syntactic-fixes` flag is specified.
|
||||
static const List<String> syntacticLintCodes = [
|
||||
LintNames.prefer_generic_function_type_aliases,
|
||||
LintNames.slash_for_doc_comments,
|
||||
LintNames.unnecessary_const,
|
||||
LintNames.unnecessary_new,
|
||||
LintNames.unnecessary_string_escapes,
|
||||
LintNames.use_function_type_syntax_for_parameters,
|
||||
];
|
||||
|
||||
/// A map from an error code to a list of generators used to create multiple
|
||||
|
@ -270,6 +277,10 @@ class BulkFixProcessor {
|
|||
return changeMap.hasFixes;
|
||||
}
|
||||
|
||||
Future<BulkFixRequestResult> organizeDirectives(
|
||||
List<AnalysisContext> contexts) =>
|
||||
_organizeDirectives(contexts);
|
||||
|
||||
Future<void> _applyProducer(
|
||||
CorrectionProducerContext context, CorrectionProducer producer) async {
|
||||
producer.configure(context);
|
||||
|
@ -696,6 +707,41 @@ class BulkFixProcessor {
|
|||
return FixProcessor.canBulkFix(errorCode);
|
||||
}
|
||||
|
||||
Future<BulkFixRequestResult> _organizeDirectives(
|
||||
List<AnalysisContext> contexts) async {
|
||||
for (var context in contexts) {
|
||||
for (var path in context.contextRoot.analyzedFiles()) {
|
||||
var pathContext = context.contextRoot.resourceProvider.pathContext;
|
||||
if (!file_paths.isDart(pathContext, path) ||
|
||||
file_paths.isGenerated(path)) {
|
||||
continue;
|
||||
}
|
||||
var result =
|
||||
context.currentSession.getParsedUnit(path) as ParsedUnitResult;
|
||||
var code = result.content;
|
||||
var errors = result.errors;
|
||||
// check if there are scan/parse errors in the file
|
||||
var hasParseErrors = errors.any((error) =>
|
||||
error.errorCode is ScannerErrorCode ||
|
||||
error.errorCode is ParserErrorCode);
|
||||
if (hasParseErrors) {
|
||||
// cannot process files with parse errors
|
||||
continue;
|
||||
}
|
||||
// do organize
|
||||
var sorter = ImportOrganizer(code, result.unit, errors);
|
||||
var edits = sorter.organize();
|
||||
await builder.addGenericFileEdit(path, (builder) {
|
||||
for (var edit in edits) {
|
||||
builder.addSimpleReplacement(
|
||||
SourceRange(edit.offset, edit.length), edit.replacement);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return BulkFixRequestResult(builder);
|
||||
}
|
||||
|
||||
/// Return the override set corresponding to the given [result], or `null` if
|
||||
/// there is no corresponding configuration file or the file content isn't a
|
||||
/// valid override set.
|
||||
|
|
|
@ -1733,6 +1733,9 @@ class FixProcessor extends BaseProcessor {
|
|||
/// A map from error codes to a list of fix generators that work with only
|
||||
/// parsed results.
|
||||
static final Map<String, List<ProducerGenerator>> parseLintProducerMap = {
|
||||
LintNames.prefer_generic_function_type_aliases: [
|
||||
ConvertToGenericFunctionSyntax.new,
|
||||
],
|
||||
LintNames.slash_for_doc_comments: [
|
||||
ConvertDocumentationIntoLine.new,
|
||||
],
|
||||
|
@ -1745,6 +1748,9 @@ class FixProcessor extends BaseProcessor {
|
|||
LintNames.unnecessary_string_escapes: [
|
||||
RemoveUnnecessaryStringEscape.new,
|
||||
],
|
||||
LintNames.use_function_type_syntax_for_parameters: [
|
||||
ConvertToGenericFunctionSyntax.new,
|
||||
],
|
||||
};
|
||||
|
||||
final DartFixContext fixContext;
|
||||
|
|
|
@ -22,6 +22,7 @@ class AbstractSingleUnitTest extends AbstractContextTest {
|
|||
bool useLineEndingsForPlatform = false;
|
||||
|
||||
late String testCode;
|
||||
late ParsedUnitResult testParsedResult;
|
||||
late ResolvedUnitResult testAnalysisResult;
|
||||
late CompilationUnit testUnit;
|
||||
late CompilationUnitElement testUnitElement;
|
||||
|
@ -48,6 +49,7 @@ class AbstractSingleUnitTest extends AbstractContextTest {
|
|||
@override
|
||||
Future<ParsedUnitResult> getParsedUnit(File file) async {
|
||||
var result = await super.getParsedUnit(file);
|
||||
testParsedResult = result;
|
||||
testCode = result.content;
|
||||
testUnit = result.unit;
|
||||
findNode = FindNode(testCode, testUnit);
|
||||
|
|
|
@ -24,14 +24,14 @@ class PreferGenericFunctionTypeAliasesBulkTest extends BulkFixProcessorTest {
|
|||
String get lintCode => LintNames.prefer_generic_function_type_aliases;
|
||||
|
||||
Future<void> test_singleFile() async {
|
||||
await resolveTestCode('''
|
||||
await parseTestCode('''
|
||||
typedef String F(int x);
|
||||
typedef F2<P, R>(P x);
|
||||
''');
|
||||
await assertHasFix('''
|
||||
typedef F = String Function(int x);
|
||||
typedef F2<P, R> = Function(P x);
|
||||
''');
|
||||
''', isParse: true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,23 +93,23 @@ class UseFunctionTypeSyntaxForParametersBulkTest extends BulkFixProcessorTest {
|
|||
String get lintCode => LintNames.use_function_type_syntax_for_parameters;
|
||||
|
||||
Future<void> test_singleFile() async {
|
||||
await resolveTestCode('''
|
||||
await parseTestCode('''
|
||||
g(String f(int x), int h()) {}
|
||||
''');
|
||||
await assertHasFix('''
|
||||
g(String Function(int x) f, int Function() h) {}
|
||||
''');
|
||||
''', isParse: true);
|
||||
}
|
||||
|
||||
@failingTest
|
||||
Future<void> test_singleFile_nested() async {
|
||||
// Only the outer function gets converted.
|
||||
await resolveTestCode('''
|
||||
await parseTestCode('''
|
||||
g(String f(int h())) {}
|
||||
''');
|
||||
await assertHasFix('''
|
||||
g(String Function(int Function() h) f) {}
|
||||
''');
|
||||
''', isParse: true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -118,6 +118,20 @@ abstract class BulkFixProcessorTest extends AbstractSingleUnitTest {
|
|||
expect(fileEdits, isEmpty);
|
||||
}
|
||||
|
||||
Future<void> assertOrganize(String expectedCode) async {
|
||||
var tracker = DeclarationsTracker(MemoryByteStore(), resourceProvider);
|
||||
var analysisContext = contextFor(testFile);
|
||||
tracker.addContext(analysisContext);
|
||||
processor = BulkFixProcessor(TestInstrumentationService(), await workspace,
|
||||
useConfigFiles: useConfigFiles);
|
||||
await processor.organizeDirectives([analysisContext]);
|
||||
var change = processor.builder.sourceChange;
|
||||
var fileEdits = change.edits;
|
||||
expect(fileEdits, hasLength(1));
|
||||
resultCode = SourceEdit.applySequence(testCode, change.edits[0].edits);
|
||||
expect(resultCode, expectedCode);
|
||||
}
|
||||
|
||||
/// Computes fixes for the specified [testUnit].
|
||||
Future<BulkFixProcessor> computeFixes({bool isParse = false}) async {
|
||||
var tracker = DeclarationsTracker(MemoryByteStore(), resourceProvider);
|
||||
|
|
|
@ -11,10 +11,30 @@ import 'fix_processor.dart';
|
|||
|
||||
void main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(OrganizeImportsBulkTest);
|
||||
defineReflectiveTests(OrganizeImportsTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class OrganizeImportsBulkTest extends BulkFixProcessorTest {
|
||||
Future<void> test_single_file() async {
|
||||
await parseTestCode('''
|
||||
import 'dart:io';
|
||||
import 'dart:async';
|
||||
|
||||
Future a;
|
||||
''');
|
||||
|
||||
await assertOrganize('''
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
Future a;
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class OrganizeImportsTest extends FixProcessorLintTest {
|
||||
@override
|
||||
|
|
Loading…
Reference in a new issue