1
- # Declaring and Primary Constructors
1
+ # Declaring Constructors
2
2
3
3
Author: Erik Ernst
4
4
5
5
Status: Accepted
6
6
7
- Version: 1.9
7
+ Version: 1.10
8
8
9
9
Experiment flag: declaring-constructors
10
10
@@ -243,9 +243,9 @@ constructor parameter is `final`.
243
243
244
244
In the case where the declaration is an ` extension type ` , the modifier
245
245
` final ` on the representation variable can be specified or omitted. Note
246
- that an extension type declaration is specified to use a primary
247
- constructor (in that case there is no other choice, it is in the grammar
248
- rules ):
246
+ that an extension type declaration is specified to use a declaring
247
+ constructor (it is not supported to declare the representation variable
248
+ using a normal instance variable declaration ):
249
249
250
250
``` dart
251
251
// Using a primary constructor.
@@ -619,6 +619,13 @@ constructors as well.
619
619
'const' <constructorName> <formalParameterList>
620
620
| <declaringConstantConstructorSignature>;
621
621
622
+ <constructorName> ::= // Modified rule.
623
+ <typeIdentifierOrNew> ('.' identifierOrNew)?;
624
+
625
+ <typeIdentifierOrNew> ::= // New rule.
626
+ <typeIdentifier>
627
+ | 'new';
628
+
622
629
<declaringConstantConstructorSignature> ::= // New rule.
623
630
'const' 'this' ('.' <identifierOrNew>)? <declaringParameterList>;
624
631
@@ -686,8 +693,8 @@ extension type declaration, together with a declaration in the body that
686
693
contains a ` <declaringConstructorSignature> ` * (which does not contain a
687
694
` <declaringParameterList> ` , because that's an error)* .
688
695
689
- A class declaration whose class body is ` ; ` is treated as a class
690
- declaration whose class body is ` {} ` .
696
+ A class or extension type declaration whose class body is ` ; ` is treated as
697
+ a declaration whose body is ` {} ` .
691
698
692
699
Let _ D_ be a class, extension type, or enum declaration.
693
700
@@ -732,8 +739,19 @@ superclass.*
732
739
A compile-time error occurs if a ` <defaultDeclaringNamedParameter> ` has the
733
740
modifier ` required ` as well as a default value.
734
741
742
+ * Note that the updated grammar rule for ` <constructorName> ` allows
743
+ non-declaring constructors to use ` new ` where the current rules require
744
+ the class name. This is not a necessary part of the declaring constructors
745
+ feature, but it contributes to the overall brevity of Dart programs.*
746
+
747
+
735
748
### Static processing
736
749
750
+ The ability to use ` new ` rather than the class name in declarations of
751
+ ordinary (non-declaring) constructors is purely syntactic. The static
752
+ analysis and meaning of such constructors is identical to the form that
753
+ uses the class name.
754
+
737
755
The name of a primary constructor of the form
738
756
` 'const'? id1 <typeParameters>? <declaringParameterList> ` is ` id1 ` * (that
739
757
is, the same as the name of the class)* .
@@ -874,12 +892,13 @@ reason for this error is that the modifier `covariant` must be specified on
874
892
the declaration of ` v ` which is known to exist, not on the parameter.*
875
893
876
894
A compile-time error occurs if _ p_ has both of the modifiers ` covariant `
877
- and ` final ` . * A final instance variable cannot be covariant, because being
878
- covariant is a property of the setter.*
895
+ and ` final ` , also if the latter is implicitly induced * (which can occur in a
896
+ primary constructor of an extension type declaration)* . * A final instance
897
+ variable cannot be covariant, because being covariant is a property of the
898
+ setter.*
879
899
880
900
A compile-time error occurs if _ p_ has the modifier ` covariant ` , but
881
- neither ` var ` nor ` final ` . * This parameter does not induce an instance
882
- variable, so there is no setter.*
901
+ not ` var ` . * This parameter does not induce a setter.*
883
902
884
903
Conversely, it is not an error for the modifier ` covariant ` to occur on a
885
904
declaring formal parameter _ p_ of a declaring constructor. This extends the
@@ -890,33 +909,36 @@ constructors.
890
909
891
910
The semantics of the declaring constructor is found in the following steps,
892
911
where _ D_ is the class, extension type, or enum declaration in the program
893
- that includes a declaring constructor, and _ D2_ is the result of the
912
+ that includes a declaring constructor _ k _ , and _ D2_ is the result of the
894
913
derivation of the semantics of _ D_ . The derivation step will delete
895
- elements that amount to the declaring constructor; it will add a new
896
- constructor _ k _ ; and it will add zero or more instance variable
914
+ elements that amount to the declaring constructor. Semantically, it will
915
+ add a new constructor _ k2 _ , and it will add zero or more instance variable
897
916
declarations.
898
917
918
+ * Adding program elements 'semantically' implies that this is not a source
919
+ code transformation, it is a way to obtain semantic program elements that
920
+ differ from the ones that are obtained from pre-feature declarations, but
921
+ can be specified in terms of pre-feature declarations.*
922
+
899
923
Where no processing is mentioned below, _ D2_ is identical to _ D_ . Changes
900
924
occur as follows:
901
925
902
- Assume that ` p ` is an optional formal parameter in _ D_ which has the
903
- modifier ` var ` or the modifier ` final ` * (that is, ` p ` is a declaring
904
- parameter)* .
905
-
906
- Assume that the combined member signature for a getter with the same name
907
- as ` p ` from the superinterfaces of _ D_ exists, and has return type ` T ` . In
908
- that case the parameter ` p ` has declared type ` T ` as well.
909
-
910
- * In other words, an instance variable introduced by a declaring parameter
911
- is subject to override inference, just like an explicitly declared instance
912
- variable.*
913
-
914
- Otherwise, assume that ` p ` does not have a declared type, but it does have
915
- a default value whose static type in the empty context is a type (not a
916
- type schema) ` T ` which is not ` Null ` . In that case ` p ` is considered to
917
- have the declared type ` T ` . When ` T ` is ` Null ` , ` p ` is considered to have
918
- the declared type ` Object? ` . If ` p ` does not have a declared type nor a
919
- default value then ` p ` is considered to have the declared type ` Object? ` .
926
+ Let ` p ` be a formal parameter in _ k_ which has the modifier ` var ` or the
927
+ modifier ` final ` * (that is, ` p ` is a declaring parameter)* .
928
+
929
+ Consider the situation where ` p ` has no type annotation:
930
+ - if combined member signature for a getter with the same name as ` p ` from
931
+ the superinterfaces of _ D_ exists and has return type ` T ` , the parameter
932
+ ` p ` has declared type ` T ` . If no such getter exists, but a setter with
933
+ the same basename exists, with a formal parameter whose type is ` T ` , the
934
+ parameter ` p ` has declared type ` T ` . * In other words, an instance
935
+ variable introduced by a declaring parameter is subject to override
936
+ inference, just like an explicitly declared instance variable.*
937
+ - otherwise, if ` p ` is optional and has a default value whose static type
938
+ in the empty context is a type ` T ` which is not ` Null ` then ` p ` has
939
+ declared type ` T ` . When ` T ` is ` Null ` , ` p ` has declared type ` Object? ` .
940
+ - otherwise, if ` p ` does not have a default value then ` p ` has declared
941
+ type ` Object? ` .
920
942
921
943
* Dart has traditionally assumed the type ` dynamic ` in such situations. We
922
944
have chosen the more strictly checked type ` Object? ` instead, in order to
@@ -932,25 +954,25 @@ this by specifying the current scope explicitly as the body scope, in spite
932
954
of the fact that the declaring constructor is actually placed outside the
933
955
braces that delimit the class body.*
934
956
935
- Next, _ k _ has the modifier ` const ` iff the keyword ` const ` occurs just
957
+ Next, _ k2 _ has the modifier ` const ` iff the keyword ` const ` occurs just
936
958
before the name of _ D_ or before ` this ` , or if _ D_ is an ` enum `
937
959
declaration.
938
960
939
- Consider the case where _ D _ is a declaring header constructor. If the name
961
+ Consider the case where _ k _ is a declaring header constructor. If the name
940
962
` C ` in _ D_ and the type parameter list, if any, is followed by ` .id ` where
941
- ` id ` is an identifier then _ k _ has the name ` C.id ` . If it is followed by
942
- ` .new ` then _ k _ has the name ` C ` . If it is not followed by ` . ` then _ k _
943
- has the name ` C ` . If it exists, _ D2_ omits the part derived from
944
- ` '.' <identifierOrNew> ` that follows the name and type parameter list, if
945
- any, in _ D _ . Moreover, _ D2_ omits the formal parameter list _ L_ that
946
- follows the name, type parameter list, if any, and ` .id ` , if any.
963
+ ` id ` is an identifier then _ k2 _ has the name ` C.id ` . If it is followed by
964
+ ` .new ` then _ k2 _ has the name ` C ` . If it is not followed by ` . ` then _ k2 _
965
+ has the name ` C ` . _ D2_ omits the part derived from ` '.' <identifierOrNew> `
966
+ that follows the name and type parameter list in _ D _ , if said part exists.
967
+ Moreover, _ D2_ omits the formal parameter list _ L_ that follows the name,
968
+ type parameter list, if any, and ` .id ` , if any.
947
969
948
970
Otherwise, _ D_ is a declaring body constructor. If the reserved word ` this `
949
- is followed by ` .id ` where ` id ` is an identifier then _ k _ has the name
950
- ` C.id ` . If it is followed by ` .new ` then _ k _ has the name ` C ` . If it is not
951
- followed by ` . ` then _ k _ has the name ` C ` .
971
+ is followed by ` .id ` where ` id ` is an identifier then _ k2 _ has the name
972
+ ` C.id ` . If it is followed by ` .new ` then _ k2 _ has the name ` C ` . If it is not
973
+ followed by ` . ` then _ k2 _ has the name ` C ` .
952
974
953
- The formal parameter list _ L2_ of _ k _ is identical to _ L_ , except that each
975
+ The formal parameter list _ L2_ of _ k2 _ is identical to _ L_ , except that each
954
976
formal parameter is processed as follows.
955
977
956
978
The formal parameters in _ L_ and _ L2_ occur in the same order, and
@@ -968,22 +990,19 @@ positional or named parameter remains optional; if it has a default value
968
990
unchanged from _ L_ to _ L2_ * (this is a plain, non-declaring parameter)* .
969
991
- Otherwise, a formal parameter (named or positional) of the form ` var T p `
970
992
or ` final T p ` where ` T ` is a type and ` p ` is an identifier is replaced
971
- in _ L2_ by ` this.p ` , along with its default value, if any. Next, an
972
- instance variable declaration of the form ` T p; ` or ` final T p; ` is added
973
- to _ D2_ . The instance variable has the modifier ` final ` if the parameter
974
- in _ L_ has the modifier ` final ` , or _ D_ is an ` extension type `
975
- declaration, or _ D_ is an ` enum ` declaration. In all cases, if ` p ` has
976
- the modifier ` covariant ` then this modifier is removed from the parameter
977
- in _ L2_ , and it is added to the instance variable declaration named ` p ` .
978
-
979
- In every case, any DartDoc comments are copied along with the formal
980
- parameter, and in the case where an instance variable is implicitly
981
- induced, the DartDoc comment is also added to that instance variable.
993
+ in _ L2_ by ` this.p ` , along with its default value, if any. Next, a
994
+ semantic instance variable declaration corresponding to the syntax ` T p; `
995
+ or ` final T p; ` is added to _ D2_ . It includes the modifier ` final ` if the
996
+ parameter in _ L_ has the modifier ` final ` , or _ D_ is an ` extension type `
997
+ declaration and _ k_ is a declaring header constructor. In all cases, if
998
+ ` p ` has the modifier ` covariant ` then this modifier is removed from the
999
+ parameter in _ L2_ , and it is added to the instance variable declaration
1000
+ named ` p ` .
982
1001
983
1002
If there is an initializer list following the formal parameter list _ L_
984
- then _ k _ has an initializer list with the same elements in the same order.
1003
+ then _ k2 _ has an initializer list with the same elements in the same order.
985
1004
986
- Finally, _ k _ is added to _ D2_ , and _ D_ is replaced by _ D2_ .
1005
+ Finally, _ k2 _ is added to _ D2_ , and _ D_ is replaced by _ D2_ .
987
1006
988
1007
### Discussion
989
1008
@@ -1017,6 +1036,10 @@ of declaration, and the constructor might be non-const).
1017
1036
1018
1037
### Changelog
1019
1038
1039
+ 1.10 - October 3, 2025
1040
+
1041
+ * Rename the feature to 'declaring constructors'. Fix several small errors.
1042
+
1020
1043
1.9 - August 8, 2025
1021
1044
1022
1045
* Change the scoping such that non-late initializing expressions have the
0 commit comments