Skip to content

Commit

Permalink
Version 3.6.0-294.0.dev
Browse files Browse the repository at this point in the history
Merge 27479d6 into dev
  • Loading branch information
Dart CI committed Sep 28, 2024
2 parents b60b1a6 + 27479d6 commit 855bd9a
Show file tree
Hide file tree
Showing 11 changed files with 177 additions and 29 deletions.
6 changes: 6 additions & 0 deletions pkg/analysis_server/analyzer_use_new_elements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@ lib/src/services/correction/dart/add_eol_at_end_of_file.dart
lib/src/services/correction/dart/add_explicit_call.dart
lib/src/services/correction/dart/add_explicit_cast.dart
lib/src/services/correction/dart/add_missing_enum_like_case_clauses.dart
lib/src/services/correction/dart/add_field_formal_parameters.dart
lib/src/services/correction/dart/add_key_to_constructors.dart
lib/src/services/correction/dart/add_late.dart
lib/src/services/correction/dart/add_leading_newline_to_string.dart
lib/src/services/correction/dart/add_missing_parameter_named.dart
lib/src/services/correction/dart/add_missing_required_argument.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import 'package:analysis_server/src/utilities/extensions/ast.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/source/source.dart';
Expand Down Expand Up @@ -171,6 +172,29 @@ DefaultArgument? getDefaultStringParameterValue(
return null;
}

/// Return a default argument value for the given [parameter].
DefaultArgument? getDefaultStringParameterValue2(
FormalParameterElement parameter, String quote) {
var type = parameter.type;
if (type is InterfaceType) {
if (type.isDartCoreList) {
return DefaultArgument('[]', cursorPosition: 1);
} else if (type.isDartCoreMap) {
return DefaultArgument('{}', cursorPosition: 1);
} else if (type.isDartCoreString) {
return DefaultArgument('$quote$quote', cursorPosition: 1);
}
} else if (type is FunctionType) {
var params = type.parameters
.map((p) => '${getTypeString(p.type)}${p.name}')
.join(', ');
// TODO(devoncarew): Support having this method return text with newlines.
var text = '($params) { }';
return DefaultArgument(text, cursorPosition: text.length - 2);
}
return null;
}

String getRequestLineIndent(DartCompletionRequest request) {
var content = request.content;
var lineStartOffset = request.offset;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class AddMissingParameterNamed extends ResolvedCorrectionProducer {
}

// We cannot add named parameters when there are positional positional.
if (context.optionalPositional.isNotEmpty) {
if (context.optionalPositional2.isNotEmpty) {
return;
}

Expand All @@ -71,11 +71,13 @@ class AddMissingParameterNamed extends ResolvedCorrectionProducer {
}
}

if (context.named.isNotEmpty) {
var prevNode = await context.getParameterNode(context.named.last);
if (context.named2.isNotEmpty) {
var prevNode =
await context.getParameterNode2(context.named2.last.firstFragment!);
await addParameter(prevNode?.end, ', ', '');
} else if (context.required.isNotEmpty) {
var prevNode = await context.getParameterNode(context.required.last);
} else if (context.required2.isNotEmpty) {
var prevNode = await context
.getParameterNode2(context.required2.last.firstFragment!);
await addParameter(prevNode?.end, ', {', '}');
} else {
var parameterList = await context.getParameterList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/utilities/extensions/flutter.dart';
import 'package:analysis_server_plugin/edit/dart/correction_producer.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:collection/collection.dart';
Expand All @@ -33,20 +33,20 @@ class AddMissingRequiredArgument extends ResolvedCorrectionProducer {
@override
Future<void> compute(ChangeBuilder builder) async {
InstanceCreationExpression? creation;
Element? targetElement;
Element2? targetElement;
ArgumentList? argumentList;

if (node is SimpleIdentifier ||
node is ConstructorName ||
node is NamedType) {
var invocation = node.parent;
if (invocation is MethodInvocation) {
targetElement = invocation.methodName.staticElement;
targetElement = invocation.methodName.element;
argumentList = invocation.argumentList;
} else {
creation = invocation?.thisOrAncestorOfType();
if (creation != null) {
targetElement = creation.constructorName.staticElement;
targetElement = creation.constructorName.element;
argumentList = creation.argumentList;
}
}
Expand All @@ -57,7 +57,7 @@ class AddMissingRequiredArgument extends ResolvedCorrectionProducer {
return;
}

if (targetElement is ExecutableElement && argumentList != null) {
if (targetElement is ExecutableElement2 && argumentList != null) {
// Format: "Missing required argument 'foo'."
var messageParts =
diagnostic.problemMessage.messageText(includeUrl: false).split("'");
Expand All @@ -66,7 +66,7 @@ class AddMissingRequiredArgument extends ResolvedCorrectionProducer {
}
_missingParameterName = messageParts[1];

var missingParameter = targetElement.parameters.firstWhereOrNull(
var missingParameter = targetElement.formalParameters.firstWhereOrNull(
(p) => p.name == _missingParameterName,
);
if (missingParameter == null) {
Expand Down Expand Up @@ -94,7 +94,7 @@ class AddMissingRequiredArgument extends ResolvedCorrectionProducer {
}

var codeStyleOptions = getCodeStyleOptions(unitResult.file);
var defaultValue = getDefaultStringParameterValue(
var defaultValue = getDefaultStringParameterValue2(
missingParameter, codeStyleOptions.preferredQuoteForStrings);

await builder.addDartFileEdit(file, (builder) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/src/dart/analysis/session_helper.dart';

/// [ExecutableElement], its parameters, and operations on them.
Expand All @@ -15,14 +16,21 @@ class ExecutableParameters {
final List<ParameterElement> optionalPositional = [];
final List<ParameterElement> named = [];

final List<FormalParameterElement> required2 = [];
final List<FormalParameterElement> optionalPositional2 = [];
final List<FormalParameterElement> named2 = [];

ExecutableParameters._(this.sessionHelper, this.executable) {
for (var parameter in executable.parameters) {
if (parameter.isRequiredPositional) {
required.add(parameter);
required2.add(parameter.element);
} else if (parameter.isOptionalPositional) {
optionalPositional.add(parameter);
optionalPositional2.add(parameter.element);
} else if (parameter.isNamed) {
named.add(parameter);
named2.add(parameter.element);
}
}
}
Expand Down Expand Up @@ -64,6 +72,20 @@ class ExecutableParameters {
return null;
}

/// Return the [FormalParameter] of the [fragment] in [FormalParameterList],
/// or `null` if it can't be found.
Future<FormalParameter?> getParameterNode2(
FormalParameterFragment fragment) async {
var result = await sessionHelper.getElementDeclaration2(fragment);
var declaration = result?.node;
for (var node = declaration; node != null; node = node.parent) {
if (node is FormalParameter && node.parent is FormalParameterList) {
return node;
}
}
return null;
}

static ExecutableParameters? forInvocation(
AnalysisSessionHelper sessionHelper, AstNode? invocation) {
Element? element;
Expand Down
4 changes: 4 additions & 0 deletions pkg/analyzer/lib/dart/element/element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ library;
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/scope.dart';
import 'package:analyzer/dart/element/type.dart';
Expand Down Expand Up @@ -2203,6 +2204,9 @@ abstract class ParameterElement
/// The code of the default value, or `null` if no default value.
String? get defaultValueCode;

@experimental
FormalParameterElement get element;

/// Whether the parameter has a default value.
bool get hasDefaultValue;

Expand Down
3 changes: 3 additions & 0 deletions pkg/analyzer/lib/dart/element/element2.dart
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,9 @@ abstract class FormalParameterElement
/// Returns `null` if no default value.
String? get defaultValueCode;

@override
FormalParameterFragment? get firstFragment;

/// The formal parameters defined by this formal parameter.
///
/// A parameter will only define other parameters if it is a function typed
Expand Down
4 changes: 4 additions & 0 deletions pkg/analyzer/lib/src/dart/element/member.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,10 @@ class ParameterMember extends VariableMember
@override
String? get defaultValueCode => declaration.defaultValueCode;

@override
// TODO(scheglov): we lose types
FormalParameterElement get element => declaration.element;

@Deprecated('Use enclosingElement3 instead')
@override
Element? get enclosingElement => declaration.enclosingElement;
Expand Down
61 changes: 46 additions & 15 deletions pkg/linter/lib/src/rules/analyzer_use_new_elements.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,33 @@ import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/element/element.dart'; // ignore: implementation_imports
import 'package:analyzer/src/dart/element/type_visitor.dart'; // ignore: implementation_imports

import '../analyzer.dart';

const _desc = r'Use new element model in opted-in files.';

bool _isOldModelElement(Element2? element) {
var firstFragment = element?.firstFragment;
if (firstFragment != null) {
var libraryFragment = firstFragment.libraryFragment;
var uriStr = libraryFragment.source.uri.toString();
return const {
'package:analyzer/dart/element/element.dart',
}.contains(uriStr);
}
return false;
}

bool _isOldModelType(DartType? type) {
var visitor = _TypeVisitor();
type?.accept(visitor);
return visitor.result;
}

/// The lint must be enabled for a Pub package.
///
/// The lint rule reads once the file `analyzer_use_new_elements.txt`
Expand Down Expand Up @@ -51,8 +71,9 @@ class AnalyzerUseNewElements extends LintRule {
}

var visitor = _Visitor(this);
registry.addSimpleIdentifier(this, visitor);
registry.addMethodInvocation(this, visitor);
registry.addNamedType(this, visitor);
registry.addSimpleIdentifier(this, visitor);
}

bool _isEnabledForFile(LinterContext context) {
Expand Down Expand Up @@ -123,36 +144,46 @@ class _FilesRegistry {
}
}

class _TypeVisitor extends RecursiveTypeVisitor {
bool result = false;

@override
bool visitInterfaceType(InterfaceType type) {
result |= _isOldModelElement(type.element3);
return super.visitInterfaceType(type);
}
}

class _Visitor extends SimpleAstVisitor {
final LintRule rule;

_Visitor(this.rule);

@override
visitMethodInvocation(MethodInvocation node) {
if (_isOldModelType(node.staticType)) {
rule.reportLint(node.methodName);
}
}

@override
visitNamedType(NamedType node) {
if (_isOldElementModel(node.element2)) {
if (_isOldModelElement(node.element2)) {
rule.reportLintForToken(node.name2);
}
}

@override
void visitSimpleIdentifier(SimpleIdentifier node) {
var element = node.staticType?.element3;
if (_isOldElementModel(element)) {
rule.reportLint(node);
if (node.parent case MethodInvocation invocation) {
if (invocation.methodName == node) {
return;
}
}
}

static bool _isOldElementModel(Element2? element) {
var firstFragment = element?.firstFragment;
if (firstFragment != null) {
var libraryFragment = firstFragment.libraryFragment;
var uriStr = libraryFragment.source.uri.toString();
return const {
'package:analyzer/dart/element/element.dart',
}.contains(uriStr);
if (_isOldModelType(node.staticType)) {
rule.reportLint(node);
}
return false;
}
}

Expand Down
Loading

0 comments on commit 855bd9a

Please sign in to comment.