Using `VariableElement.computeConstantValue`, can we read fields from superclasses?

38 views
Skip to first unread message

dark...@gmail.com

unread,
Feb 12, 2024, 6:40:01 AM2/12/24
to Dart Analyzer Discussion
Hello!

I was trying to use VariableElement.computeConstantValue to obtain some information about a constant I have full control over.


I was successfully able to read direct field of a given variable. But when trying to read fields coming from the superclass, I seem to always get `null`.
Is it supposed to be possible?

Thanks!

dark...@gmail.com

unread,
Feb 12, 2024, 6:45:19 AM2/12/24
to Dart Analyzer Discussion, dark...@gmail.com
For example, consider:

class Foo extends Bar {
const Foo(this.a, super.b);

final int a;
}

class Bar {
const Bar(this.b);

final int b;
}

const value = Foo(1, 2);

When trying to inspect `value`, calling `DartObject.toString()` on it gives:
Foo ((super) = Bar (b = int (2)); a = int (1))
This suggests that both fields were parsed.

But `getField('a')` returns `1`, yet `getField('b')` returns `null`

dark...@gmail.com

unread,
Feb 12, 2024, 6:54:32 AM2/12/24
to Dart Analyzer Discussion, dark...@gmail.com
Ignore me, I found the solution by adding some prints in the SDK's source.

It seems that we have to do:
`fooObject.getField('(super)')?.getField('b');`

However, I couldn't find this documented anywhere. I thin it'd be variable information to add on `getField`'s dartdoc

Brian Wilkerson

unread,
Feb 12, 2024, 1:02:17 PM2/12/24
to analyzer...@dartlang.org
It's a bit unfortunate. I believe the reason is because of the possibility of a field in a subclass shadowing a field in a superclass and the occasional need (maybe only in tests) to check that the superclass field has the right value.

It does seem like there could be a better API that would make the common case (where there is no shadowing) easier.

--
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/2b7fb20c-f401-4de9-91e8-b9bc5f986d36n%40dartlang.org.

dark...@gmail.com

unread,
Feb 12, 2024, 1:33:33 PM2/12/24
to Dart Analyzer Discussion, brianwilkerson
I ended-up adding an extension method that does a simple recursion:

extension DartObjectSuperField on DartObject {
DartObject? getFieldInThisOrSuper(String name) {
final field = getField(name);
if (field != null) return field;

final superField = getField('(super)');
if (superField == null) return null;

return superField.getFieldInThisOrSuper(name);
}
}


I'm mainly worried about discoverability. That `(super)` syntax isn't well documented.

To find it, I ended up putting a print in DartObjectImpl, to print GenericState._fieldMap.keys

Brian Wilkerson

unread,
Feb 12, 2024, 2:14:19 PM2/12/24
to analyzer...@dartlang.org
I created https://github.com/dart-lang/sdk/issues/54895 so that we could discuss various possible improvements without loosing the thread.

Reply all
Reply to author
Forward
0 new messages