Skip to content

Commit

Permalink
Version 3.7.0-127.0.dev
Browse files Browse the repository at this point in the history
Merge c9391d7 into dev
  • Loading branch information
Dart CI committed Nov 9, 2024
2 parents 45aac6c + c9391d7 commit 21f0664
Show file tree
Hide file tree
Showing 11 changed files with 241 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ class ReplaceWithVar extends ResolvedCorrectionProducer {
var grandparent = parent?.parent;
if (parent is VariableDeclarationList &&
(grandparent is VariableDeclarationStatement ||
grandparent is ForPartsWithDeclarations)) {
grandparent is ForPartsWithDeclarations ||
grandparent is TopLevelVariableDeclaration ||
grandparent is FieldDeclaration)) {
var variables = parent.variables;
if (variables.length != 1) {
return;
Expand Down Expand Up @@ -159,6 +161,10 @@ class ReplaceWithVar extends ResolvedCorrectionProducer {
return true;
}
return false;
} else if (parent is TopLevelVariableDeclaration) {
return _canConvertVariableDeclarationList(parent.variables);
} else if (parent is FieldDeclaration) {
return _canConvertVariableDeclarationList(parent.fields);
}
parent = parent.parent;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2199,7 +2199,7 @@ LintCode.omit_local_variable_types:
LintCode.omit_obvious_local_variable_types:
status: hasFix
LintCode.omit_obvious_property_types:
status: needsEvaluation
status: hasFix
LintCode.one_member_abstracts:
status: noFix
notes: |-
Expand Down Expand Up @@ -2362,7 +2362,7 @@ LintCode.sort_unnamed_constructors_first:
LintCode.specify_nonobvious_local_variable_types:
status: hasFix
LintCode.specify_nonobvious_property_types:
status: needsEvaluation
status: hasFix
LintCode.test_types_in_equals:
status: noFix
LintCode.throw_in_finally:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ final _builtInLintProducers = <LintCode, List<ProducerGenerator>>{
LinterLintCode.null_closures: [ReplaceNullWithClosure.new],
LinterLintCode.omit_local_variable_types: [ReplaceWithVar.new],
LinterLintCode.omit_obvious_local_variable_types: [ReplaceWithVar.new],
LinterLintCode.omit_obvious_property_types: [ReplaceWithVar.new],
LinterLintCode.prefer_adjacent_string_concatenation: [RemoveOperator.new],
LinterLintCode.prefer_collection_literals: [
ConvertToMapLiteral.new,
Expand Down Expand Up @@ -460,6 +461,9 @@ final _builtInLintProducers = <LintCode, List<ProducerGenerator>>{
LinterLintCode.specify_nonobvious_local_variable_types: [
AddTypeAnnotation.bulkFixable,
],
LinterLintCode.specify_nonobvious_property_types: [
AddTypeAnnotation.bulkFixable,
],
LinterLintCode.type_annotate_public_apis: [AddTypeAnnotation.bulkFixable],
LinterLintCode.type_init_formals: [RemoveTypeAnnotation.other],
LinterLintCode.type_literal_in_constant_pattern: [
Expand Down Expand Up @@ -1085,8 +1089,8 @@ final _builtInNonLintProducers = <ErrorCode, List<ProducerGenerator>>{
// updated so that only the appropriate subset is generated.
QualifyReference.new,
],
CompileTimeErrorCode
.UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE: [
CompileTimeErrorCode.UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE:
[
// TODO(brianwilkerson): Consider adding fixes to create a field, getter,
// method or setter. The existing producers would need to be updated so
// that only the appropriate subset is generated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ void main() {
defineReflectiveTests(OmitLocalVariableTypesLintTest);
defineReflectiveTests(OmitObviousLocalVariableTypesLintBulkTest);
defineReflectiveTests(OmitObviousLocalVariableTypesLintTest);
defineReflectiveTests(OmitObviousPropertyTypesLintBulkTest);
defineReflectiveTests(OmitObviousPropertyTypesLintTest);
});
}

Expand Down Expand Up @@ -654,3 +656,187 @@ String f() {
''');
}
}

@reflectiveTest
class OmitObviousPropertyTypesLintBulkTest extends BulkFixProcessorTest {
@override
String get lintCode => LintNames.omit_obvious_property_types;

Future<void> test_singleFile() async {
await resolveTestCode('''
List<String> l = ['a'];
class A {
static List<String> l = ['a'];
}
''');
await assertHasFix('''
var l = <String>['a'];
class A {
static var l = <String>['a'];
}
''');
}
}

@reflectiveTest
class OmitObviousPropertyTypesLintTest extends FixProcessorLintTest {
@override
FixKind get kind => DartFixKind.REPLACE_WITH_VAR;

@override
String get lintCode => LintNames.omit_obvious_property_types;

Future<void> test_generic_instanceCreation_cascade() async {
await resolveTestCode('''
Set<String> s = Set<String>()..addAll([]);
''');
await assertHasFix('''
var s = Set<String>()..addAll([]);
''');
}

Future<void> test_generic_instanceCreation_withArguments() async {
await resolveTestCode('''
final C<int> c = C<int>();
class C<T> {}
''');
await assertHasFix('''
final c = C<int>();
class C<T> {}
''');
}

Future<void> test_generic_listLiteral() async {
await resolveTestCode('''
List<num> l = <num>[x];
int x = 2 + 'Not obvious'.length;
''');
await assertHasFix('''
var l = <num>[x];
int x = 2 + 'Not obvious'.length;
''');
}

Future<void> test_generic_listLiteral_const() async {
await resolveTestCode('''
const List<String> values = const ['a'];
''');
await assertHasFix('''
const values = const <String>['a'];
''');
}

Future<void> test_generic_mapLiteral() async {
await resolveTestCode('''
Map<String, double> m = {'a': 1.5};
''');
await assertHasFix('''
var m = <String, double>{'a': 1.5};
''');
}

Future<void> test_generic_mapLiteral_const() async {
await resolveTestCode('''
const Map<String, double> m = {'a': 1.5};
''');
await assertHasFix('''
const m = <String, double>{'a': 1.5};
''');
}

Future<void> test_generic_setLiteral() async {
await resolveTestCode('''
Set<double> s = {1.5};
''');
await assertHasFix('''
var s = <double>{1.5};
''');
}

Future<void> test_generic_setLiteral_cascade() async {
await resolveTestCode('''
Set<String> s = {'a'}..addAll([]);
''');
await assertHasFix('''
var s = <String>{'a'}..addAll([]);
''');
}

Future<void> test_generic_setLiteral_const() async {
await resolveTestCode('''
const Set<String> s = const {'a'};
''');
await assertHasFix('''
const s = const <String>{'a'};
''');
}

Future<void> test_generic_setLiteral_recordType() async {
await resolveTestCode('''
Set<(double, double)> s = {(1.5, 2.5)};
''');
await assertHasFix('''
var s = <(double, double)>{(1.5, 2.5)};
''');
}

Future<void> test_simple() async {
await resolveTestCode('''
String s = '';
''');
await assertHasFix('''
var s = '';
''');
}

Future<void> test_simple_const() async {
await resolveTestCode('''
const String s = '';
''');
await assertHasFix('''
const s = '';
''');
}

Future<void> test_simple_final() async {
await resolveTestCode('''
final String s = '';
''');
await assertHasFix('''
final s = '';
''');
}

Future<void> test_simple_recordType() async {
await resolveTestCode(r'''
(double, String) r = (3.5, '');
''');
await assertHasFix(r'''
var r = (3.5, '');
''');
}

Future<void> test_top_level() async {
await resolveTestCode('''
List<String> list = ['a'];
''');
await assertHasFix('''
var list = <String>['a'];
''');
}

Future<void> test_top_level_final() async {
await resolveTestCode('''
final List<String> list = ['a'];
''');
await assertHasFix('''
final list = <String>['a'];
''');
}
}
7 changes: 2 additions & 5 deletions pkg/analyzer_utilities/lib/tools.dart
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,8 @@ class DartFormat {
static String get _dartPath => Platform.resolvedExecutable;

static void formatFile(File file) {
var result = Process.runSync(_dartPath, [
'format',
'--language-version=latest',
file.path
]);
var result = Process.runSync(
_dartPath, ['format', '--language-version=latest', file.path]);
_throwIfExitCode(result);
}

Expand Down
1 change: 0 additions & 1 deletion pkg/linter/lib/src/rules/omit_local_variable_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ class OmitLocalVariableTypes extends LintRule {
List<String> get incompatibleRules => const [
LintNames.always_specify_types,
LintNames.specify_nonobvious_local_variable_types,
LintNames.specify_nonobvious_property_types,
];

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,19 @@ import '../analyzer.dart';
import '../extensions.dart';
import '../util/obvious_types.dart';

const _desc = r'Specify non-obvious type annotations for local variables.';
const _desc =
r'Specify non-obvious type annotations for top-level and static variables.';

class SpecifyNonObviousPropertyTypes extends LintRule {
SpecifyNonObviousPropertyTypes()
: super(
name: 'specify_nonobvious_property_types',
name: LintNames.specify_nonobvious_property_types,
description: _desc,
state: State.experimental(),
);

@override
List<String> get incompatibleRules => const ['omit_local_variable_types'];
List<String> get incompatibleRules => const [];

@override
LintCode get lintCode => LinterLintCode.specify_nonobvious_property_types;
Expand Down
27 changes: 25 additions & 2 deletions pkg/linter/lib/src/util/obvious_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,20 @@ extension DartTypeExtensions on DartType? {
}
return null;
}

({DartType? key, DartType? value})? get keyValueTypeOfMap {
var self = this; // Enable promotion.
if (self == null) return null;
if (self is InterfaceType) {
var mapInterfaces =
self.implementedInterfaces.where((type) => type.isDartCoreMap);
if (mapInterfaces.length == 1) {
var [key, value] = mapInterfaces.first.typeArguments;
return (key: key, value: value);
}
}
return null;
}
}

extension ExpressionExtensions on Expression {
Expand Down Expand Up @@ -118,8 +132,17 @@ extension ExpressionExtensions on Expression {
return false;
}
}
var theSelfElementType = self.staticType.elementTypeOfIterable;
return theSelfElementType == theObviousType;
if (theObviousType != null) {
var theSelfElementType = self.staticType.elementTypeOfIterable;
return theSelfElementType == theObviousType;
} else if (theObviousKeyType != null && theObviousValueType != null) {
var keyValueTypes = self.staticType.keyValueTypeOfMap;
if (keyValueTypes == null) return false;
return theObviousKeyType == keyValueTypes.key &&
theObviousValueType == keyValueTypes.value;
} else {
return false;
}
case RecordLiteral():
for (var expression in self.fields) {
if (!expression.hasObviousType) return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ main() {
@reflectiveTest
class SpecifyNonObviousPropertyTypesTest extends LintRuleTest {
@override
String get lintRule => 'specify_nonobvious_property_types';
String get lintRule => LintNames.specify_nonobvious_property_types;

test_as_dynamic_instance() async {
await assertNoDiagnostics(r'''
Expand Down
Loading

0 comments on commit 21f0664

Please sign in to comment.