Skip to content

Getters don't show up consistently for inline values #5550

Closed

Description

@DanTup
import 'dart:developer';

var bar3 = 1;

class A {
  String get bar1 => 'bar';
  var bar2 = 1;

  void foo() {
    print(this.bar1);
    print(this.bar2);
    print(bar1);
    print(bar2);
    print(bar3);
    var a = A();
    print(a.bar1);
    print(a.bar2);
    print(A().bar1);
    print(A().bar2);

    debugger();
  }
}

main() {
  A().foo();
}

Image

Activity

  1. added this to the On Deck milestone on Jun 16, 2025
  2. FMorschel commented on Jun 16, 2025

    @FMorschel
    Contributor

    I'm not sure we want to show getters. There shouldn't be side effects, but since they are getters, there can be.

    Maybe @bwilkerson can weigh in.

  3. DanTup commented on Jun 16, 2025

    @DanTup
    MemberAuthor

    Yeah, we only show getters when you have dart.experimentalInlineValuesProperties enabled (and I'm still not entirely sure if we'll ultimately want to ship this on-by-default). But if we do/might, then we should handle all of the getters shown above, and not only the ones that are qualified like instance.getter).

  4. bwilkerson commented on Jun 16, 2025

    @bwilkerson

    I agree that we want to be consistent and either show all getters or none of them.

    I think we show getters in the debugger, so that argues in favor of showing them (although the debugger only displays getters for an object when you expand the object, so there's more user control). What are the reasons we might not want to?

    • possible side effects (not worse than in the debugger)
    • are there performance concerns?
    • are we concerned about visual clutter?
  5. DanTup commented on Jun 16, 2025

    @DanTup
    MemberAuthor

    My original idea was that we'd keep it behind a flag for a while to get feedback, then switch to using the same flag (which defaults to true) as for showing getters in the debugger.

    However, I don't think these are completely equivalent for the reason you give - the debugger views are generally user-initiated (eg. you expand the parent object), so here there is an increased chance of triggering unexpected side-effects. I don't know if side effects in getters are common enough that it would be a real problem though. I suggest we continue to iterate (eg. fixing the bugs above) and then encourage more people to try out the flag and provide feedback.

  6. bwilkerson commented on Jun 16, 2025

    @bwilkerson

    That sounds good to me.

  7. modified the milestones: On Deck, v3.130.0 on Feb 4, 2026
  8. DanTup commented on Feb 9, 2026

    @DanTup
    MemberAuthor

    Looking at this again, I'm less sure now that we want to do this here. Yes, we do invoke getters when this setting is enabled, but as far as I can tell from my report here, the place where we're missing this is where there's also an invocation (a constructor in this case):

    A().s;
    

    While we've accepted the side-effects of running getters, I'm less sure about invocations or constructors seems reasonable. Producing an instance of something to read the value for the InlayHint and then throwing it away feels odd, and if you had something like a generated id, the one you see on the inlay hint wouldn't by the same as the one read in the code.

    So, my feeling is that we don't do this, and we draw the line at only ever invoking getters.

    Of course, I'm interested in others opinions too.

  9. FMorschel commented on Feb 9, 2026

    @FMorschel
    Contributor

    I agree. We could maybe enable this (for instantiation) only when cascades are used?

  10. DanTup commented on Feb 9, 2026

    @DanTup
    MemberAuthor

    We could maybe enable this (for instantiation) only when cascades are used?

    I'm not sure I understand why that's different?

  11. FMorschel commented on Feb 9, 2026

    @FMorschel
    Contributor

    Because usually that is used to assign a variable.

    var v = C()..getter;

    And although doing the above is weird for production, it is a valid way to see the produced value (maybe there is some computation happening).

  12. bwilkerson commented on Feb 9, 2026

    @bwilkerson

    So, my feeling is that we don't do this, and we draw the line at only ever invoking getters.

    I agree.

    Because usually that is used to assign a variable.

    Is the reasoning here that the result of C() is cached (in v) so we could evaluate v.getter to get the value?

    If so, I don't think we want to perform the kind of analysis that would allow us to conclude that the value is cached in a variable in the plugin, and I don't think it would be worth the cost to add a protocol for this purpose to the analysis server.

  13. DanTup commented on Feb 9, 2026

    @DanTup
    MemberAuthor

    and I don't think it would be worth the cost to add a protocol for this purpose to the analysis server.

    LSP does already have support for this - we could return a range with a String expression on it that is different to the code in the range. We haven't implemented anything that does that so far though, we just support:

    1. Variables - where we tell the IDE that some range of source code is the name of a variable that it can find in the Variables data
    2. Expressions - where we tell the IDE that some range of source code is an expression that can be evaluated (the same as typing in Debug Console)

    However, I'm not convinced we should do this for a few reasons:

    1. It would be inconsistent to invoke non-getters in some places and not others. I think evaluating getters (which we do behind a setting named evaluateGettersInDebugViews or similar) is an easily understandable line
    2. We would have to rewrite the expression to use the variable, and I suspect there are many ways of writing expressions that might need handling
    3. As far as I can tell, the only reason to write this code is if getter specifically has side-effects (invoking a stateless getter and throwing the value away seems pointless)? In which case, this kind of code is probably very uncommon (and perhaps a mistake)?
  14. DanTup commented on Feb 11, 2026

    @DanTup
    MemberAuthor

    Closing this for the reasons above, but happy to revisit if there are objections or other ideas.

  15. removed this from the v3.130.0 milestone on Feb 11, 2026
  16. added and removed
    in editorRelates to code editing or language features
    in lsp/analysis serverSomething to be fixed in the Dart analysis server
    on Feb 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions