Skip to content

Commit

Permalink
Version 3.3.0-64.0.dev
Browse files Browse the repository at this point in the history
Merge d96c71b into dev
  • Loading branch information
Dart CI committed Oct 26, 2023
2 parents b9d7251 + d96c71b commit 49bb1af
Show file tree
Hide file tree
Showing 13 changed files with 535 additions and 156 deletions.
10 changes: 2 additions & 8 deletions pkg/analysis_server/lib/src/analysis_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/services/available_declarations.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:analyzer/src/utilities/extensions/analysis_session.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/src/protocol/protocol_internal.dart';
import 'package:collection/collection.dart';
Expand Down Expand Up @@ -611,14 +612,7 @@ abstract class AnalysisServer {
return null;
}
try {
var currentSession = driver.currentSession;
var unitElement = await currentSession.getUnitElement(path);
if (unitElement is! UnitElementResult) {
return null;
}
var libraryPath = unitElement.element.library.source.fullName;
var result = await currentSession.getResolvedLibrary(libraryPath);
return result is ResolvedLibraryResult ? result : null;
return driver.currentSession.getResolvedContainingLibrary(path);
} on InconsistentAnalysisException {
return null;
} catch (exception, stackTrace) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import 'package:analyzer/src/string_source.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:analyzer/src/utilities/cancellation.dart';
import 'package:analyzer/src/utilities/extensions/analysis_session.dart';
import 'package:analyzer/src/utilities/extensions/string.dart';
import 'package:analyzer/src/workspace/blaze.dart';
import 'package:analyzer/src/workspace/gn.dart';
Expand Down Expand Up @@ -261,10 +262,12 @@ class BulkFixProcessor {
if (file_paths.isDart(pathContext, path) && !file_paths.isGenerated(path)) {
var library = await performance.runAsync(
'getResolvedLibrary',
(_) => context.currentSession.getResolvedLibrary(path),
(_) => context.currentSession.getResolvedContainingLibrary(path),
);
if (!isCancelled && library is ResolvedLibraryResult) {
await _fixErrorsInLibrary(library, autoTriggered: autoTriggered);
final unit = library?.unitWithPath(path);
if (!isCancelled && library != null && unit != null) {
await _fixErrorsInLibraryUnit(unit, library,
autoTriggered: autoTriggered);
}
}

Expand Down Expand Up @@ -566,33 +569,42 @@ class BulkFixProcessor {
/// library associated with the analysis [result].
Future<void> _fixErrorsInLibrary(ResolvedLibraryResult result,
{bool stopAfterFirst = false, bool autoTriggered = false}) async {
var analysisOptions = result.session.analysisContext.analysisOptions;
for (var unitResult in result.units) {
await _fixErrorsInLibraryUnit(unitResult, result,
stopAfterFirst: stopAfterFirst, autoTriggered: autoTriggered);
}
}

/// Use the change [builder] to create fixes for the diagnostics in
/// [unit].
Future<void> _fixErrorsInLibraryUnit(
ResolvedUnitResult unit, ResolvedLibraryResult library,
{bool stopAfterFirst = false, bool autoTriggered = false}) async {
var analysisOptions = unit.session.analysisContext.analysisOptions;

DartFixContextImpl fixContext(
ResolvedUnitResult result,
AnalysisError diagnostic, {
required bool autoTriggered,
}) {
return DartFixContextImpl(
instrumentationService,
workspace,
result,
unit,
diagnostic,
autoTriggered: autoTriggered,
);
}

CorrectionProducerContext<ResolvedUnitResult>? correctionContext(
ResolvedUnitResult result, AnalysisError diagnostic) {
var overrideSet = _readOverrideSet(result);
var context =
fixContext(result, diagnostic, autoTriggered: autoTriggered);
AnalysisError diagnostic) {
var overrideSet = _readOverrideSet(unit);
var context = fixContext(diagnostic, autoTriggered: autoTriggered);
return CorrectionProducerContext.createResolved(
applyingBulkFixes: true,
dartFixContext: context,
diagnostic: diagnostic,
overrideSet: overrideSet,
resolvedResult: result,
resolvedResult: unit,
selectionOffset: diagnostic.offset,
selectionLength: diagnostic.length,
workspace: workspace,
Expand All @@ -602,61 +614,60 @@ class BulkFixProcessor {
//
// Attempt to apply the fixes that aren't related to directives.
//
for (var unitResult in result.units) {
var overrideSet = _readOverrideSet(unitResult);
for (var error in _filterErrors(analysisOptions, unitResult.errors)) {
var context =
fixContext(unitResult, error, autoTriggered: autoTriggered);
await _fixSingleError(context, unitResult, error, overrideSet);
if (isCancelled || (stopAfterFirst && changeMap.hasFixes)) {
return;
}
var overrideSet = _readOverrideSet(unit);
for (var error in _filterErrors(analysisOptions, unit.errors)) {
var context = fixContext(error, autoTriggered: autoTriggered);
await _fixSingleError(context, unit, error, overrideSet);
if (isCancelled || (stopAfterFirst && changeMap.hasFixes)) {
return;
}
}
//
// If there are no such fixes in the defining compilation unit, then apply
// the fixes related to directives.
//
var definingUnit = result.units[0];

// Only if this unit is the defining unit, we don't have other fixes and
// we were not auto-triggered should be continue with fixes for directives.
if (unit != library.units.first ||
autoTriggered ||
builder.hasEditsFor(unit.path)) {
return;
}

AnalysisError? directivesOrderingError;
var unusedImportErrors = <AnalysisError>[];
if (!autoTriggered && !builder.hasEditsFor(definingUnit.path)) {
for (var error in _filterErrors(analysisOptions, definingUnit.errors)) {
var errorCode = error.errorCode;
if (errorCode is LintCode) {
var lintName = errorCode.name;
if (lintName == LintNames.directives_ordering) {
directivesOrderingError = error;
break;
}
} else if (errorCode == WarningCode.DUPLICATE_IMPORT ||
errorCode == HintCode.UNNECESSARY_IMPORT ||
errorCode == WarningCode.UNUSED_IMPORT) {
unusedImportErrors.add(error);
for (var error in _filterErrors(analysisOptions, unit.errors)) {
var errorCode = error.errorCode;
if (errorCode is LintCode) {
var lintName = errorCode.name;
if (lintName == LintNames.directives_ordering) {
directivesOrderingError = error;
break;
}
} else if (errorCode == WarningCode.DUPLICATE_IMPORT ||
errorCode == HintCode.UNNECESSARY_IMPORT ||
errorCode == WarningCode.UNUSED_IMPORT) {
unusedImportErrors.add(error);
}
if (directivesOrderingError != null) {
// `OrganizeImports` will also remove some of the unused imports, so we
// apply it first.
var context = correctionContext(definingUnit, directivesOrderingError);
}
if (directivesOrderingError != null) {
// `OrganizeImports` will also remove some of the unused imports, so we
// apply it first.
var context = correctionContext(directivesOrderingError);
if (context != null) {
await _generateFix(
context, OrganizeImports(), directivesOrderingError.errorCode.name);
if (isCancelled || (stopAfterFirst && changeMap.hasFixes)) {
return;
}
}
} else {
for (var error in unusedImportErrors) {
var context = correctionContext(error);
if (context != null) {
await _generateFix(context, OrganizeImports(),
directivesOrderingError.errorCode.name);
await _generateFix(
context, RemoveUnusedImport(), error.errorCode.name);
if (isCancelled || (stopAfterFirst && changeMap.hasFixes)) {
return;
}
}
} else {
for (var error in unusedImportErrors) {
var context = correctionContext(definingUnit, error);
if (context != null) {
await _generateFix(
context, RemoveUnusedImport(), error.errorCode.name);
if (isCancelled || (stopAfterFirst && changeMap.hasFixes)) {
return;
}
}
}
}
}
}
Expand Down
38 changes: 38 additions & 0 deletions pkg/analysis_server/test/lsp/code_actions_source_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,44 @@ void f() {
expect(edit.textDocument.version, 1);
}

Future<void> test_part() async {
final containerFilePath = join(projectFolderPath, 'lib', 'container.dart');
final partFilePath = join(projectFolderPath, 'lib', 'part.dart');
const analysisOptionsContent = '''
linter:
rules:
- unnecessary_new
- prefer_collection_literals
''';
const containerFileContent = '''
part 'part.dart';
''';
const content = '''
part of 'container.dart';
final a = new Object();
final b = new Set<String>();
''';
const expectedContent = '''
part of 'container.dart';
final a = Object();
final b = <String>{};
''';

registerLintRules();
newFile(analysisOptionsPath, analysisOptionsContent);
newFile(containerFilePath, containerFileContent);
newFile(partFilePath, content);

await verifyActionEdits(
filePath: partFilePath,
content,
expectedContent,
command: Commands.fixAll,
);
}

Future<void> test_privateUnusedParameters_notRemovedIfSave() async {
const content = '''
class _MyClass {
Expand Down
14 changes: 14 additions & 0 deletions pkg/analyzer/lib/src/utilities/extensions/analysis_session.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,20 @@ import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/utilities/extensions/library_element.dart';

extension AnalysisSessionExtension on AnalysisSession {
/// Return the resolved library for the library containing the file with the
/// given [path].
Future<ResolvedLibraryResult?> getResolvedContainingLibrary(
String path,
) async {
var unitElement = await getUnitElement(path);
if (unitElement is! UnitElementResult) {
return null;
}
var libraryPath = unitElement.element.library.source.fullName;
var result = await getResolvedLibrary(libraryPath);
return result is ResolvedLibraryResult ? result : null;
}

/// Locates the [Element] that [location] represents.
///
/// Local elements such as variables inside functions cannot be found using
Expand Down
2 changes: 1 addition & 1 deletion pkg/dartdev/doc/dart-fix.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ lints and analysis configuration specified in your [analysis_options.yaml] file.
The second type of change - upgrading to newer package APIs - is performed
based on API changes defined for specific packages. This declarative definition
of the API changes lives in a `fix_data.yaml` file in the package's `lib/`
directory (documentation forthcoming).
directory; for details see the [documentation](https://github.com/flutter/flutter/wiki/Data-driven-Fixes).

## Command line usage

Expand Down
Loading

0 comments on commit 49bb1af

Please sign in to comment.