Is there any way to check whether constructor argument is const?

57 views
Skip to first unread message

Denis Grafov

unread,
Sep 29, 2021, 2:25:13 PM9/29/21
to Dart Analyzer Discussion
Hello, team!
I'm working on lint rule, which allows to replace final BorderRadius.circular(8) with BorderRadius.all(Radius.circular(8)), which is const.

For this case I use visitInstanceCreationExpression. (see attachment)
Снимок экрана 2021-09-29 в 20.58.36.png

As you can see, if argument is Literal,  we add this expression to list of linted expressions.
But, if the argument is SimpleIdentifier, we should visit it's instance creation somehow. This should tell us if this instance is const.
How can I check if this instance is const? Or is there any other way to do it? 

Linting example:
Снимок экрана 2021-09-29 в 21.14.12.png

Brian Wilkerson

unread,
Sep 29, 2021, 3:10:25 PM9/29/21
to Dart Analyzer Discussion
As an aside, if you're writing this lint to be part of the `linter` package, then you can also open an issue in that repo with questions like this, or open an issue to propose the lint in order to get feedback from the Flutter team on any issues that you might need to take into account when writing it.

How can I check if this instance is const? Or is there any other way to do it?

You should be able to ask the `SimpleIdentifier` for its `staticElement`. The element that's returned could be either a `VariableElement` (if the variable is a local variable or parameter) or a `PropertyAccessorElement` is the variable is a field or top-level variable (in which case what was actually referenced is the getter). In the latter case you can ask the `PropertyAccessorElement` for it's `variable`. In either case you should now have a `VariableElement`, and you can ask the variable whether it `isConst`.

I'll also note that if you check for `Identifier` rather than `SimpleIdentifier` (on line 23) then the lint will also be able to catch cases where the argument is a variable that's imported using a prefix.

If you want it to catch cases where the argument is a static field then you'll need another branch in that if-else that looks at `PropertyAccess` nodes.

--
You received this message because you are subscribed to the Google Groups "Dart Analyzer Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to analyzer-discu...@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/analyzer-discuss/78617cd2-2a34-4abb-9e24-4fb2092979c5n%40dartlang.org.

Denis Grafov

unread,
Sep 30, 2021, 4:42:12 AM9/30/21
to Dart Analyzer Discussion, brianwilkerson
Thanks!
Actually, I am contributing to dart-code-metrics package.
SimpleIdentifier's staticElement helped me with BorderRadius.circular(_value).

But, I have a question about BinaryExpression:

I should check, wherer result of binary expression is const.

Example:
ClipRRect(borderRadius: BorderRadius.circular(_constValue - _constValue)), // LINT
ClipRRect(borderRadius: BorderRadius.circular(_constValue - _finalValue)),

I wrote some code, but it doesn't work the way i thought.
Снимок экрана 2021-09-30 в 11.32.09.png
My thought was to use element's isConstantEvaluated.

But, (_constValue - _finalValue)'s isConstantEvaluated returns true.
So, I get false positive linting if binary expression result is not a const.

Is there any other way to check whether result of binary expression is const?
среда, 29 сентября 2021 г. в 22:10:25 UTC+3, brianwilkerson:

Brian Wilkerson

unread,
Sep 30, 2021, 2:05:48 PM9/30/21
to Denis Grafov, Konstantin Shcheglov, Phil Quitslund, Dart Analyzer Discussion
Actually, I am contributing to dart-code-metrics package.

Then this is definitely the better place to have asked the question.

My thought was to use element's isConstantEvaluated.

I believe that method returns `true` if the parameter has a default value and the default value has been computed. But in any case, it doesn't have anything to do with the argument expression. The element represents the parameter of the constructor, not the argument at an invocation site. If you had two invocations of the same constructor with two different argument expressions, and you asked each argument expression for their `staticParameterElement`, you'd get the same object returned for both.

Is there any other way to check whether result of binary expression is const?

No, unfortunately there isn't. It's something we've wanted for a couple of our own lints as well, but we haven't yet implemented the check.

The closest we have is the method `LinterContext.canBeConst`, but that only tells you whether it's safe to insert `const` before the expression, which for a `BinaryExpression` will always return `false`.

Denis Grafov

unread,
Oct 1, 2021, 4:40:56 AM10/1/21
to Dart Analyzer Discussion, brianwilkerson, Dart Analyzer Discussion
Allright, thank you for letting me know!

четверг, 30 сентября 2021 г. в 21:05:48 UTC+3, brianwilkerson:
Reply all
Reply to author
Forward
0 new messages