Skip to content

[Primary Constructors] Language Tests in tests/language #61687

@kallentu

Description

@kallentu

Write up language tests for the tests/language repository.

Test Tracker

https://docs.google.com/spreadsheets/d/1azvhJATeGYFZxMFxAGkeVBxnGzrU1D8nohbH25jcTgw/edit?usp=sharing

Tests to make

  • In-header syntax
  • A class that has a declaring header constructor cannot have any other non-redirecting generative constructors
  • A declaring header constructor is also known as a primary constructor, because all other generative constructors must invoke the primary one (directly or indirectly).
  • An empty class body, {}, can be replaced by ;.
  • one instance variable for each formal parameter in said parameter list that has the declaring modifier var or final.
  • all other declarations of formal parameters as final will be a compile-time error.
  • a regular (non-declaring) formal parameter can not use the syntax var name, it must have a type (T name) or the type must be omitted (name).
  • A declaring header constructor can have a body and/or an initializer list. These elements are placed in the class body in a declaration that provides "the rest" of the constructor declaration which is given in the header.
  • There is no way to indicate that the instance variable declarations should have the modifiers late or external (because formal parameters cannot have those modifiers). This omission is not seen as a problem in this proposal: They can be declared using the same syntax as today, and initialization, if any, can be done in a constructor body.
  • Declaring constructors can have super parameters.
  • Declaring constructors can have named parameters, required or not.
  • Declaring constructors can be constant.
  • Declaring constructors can have assertions
  • Declaring constructors can have optional parameters
    • These optional parameters can have default values (which must be constant)
    • We can omit the type of an optional parameter with a default value, in which case the type is inferred from the default value:
  • The modifier final on a parameter in a declaring constructor specifies that the instance variable declaration which is induced by this declaring constructor parameter is final.
  • In the case where the declaration is an extension type, the modifier final on the representation variable can be specified or omitted.
  • The class header can have additional elements, just like class headers where there is no primary constructor (like generics, extends, implements, with)
  • When using a declaring body constructor it is possible to use an initializer list in order to invoke a superconstructor and/or initialize some explicitly declared instance variables with a computed value. The declaring header constructor can have the same elements, but they are declared in the class body.
  • When there is a primary constructor, we can allow the initializing expressions of non-late instance variables to access the constructor parameters
  • Subclassing a class with primary constructors and overriding fields
  • factory() => C(); is a factory constructor whose name is the name of the enclosing class, and not a method.

Syntax

  • It is an error to have a declaring constructor in the class body, but no declaring parameter list, neither in the header nor in the body.
    • A compile-time error occurs if D includes a that does not contain a , and the body of D contains a that does not contain a .
  • The keyword const can be specified in the class header when it contains a primary constructor, and in this case const can not be specified in the part of the primary constructor that occurs in the body (that is, the declaration that starts with this and contains an initializer list and/or a constructor body, if any).
  • A compile-time error occurs if a has the modifier required as well as a default value.
  • Mixins cannot have declaring headerconstructors.
  • factory shorter syntax
  • new shorter syntax

Static Processing

  • new rather than the class name in declarations of ordinary (non-declaring) constructors
  • A compile-time error occurs if a class, enum, or extension type has a primary constructor whose name is also the name of a constructor declared in the body.
  • A compile-time error occurs if the body of D contains a non-redirecting generative constructor, unless D is an extension type.
  • If D is an extension type, it is a compile-time error if D does not contain a declaring constructor that has exactly one declaring parameter which is final.
  • A compile-time error occurs if the name of the primary constructor is the same as the name of a constructor (declaring or not) in the body.

Errors
The following errors apply to formal parameters of a declaring constructor, be it in the header or in the body. Let p be a formal parameter of a declaring constructor in a class, enum, or extension type declaration D named C:

  • A compile-time error occurs if p contains a term of the form this.v, or super.v where v is an identifier, and p has the modifier covariant. For example, required covariant int this.v is an error. The reason for this error is that the modifier covariant must be specified on the declaration of v which is known to exist, not on the parameter.
  • A compile-time error occurs if p has both of the modifiers covariant and final, also if the latter is implicitly induced (which can occur in a primary constructor of an extension type declaration). A final instance variable cannot be covariant, because being covariant is a property of the setter.
  • A compile-time error occurs if p has the modifier covariant, but not var. This parameter does not induce a setter.
  • Conversely, it is not an error for the modifier covariant to occur on a declaring formal parameter p of a declaring constructor. This extends the existing allowlist of places where covariant can occur.

Transformation in the spec

  • Read it over again. Pull out anything that might need to be tested.

Tests that we removed:

  • In-body syntax
  • A declaring body constructor can have a body and an initializer list as well as initializing formals and super parameters, just like other constructors in the body.
  • It is an error to have a declaring parameter list both in the header and in the body.
  • A compile-time error occurs if a class contains two or more declarations of a declaring constructor.
    • The meaning of a declaring constructor is defined in terms of rewriting it to a body constructor (a regular one, not declaring) and zero or more instance variable declarations. This implies that there is a class body when there is a declaring constructor. We do not wish to define declaring constructors such that the absence or presence of a declaring constructor can change the length of the superclass chain, and hence class C; has a class body just like class C(int i); and just like class C extends Object {}, and all three of them have Object as their direct superclass.
  • Mixins cannot have declaring body constructors.

Metadata

Metadata

Assignees

Labels

area-languageDart language related items (some items might be better tracked at github.com/dart-lang/language).feature-primary-constructorsImplementation of the primary constructors feature. Otherwise known as declaring constructors.type-implementationInitial implementation of a language or library feature

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions