Skip to content

Overlap between FormalParameterList.leftDelimiter and FormalParameterList.parameters #60445

Open
@stereotype441

Description

@stereotype441

A nice property of nearly all analyzer AstNode types is that the set of Token, AstNode, and NodeList objects that are pointed to by the AstNode always covers non-overlapping ranges of tokens.

However, FormalParameterList is an exception, because FormalParameterList.parameters is a NodeList of all the parameters (including required positional, optional positional, and named parameters), and FormalParameterList.leftDelimiter is the { or [ token that precedes the first optional positional or named parameter. Therefore, FormalParameterList.leftDelimiter, when present, is a token that is within the span of tokens pointed to by FormalParameterList.parameters.

An unfortunate consequence of this is that the lists returned by FormalParameterList.childEntities and FormalParameterListImpl.namedChildEntities behave oddly: they expand out the parameters node list into its constituent elements, and insert the leftDelimiter at the appropriate spot in the list.

This seems confusing and bug-prone to me. I think we should consider changing the FormalParameterList AST representation from this:

class FormalParameterList {
  Token get leftParenthesis;
  NodeList<FormalParameter> get parameters;
  Token? get leftDelimiter;
  Token? get rightDelimiter;
  Token get rightParenthesis;
}

To something more like this:

class FormalParameterList {
  Token get leftParenthesis;
  NodeList<FormalParameter> get requiredPositionalParameters;
  OptionalOrNamedFormalParameters? get optionalPositionalParameters;
  OptionalOrNamedFormalParameters? get namedParameters;
  Token get rightParenthesis;
}

class OptionalOrNamedFormalParameters {
  Token get leftDelimiter;
  NodeList<FormalParameter> get parameters;
  Token get rightDelimiter;
}

In addition to avoiding overlap between nodelists and tokens, this would have the advantage of more closely following the grammar of the language spec, and would be potentially more future-proof if we ever decide to allow a single function to have both optional positional and named parameters.

Metadata

Metadata

Assignees

No one assigned

    Labels

    analyzer-apiIssues that impact the public API of the analyzer packageanalyzer-technical-debtarea-dart-modelFor issues related to conformance to the language spec in the parser, compilers or the CLI analyzer.dart-model-analyzer-packageIssues related to package:analyzer

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions