Skip to content

proposal: nesting_too_deepΒ #57135

@gardenofwine

Description

@gardenofwine

nesting_too_deep

Description

Limit the amount of prefix tabs/spaces in lines of code, by limiting nesting. Flutter widget code can sometimes become nested to a level where lines of code become prefixed by a considerable amount of tabs/spaces.
combined with a linter such as lines_longer_than_80_chars, even short code lines would have to be broken up to multiple lines - so they won't exceed the 80 character limit.

Details

Below is an example of deeply nested code from the Flutter Constraints documentation. What might otherwise be code that is easy to read and occupy one line of code

TextStyle(color: Colors.blue[900], fontStyle: FontStyle.italic)

Has to be broken down to 3 lines, making the code less readable. The same code can be refactored with helper functions, to reduce nesting.

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Layout Article',
      home: SafeArea(
        child: Material(
          color: Colors.black,
          child: FittedBox(
            child: Container(
              width: 400,
              height: 670,
              color: const Color(0xFFCCCCCC),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Expanded(
                      child: ConstrainedBox(
                          constraints: const BoxConstraints.tightFor(
                              width: double.infinity, height: double.infinity),
                          child: widget.examples[count - 1])),
                  Container(
                    height: 50,
                    width: double.infinity,
                    color: Colors.black,
                    child: SingleChildScrollView(
                      scrollDirection: Axis.horizontal,
                      child: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          for (int i = 0; i < widget.examples.length; i++)
                            Container(
                              width: 58,
                              padding: const EdgeInsets.only(left: 4, right: 4),
                              child: button(i + 1),
                            ),
                        ],
                      ),
                    ),
                  ),
                  Container(
                    height: 273,
                    color: Colors.grey[50],
                    child: Scrollbar(
                      child: SingleChildScrollView(
                        key: ValueKey(count),
                        child: Padding(
                          padding: const EdgeInsets.all(10),
                          child: Column(
                            children: [
                              Center(child: Text(code)),
                              const SizedBox(height: 15),
                              Text(
                                explanation,
                                style: TextStyle(
                                    color: Colors.blue[900],
                                    fontStyle: FontStyle.italic),
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

Kind

Style advice

Bad Examples

See description for a code that could trigger the linter

Good Examples

  Widget _count() {
    return Expanded(
        child: ConstrainedBox(
            constraints: const BoxConstraints.tightFor(
                width: double.infinity, height: double.infinity),
            child: widget.examples[count - 1]));
  }

  Widget _buttons() {
    return Container(
      height: 50,
      width: double.infinity,
      color: Colors.black,
      child: SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            for (int i = 0; i < widget.examples.length; i++)
              Container(
                width: 58,
                padding: const EdgeInsets.only(left: 4, right: 4),
                child: button(i + 1),
              ),
          ],
        ),
      ),
    );
  }

  Widget _explanation() {
    return Container(
      height: 273,
      color: Colors.grey[50],
      child: Scrollbar(
        child: SingleChildScrollView(
          key: ValueKey(count),
          child: Padding(
            padding: const EdgeInsets.all(10),
            child: Column(
              children: [
                Center(child: Text(code)),
                const SizedBox(height: 15),
                Text(
                  explanation,
                  style: TextStyle(
                      color: Colors.blue[900], fontStyle: FontStyle.italic),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Layout Article',
      home: SafeArea(
        child: Material(
          color: Colors.black,
          child: FittedBox(
            child: Container(
              width: 400,
              height: 670,
              color: const Color(0xFFCCCCCC),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  _count(),
                  _buttons(),
                  _explanation(),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

Discussion

Discussion checklist

  • [x ] List any existing rules this proposal modifies, complements, overlaps or conflicts with.
  • [x ] List any relevant issues (reported here, the SDK Tracker, or elsewhere).
  • [x ] If there's any prior art (e.g., in other linters), please add references here.
  • [x ] If this proposal corresponds to Effective Dart or Flutter Style Guide advice, please call it out. (If there isn't any corresponding advice, should there be?)
  • [x ] If this proposal is motivated by real-world examples, please provide as many details as you can. Demonstrating potential impact is especially valuable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3A lower priority bug or feature requestarea-devexpFor issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages.devexp-linterIssues with the analyzer's support for the linter packagelinter-lint-proposallinter-status-pendingtype-enhancementA request for a change that isn't a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions