[analysis_server] Dot shorthands: Update prefer_const_constructors lint.
Now that `DotShorthandsConstructorInvocation`'s `canBeConst` is updated, we can also update the `prefer_const_constructors` lint. We skip the lint when we have the `@literal` metadata on the constructor since it's already reporting a warning here: https://dart-review.googlesource.com/c/sdk/+/434881. Similar to instance creation expressions, we also skip reporting a lint if we're instantiating the `Object` class. Otherwise, if the constructor we're calling with the shorthand is const and we can const-ify it, we report this lint. Added unit tests. Fixes: https://github.com/dart-lang/sdk/issues/60911 Bug: https://github.com/dart-lang/sdk/issues/60893 Change-Id: Ib4bcba629f60e0dbff110080918adfacfb1ba5d2 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/434981 Commit-Queue: Kallen Tu <kallentu@google.com> Reviewed-by: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
@@ -24,6 +24,7 @@ class PreferConstConstructors extends LintRule {
|
||||
@override
|
||||
void registerNodeProcessors(NodeLintRegistry registry, RuleContext context) {
|
||||
var visitor = _Visitor(this);
|
||||
registry.addDotShorthandConstructorInvocation(this, visitor);
|
||||
registry.addInstanceCreationExpression(this, visitor);
|
||||
}
|
||||
}
|
||||
@@ -33,6 +34,30 @@ class _Visitor extends SimpleAstVisitor<void> {
|
||||
|
||||
_Visitor(this.rule);
|
||||
|
||||
@override
|
||||
void visitDotShorthandConstructorInvocation(
|
||||
DotShorthandConstructorInvocation node,
|
||||
) {
|
||||
if (node.isConst) return;
|
||||
|
||||
var element = node.constructorName.element;
|
||||
if (element is! ConstructorElement) return;
|
||||
if (!element.isConst) return;
|
||||
|
||||
// Handled by an analyzer warning.
|
||||
if (element.metadata.hasLiteral) return;
|
||||
|
||||
var enclosingElement = element.enclosingElement;
|
||||
if (enclosingElement is ClassElement && enclosingElement.isDartCoreObject) {
|
||||
// Skip lint for `new Object()`, because it can be used for ID creation.
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.canBeConst) {
|
||||
rule.reportAtNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void visitInstanceCreationExpression(InstanceCreationExpression node) {
|
||||
if (node.isConst) return;
|
||||
|
||||
@@ -74,6 +74,18 @@ var a = A({});
|
||||
);
|
||||
}
|
||||
|
||||
test_canBeConst_dotShorthand() async {
|
||||
await assertDiagnostics(
|
||||
r'''
|
||||
class A {
|
||||
const A();
|
||||
}
|
||||
A a = .new();
|
||||
''',
|
||||
[lint(31, 6)],
|
||||
);
|
||||
}
|
||||
|
||||
test_canBeConst_explicitTypeArgument_dynamic() async {
|
||||
await assertDiagnostics(
|
||||
r'''
|
||||
@@ -275,6 +287,15 @@ var a = A();
|
||||
''');
|
||||
}
|
||||
|
||||
test_cannotBeConst_notConstConstructor_dotShorthand() async {
|
||||
await assertNoDiagnostics(r'''
|
||||
class A {
|
||||
A();
|
||||
}
|
||||
A a = .new();
|
||||
''');
|
||||
}
|
||||
|
||||
test_cannotBeConst_stringLiteralArgument_withInterpolation() async {
|
||||
await assertNoDiagnostics(r'''
|
||||
class A {
|
||||
@@ -363,6 +384,28 @@ K k() {
|
||||
);
|
||||
}
|
||||
|
||||
test_extraPositionalArgument_dotShorthands() async {
|
||||
await assertDiagnostics(
|
||||
r'''
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
class K {
|
||||
@literal
|
||||
const K();
|
||||
}
|
||||
|
||||
K k() {
|
||||
K kk = .new();
|
||||
return kk;
|
||||
}
|
||||
''',
|
||||
[
|
||||
// No lint
|
||||
error(WarningCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR, 88, 6),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
test_isConst_intLiteralArgument() async {
|
||||
await assertNoDiagnostics(r'''
|
||||
class A {
|
||||
@@ -386,6 +429,12 @@ var a = const A();
|
||||
test_objectConstructorCall() async {
|
||||
await assertNoDiagnostics(r'''
|
||||
var x = Object();
|
||||
''');
|
||||
}
|
||||
|
||||
test_objectConstructorCall_dotShorthand() async {
|
||||
await assertNoDiagnostics(r'''
|
||||
Object x = .new();
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user