Skip to content

Commit

Permalink
Version 3.4.0-234.0.dev
Browse files Browse the repository at this point in the history
Merge 081cff0 into dev
  • Loading branch information
Dart CI committed Mar 14, 2024
2 parents 2bc8b22 + 081cff0 commit 70ca232
Show file tree
Hide file tree
Showing 18 changed files with 194 additions and 163 deletions.
17 changes: 0 additions & 17 deletions pkg/analysis_server/lib/src/plugin/plugin_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import 'package:analyzer_plugin/src/protocol/protocol_internal.dart';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'package:watcher/watcher.dart' as watcher;
import 'package:yaml/yaml.dart';

Expand Down Expand Up @@ -482,22 +481,6 @@ class PluginManager {
return plugins;
}

/// Record a failure to run the plugin associated with the host package with
/// the given [hostPackageName]. The failure is described by the [message],
/// and is expected to have occurred before a path could be computed, and
/// hence before [addPluginToContextRoot] could be invoked.
void recordPluginFailure(String hostPackageName, String message) {
try {
throw PluginException(message);
} catch (exception, stackTrace) {
var pluginPath = path.join(hostPackageName, 'tools', 'analyzer_plugin');
var plugin = DiscoveredPluginInfo(
pluginPath, '', '', notificationManager, instrumentationService);
plugin.reportException(CaughtException(exception, stackTrace));
_pluginMap[pluginPath] = plugin;
}
}

/// The given [contextRoot] is no longer being analyzed.
void removedContextRoot(analyzer.ContextRoot contextRoot) {
var plugins = _pluginMap.values.toList();
Expand Down
34 changes: 15 additions & 19 deletions pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,22 @@ class PluginWatcher implements DriverWatcher {
var uri = 'package:$hostPackageName/$hostPackageName.dart';
var source = driver.sourceFactory.forUri(uri);
if (source == null) {
manager.recordPluginFailure(hostPackageName,
'Could not resolve "$uri" in ${contextRoot.root}.');
} else {
var context = resourceProvider.pathContext;
var packageRoot = context.dirname(context.dirname(source.fullName));
var pluginPath = _locator.findPlugin(packageRoot);
if (pluginPath == null) {
manager.recordPluginFailure(
hostPackageName, 'Could not find plugin in "$packageRoot".');
} else {
//
// Add the plugin to the context root.
//
// TODO(brianwilkerson): Do we need to wait for the plugin to be added?
// If we don't, then tests don't have any way to know when to expect
// that the list of plugins has been updated.
manager.addPluginToContextRoot(
driver.analysisContext!.contextRoot, pluginPath);
}
return;
}
var context = resourceProvider.pathContext;
var packageRoot = context.dirname(context.dirname(source.fullName));
var pluginPath = _locator.findPlugin(packageRoot);
if (pluginPath == null) {
return;
}
//
// Add the plugin to the context root.
//
// TODO(brianwilkerson): Do we need to wait for the plugin to be added?
// If we don't, then tests don't have any way to know when to expect
// that the list of plugins has been updated.
manager.addPluginToContextRoot(
driver.analysisContext!.contextRoot, pluginPath);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ class DeclarationHelper {
/// suggestions are being produced by the various passes.
final bool skipImports;

/// The nodes that should be excluded, for example because we identified
/// that they were created during parsing recovery, and don't contain
/// useful suggestions.
final Set<AstNode> excludedNodes;

/// The number of local variables that have already been suggested.
int _variableDistance = 0;

Expand Down Expand Up @@ -102,6 +107,7 @@ class DeclarationHelper {
required this.mustBeType,
required this.preferNonInvocation,
required this.skipImports,
required this.excludedNodes,
});

/// Return the suggestion kind that should be used for executable elements.
Expand Down Expand Up @@ -1615,12 +1621,18 @@ class DeclarationHelper {
}

void _visitTypeParameterList(TypeParameterList? typeParameters) {
if (typeParameters != null) {
for (var typeParameter in typeParameters.typeParameters) {
var element = typeParameter.declaredElement;
if (element != null) {
_suggestTypeParameter(element);
}
if (typeParameters == null) {
return;
}

if (excludedNodes.contains(typeParameters)) {
return;
}

for (var typeParameter in typeParameters.typeParameters) {
var element = typeParameter.declaredElement;
if (element != null) {
_suggestTypeParameter(element);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
bool mustBeStatic = false,
bool mustBeType = false,
bool preferNonInvocation = false,
Set<AstNode> excludedNodes = const {},
}) {
var contextType = state.contextType;
if (contextType is FunctionType) {
Expand Down Expand Up @@ -189,6 +190,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
mustBeType: mustBeType,
preferNonInvocation: preferNonInvocation,
skipImports: skipImports,
excludedNodes: excludedNodes,
);
}

Expand Down Expand Up @@ -2248,7 +2250,10 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
rightParenthesis != null &&
rightParenthesis.type == TokenType.CLOSE_PAREN &&
rightParenthesis.isSynthetic) {
_forTypeAnnotation(node);
_forTypeAnnotation(
node,
excludedNodes: {typeParameters},
);
return;
}
}
Expand Down Expand Up @@ -2804,11 +2809,14 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {

/// Adds the suggestions that are appropriate when the selection is at the
/// beginning of a type annotation.
void _forTypeAnnotation(AstNode node,
{bool mustBeExtensible = false,
bool mustBeImplementable = false,
bool mustBeMixable = false,
bool mustBeNonVoid = false}) {
void _forTypeAnnotation(
AstNode node, {
bool mustBeExtensible = false,
bool mustBeImplementable = false,
bool mustBeMixable = false,
bool mustBeNonVoid = false,
Set<AstNode> excludedNodes = const {},
}) {
if (!(mustBeExtensible || mustBeImplementable || mustBeMixable)) {
keywordHelper.addKeyword(Keyword.DYNAMIC);
if (!mustBeNonVoid) {
Expand All @@ -2821,12 +2829,13 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
return;
}
declarationHelper(
mustBeExtensible: mustBeExtensible,
mustBeImplementable: mustBeImplementable,
mustBeMixable: mustBeMixable,
mustBeType: true,
mustBeNonVoid: mustBeNonVoid)
.addLexicalDeclarations(node);
mustBeExtensible: mustBeExtensible,
mustBeImplementable: mustBeImplementable,
mustBeMixable: mustBeMixable,
mustBeType: true,
mustBeNonVoid: mustBeNonVoid,
excludedNodes: excludedNodes,
).addLexicalDeclarations(node);
}

/// Adds the suggestions that are appropriate when the selection is at the
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2024, 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:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';

class ReplaceWithNamedConstant extends ResolvedCorrectionProducer {
@override
FixKind get fixKind => DartFixKind.USE_NAMED_CONSTANTS;

@override
Future<void> compute(ChangeBuilder builder) async {
final diagnostic = this.diagnostic;
if (diagnostic is AnalysisError) {
String? correctionMessage = diagnostic.correctionMessage;
if(correctionMessage == null){
return;
}

String? correction = _getCorrection(correctionMessage);
if(correction == null){
return;
}

await builder.addDartFileEdit(file, (builder) {
builder.addSimpleReplacement(range.error(diagnostic), correction);
});
}
}


static String? _getCorrection(String message) {
final match = RegExp(r"'(.*)'").firstMatch(message);
if (match == null) {
return null;
}
return match.group(1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2451,7 +2451,7 @@ LintCode.use_key_in_widget_constructors:
LintCode.use_late_for_private_fields_and_variables:
status: needsFix
LintCode.use_named_constants:
status: needsFix
status: hasFix
LintCode.use_raw_strings:
status: hasFix
LintCode.use_rethrow_when_possible:
Expand Down
5 changes: 5 additions & 0 deletions pkg/analysis_server/lib/src/services/correction/fix.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1911,6 +1911,11 @@ class DartFixKind {
DartFixKindPriority.IN_FILE,
"Use x.isNotEmpty instead of '!x.isEmpty' everywhere in file",
);
static const USE_NAMED_CONSTANTS = FixKind(
'dart.fix.use.namedConstants',
DartFixKindPriority.DEFAULT,
'Replace with a predefined named constant'
);
static const USE_NOT_EQ_NULL = FixKind(
'dart.fix.use.notEqNull',
DartFixKindPriority.DEFAULT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ import 'package:analysis_server/src/services/correction/dart/replace_with_identi
import 'package:analysis_server/src/services/correction/dart/replace_with_interpolation.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_is_empty.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_is_nan.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_named_constant.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_not_null_aware.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_null_aware.dart';
import 'package:analysis_server/src/services/correction/dart/replace_with_part_of_uri.dart';
Expand Down Expand Up @@ -647,6 +648,9 @@ final _builtInLintProducers = <String, List<ProducerGenerator>>{
LintNames.use_key_in_widget_constructors: [
AddKeyToConstructors.new,
],
LintNames.use_named_constants: [
ReplaceWithNamedConstant.new,
],
LintNames.use_raw_strings: [
ConvertToRawString.new,
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ class LintNames {
'use_function_type_syntax_for_parameters';
static const String use_key_in_widget_constructors =
'use_key_in_widget_constructors';
static const String use_named_constants = 'use_named_constants';
static const String use_raw_strings = 'use_raw_strings';
static const String use_rethrow_when_possible = 'use_rethrow_when_possible';
static const String use_string_in_part_of_directives =
Expand Down
5 changes: 0 additions & 5 deletions pkg/analysis_server/lib/src/utilities/mocks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,6 @@ class TestPluginManager implements PluginManager {
fail('Unexpected invocation of pluginsForContextRoot');
}

@override
void recordPluginFailure(String hostPackageName, String message) {
fail('Unexpected invocation of recordPluginFailure');
}

@override
void removedContextRoot(analyzer.ContextRoot contextRoot) {
fail('Unexpected invocation of removedContextRoot');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,35 @@ suggestions
''');
}

Future<void> test_afterLess_beforeGreater_topLevel_partial() async {
Future<void> test_afterLess_beforeGreater_topLevel() async {
await computeSuggestions('''
Future<v^>
class A01 {}
Future<^>
''');
assertResponse(r'''
replacement
left: 1
suggestions
A01
kind: class
void
kind: keyword
dynamic
kind: keyword
''');
}

Future<void> test_afterLess_beforeGreater_topLevel_partial() async {
await computeSuggestions('''
class A01 {}
Future<A0^>
''');
assertResponse(r'''
replacement
left: 2
suggestions
A01
kind: class
''');
}

Expand Down
3 changes: 0 additions & 3 deletions pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,6 @@ class TestPluginManager implements PluginManager {
@override
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);

@override
void recordPluginFailure(String hostPackageName, String message) {}

@override
void removedContextRoot(ContextRoot contextRoot) {
removedContextRoots.add(contextRoot);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) 2024, 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:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/services/linter/lint_names.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'fix_processor.dart';

void main() {
defineReflectiveSuite(() {
defineReflectiveTests(ReplaceWithNamedConstantTest);
});
}

@reflectiveTest
class ReplaceWithNamedConstantTest extends FixProcessorLintTest {
@override
FixKind get kind => DartFixKind.USE_NAMED_CONSTANTS;

@override
String get lintCode => LintNames.use_named_constants;

Future<void> test_use_named_constant() async {
await resolveTestCode('''
final value = const C(0);
class C {
static const C zero = C(0);
final int f;
const C(this.f);
}
''');

await assertHasFix('''
final value = C.zero;
class C {
static const C zero = C(0);
final int f;
const C(this.f);
}
''');
}
}
Loading

0 comments on commit 70ca232

Please sign in to comment.