• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1..
2    Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3    Licensed under the Apache License, Version 2.0 (the "License");
4    you may not use this file except in compliance with the License.
5    You may obtain a copy of the License at
6    http://www.apache.org/licenses/LICENSE-2.0
7    Unless required by applicable law or agreed to in writing, software
8    distributed under the License is distributed on an "AS IS" BASIS,
9    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10    See the License for the specific language governing permissions and
11    limitations under the License.
12
13.. _Semantic Rules:
14
15Semantic Rules
16##############
17
18.. meta:
19    frontend_status: Done
20
21This Chapter contains semantic rules to be used throughout the Specification
22document. The description of the rules is more or less informal. Some details
23are omitted to simplify the understanding.
24
25|
26
27.. _Subtyping:
28
29Subtyping
30*********
31
32.. meta:
33    frontend_status: Done
34
35The *subtype* relationship between the two types ``S`` and ``T``, where ``S``
36is a subtype of ``T`` (recorded as ``S<:T``), means that any object of type
37``S`` can be safely used in any context to replace an object of type ``T``.
38The opposite is called *supertype* relationship (see :ref:`Supertyping`).
39
40By the definition of ``S<:T``, type ``T`` belongs to the set of *supertypes*
41of type ``S``. The set of *supertypes* includes all *direct supertypes* (see
42below), and all their respective *supertypes*. More formally speaking, the set
43is obtained by reflexive and transitive closure over the direct supertype
44relation.
45
46
47.. index::
48   subtyping
49   subtype
50   closure
51   reflexive closure
52   transitive closure
53   object
54   type
55   direct supertype
56   supertype
57
58Terms *subclass*, *subinterface*, *superclass*, and *superinterface* are used
59when considering class or interface types.
60
61*Direct supertypes* of a non-generic class, or of the interface type ``C``
62are **all** of the following:
63
64-  Direct superclass of ``C`` (as mentioned in its extension clause, see
65   :ref:`Class Extension Clause`) or type ``Object`` if ``C`` has no extension
66   clause specified.
67
68-  Direct superinterfaces of ``C`` (as mentioned in the implementation
69   clause of ``C``, see :ref:`Class Implementation Clause`).
70
71-  Class ``Object`` if ``C`` is an interface type with no direct superinterfaces
72   (see :ref:`Superinterfaces and Subinterfaces`).
73
74
75.. index::
76   subclass
77   subinterface
78   superclass
79   direct supertype
80   direct superclass
81   reflexive closure
82   transitive closure
83   non-generic class
84   extension clause
85   implementation clause
86   superinterface
87   Object
88   direct superinterface
89   class extension
90   subinterface
91
92*Direct supertypes* of the generic type ``C`` <``F``:sub:`1` ``,..., F``:sub:`n`>
93(for a generic class or interface type declaration ``C`` <``F``:sub:`1` ``,..., F``:sub:`n`>
94with *n*>0) are **all** of the following:
95
96-  Direct superclass of ``C`` <``F``:sub:`1` ``,..., F``:sub:`n`>.
97
98-  Direct superinterfaces of ``C`` <``F``:sub:`1` ``,..., F``:sub:`n`>.
99
100-  Type ``Object`` if ``C`` <``F``:sub:`1` ``,..., F``:sub:`n`> is a generic
101   interface type with no direct superinterfaces.
102
103
104The direct supertype of a type parameter is the type specified as the
105constraint of that type parameter.
106
107.. index::
108   direct supertype
109   generic type
110   generic class
111   interface type declaration
112   direct superinterface
113   type parameter
114   superclass
115   superinterface
116   bound
117   Object
118
119|
120
121.. _Supertyping:
122
123Supertyping
124***********
125
126.. meta:
127    frontend_status: Done
128
129The *supertype* relationship between the two types ``T`` and ``S``, where ``T``
130is a supertype of ``T`` (recorded as ``T>:S``) is opposite to subtyping (see
131:ref:`Subtyping`). *Supertyping* means that any object of type ``S`` can be
132safely used in any context to replace an object of type ``T``.
133
134.. index::
135   supertype
136   supertyping
137   context
138   type
139   object
140
141|
142
143.. _Variance:
144
145Variance
146********
147
148.. meta:
149    frontend_status: Done
150
151Variance is how subtyping between class types relates to subtyping between
152class member signatures (types of parameters, return type). Variance can be
153of three kinds:
154
155-  Invariance,
156-  Covariance, and
157-  Contravariance.
158
159.. index::
160   variance
161   subtyping
162   type
163   class member signature
164   parameter
165   return type
166   invariance
167   covariance
168   contravariance
169
170|
171
172.. _Invariance:
173
174Invariance
175==========
176
177.. meta:
178    frontend_status: Done
179
180*Invariance* refers to the ability to use the originally-specified type as a
181derived one.
182
183.. index::
184   invariance
185   type
186
187|
188
189.. _Covariance:
190
191Covariance
192==========
193
194.. meta:
195    frontend_status: Done
196
197*Covariance* is the ability to use a type that is more specific than originally
198specified.
199
200.. index::
201   covariance
202   type
203
204|
205
206.. _Contravariance:
207
208Contravariance
209==============
210
211.. meta:
212    frontend_status: Done
213
214*Contravariance* is the ability to use a type that is more general than
215originally specified.
216
217.. index::
218   contravariance
219   type
220
221Examples
222========
223
224The examples below illustrate valid and invalid usages of variance.
225If class ``Base`` is defined as follows:
226
227.. code-block:: typescript
228   :linenos:
229
230   class Base {
231      method_one(p: Base): Base {}
232      method_two(p: Derived): Base {}
233      method_three(p: Derived): Derived {}
234   }
235
236---then the code below is valid:
237
238.. code-block:: typescript
239   :linenos:
240
241   class Derived extends Base {
242      // invariance: parameter type and return type are unchanged
243      override method_one(p: Base): Base {}
244
245      // covariance for the return type: Derived is a subtype of Base
246      override method_two(p: Derived): Derived {}
247
248      // contravariance for parameter types: Base is a super type for Derived
249      override method_three(p: Base): Derived {}
250   }
251
252.. index::
253   variance
254
255On the contrary, the following code causes compile-time errors:
256
257.. code-block-meta:
258   expect-cte
259
260.. code-block:: typescript
261   :linenos:
262
263   class Derived extends Base {
264
265      // covariance for parameter types is prohibited
266      override method_one(p: Derived): Base {}
267
268      // contravariance for the return type is prohibited
269      override method_tree(p: Derived): Base {}
270   }
271
272
273|
274
275.. _Type Compatibility:
276
277Type Compatibility
278******************
279
280.. meta:
281    frontend_status: Done
282
283Type ``T``:sub:`1` is compatible with type ``T``:sub:`2` if:
284
285-  ``T``:sub:`1` is the same as ``T``:sub:`2`, or
286
287-  There is an *implicit conversion* (see :ref:`Implicit Conversions`)
288   that allows converting type ``T``:sub:`1` to type ``T``:sub:`2`.
289
290*Type compatibility* relationship  is asymmetric, i.e., that ``T``:sub:`1`
291is compatible with type ``T``:sub:`2` does not imply that ``T``:sub:`2` is
292compatible with type ``T``:sub:`1`.
293
294
295.. index::
296   type compatibility
297   conversion
298   implicit conversion
299   asymmetric relationship
300
301|
302
303.. _Compatibility of Call Arguments:
304
305Compatibility of Call Arguments
306*******************************
307
308.. meta:
309    frontend_status: Done
310
311The definition of the term *compatible* is found in :ref:`Type Compatibility`.
312
313The following semantic check must be performed for any function, method, or
314constructor call:
315
316- Type of any argument (except arguments of a rest parameter) must be
317  compatible with the type of the corresponding parameter;
318
319- Type of each argument corresponding to the rest parameter without the spread
320  operator (:ref:`Spread Expression`) must be compatible with the element type
321  of the rest type parameter;
322
323- If a single argument corresponding to the rest parameter has the spread
324  operator (:ref:`Spread Expression`), then the *expression* that follows the
325  operator must refer to an array of a type compatible with the type of the
326  rest parameter.
327
328.. index::
329   call argument
330   function call
331   method call
332   constructor call
333   semantic check
334   argument
335   rest parameter
336   spread operator
337   compatible type
338   type
339   compatibility
340
341|
342
343.. _Type Inference:
344
345Type Inference
346**************
347
348.. meta:
349    frontend_status: Done
350
351In spite of the fact that |LANG| supports strong typing, it allows not to
352burden the programmer to specify type annotations everywhere. Smart compiler
353can infer the type of some entities from the surrounding context. This
354technique called *type inference* allows keeping program code readability,
355typing less, and focusing on the business logic while keeping type safety.
356Type inference can be applied by the compiler in several contexts as follows:
357
358- Variable and constant declarations (see :ref:`Type Inference from Initializer`);
359- Implicit generic instantiations (see :ref:`Implicit Generic Instantiations`);
360- Function or method return type (see :ref:`Return Type Inference`);
361- Lambda expression parameter type (see :ref:`Lambda Signature`);
362- Array literal type inference (see :ref:`Array Type Inference from Context`,
363  and :ref:`Array Type Inference from Types of Elements`);
364- Smart types (see :ref:`Smart Types`).
365
366.. index::
367   strong typing
368   annotation
369   type inference
370   entity
371   code readability
372   type safety
373   context
374   variable
375   constant
376   declaration
377   generic instantiation
378   function
379   method
380   return type
381   lambda expression
382   parameter type
383   array literal
384   smart type
385
386|
387
388.. _Smart Types:
389
390Smart Types
391===========
392
393.. meta:
394   frontend_status: Partly
395   todo: implement a dataflow check for loops and try-catch blocks
396
397Every data entity
398
399-  a variable (see :ref:`Variable and Constant Declarations`),
400-  a class field (see :ref:`Field Declarations`),
401-  a parameter of a function or method (see :ref:`Parameter List`)
402
403has its static type, which is specified explicitly or inferred at the
404point of declaration. This type defines the set of operations that can
405be applied to the entity (namely, what methods can be called, and what other
406entities can be accessed if the entity acts as a receiver of the operation):
407
408.. code-block:: typescript
409   :linenos:
410
411    let a = new Object
412    a.toString() // entity 'a' has method toString()
413
414.. index::
415   entity
416   variable
417   class variable
418   local variable
419   function
420   method
421   static type
422   receiver
423   access
424   declaration
425
426There can be cases when the type of an entity (mostly local variables) is a
427class or interface type (see :ref:`Classes` and :ref:`Interfaces`), or union
428type (see :ref:`Union Types`). In a particular program context, the compiler
429can narrow (smart cast) a static type to a more precise type (smart type), and
430allow the operations specific to the narrowed type:
431
432.. code-block:: typescript
433   :linenos:
434
435    let a: number | string = 666
436    a++ /* Here we know for sure that type of 'a' is number and number-specific
437           operations are type-safe */
438
439    class Base {}
440    class Derived extends Base { method () {} }
441    let b: base = new Derived
442    b.method () /* Here we know for sure that type of 'b' is Derived and Derived-specific
443           operations are type-safe */
444
445Other examples are explicit calls to ``instanceof``
446(see :ref:`InstanceOf Expression`) or checks against ``null``
447(see :ref:`Reference Equality`) as part of ``if`` statements
448(see :ref:`if Statements`) or conditional expressions
449(see :ref:`Conditional Expressions`):
450
451.. code-block:: typescript
452   :linenos:
453
454    function foo (b: Base, d: Derived|null) {
455        if (b instanceof Derived) {
456            b.method()
457        }
458        if (d != null) {
459            d.method()
460        }
461    }
462
463.. index::
464   type
465   entity
466   local variable
467   interface type
468   class type
469   union type
470   context
471   compiler
472   narrowing
473   smart cast
474   smart type
475   if statement
476   conditional expression
477
478In cases like this, the smart compiler can deduce the smart type of an entity
479without requiring unnecessary ``as`` conversions (see :ref:`Cast Expressions`).
480
481Overloading (see :ref:`Function and Method Overloading`) can cause tricky
482situations when a smart type leads to the call of a function or a method
483(see :ref:`Overload Resolution`) that suits the smart type rather than the
484static type of an argument:
485
486.. code-block:: typescript
487   :linenos:
488
489    function foo (p: Base) {}
490    function foo (p: Derived) {}
491
492    let b: Base = new Derived
493    foo (b) // potential ambiguity in case of smart type, foo(p:Base) is to be called
494    foo (b as Derived) // no ambiguity,  foo(p:Derived) is to be called
495
496Particular cases supported by the compiler are determined by the compiler
497implementation.
498
499.. index::
500   compiler
501   smart type
502   entity
503   as conversion
504   conversion
505   function
506   method
507   static type
508   implementation
509
510|
511
512.. _Overloading and Overriding:
513
514Overloading and Overriding
515**************************
516
517Two important concepts apply to different contexts and entities throughout
518this specification as follows:
519
520#. *Overloading* allows defining and using functions (in general sense,
521   including methods and constructors) with the same name but different
522   signatures. The actual function to be called is determined at compile
523   time. Thus, *overloading* is related to compile-time polymorphism.
524
525#. *Overriding* is closely connected with inheritance. It is used on methods
526   but not on functions. Overriding allows a subclass to offer a specific
527   implementation of a method already defined in its parent class.
528   The actual method to be called is determined at runtime based on the
529   object's type. Thus, overriding is related to runtime polymorphism.
530
531|LANG| uses two semantic rules related to these concepts:
532
533-  *Overload-equivalence* rule: the *overloading* of two entities is
534   correct if their signatures are **not** *overload-equivalent* (see
535   :ref:`Overload-Equivalent Signatures`).
536
537-  *Override-compatibility* rule: the *overriding* of two entities is
538   correct if their signatures are *override-compatible* (see
539   :ref:`Override-Compatible Signatures`).
540
541See :ref:`Overloading for Functions`,
542:ref:`Overloading and Overriding in Classes`, and
543:ref:`Overloading and Overriding in Interfaces` for details.
544
545.. index::
546   overloading
547   overriding
548   context
549   entity
550   function
551   constructor
552   method
553   signature
554   compile-time polymorphism
555   runtime polymorphism
556   inheritance
557   parent class
558   object type
559   runtime
560   overload-equivalence
561   override-compatibility
562
563|
564
565.. _Overload-Equivalent Signatures:
566
567Overload-Equivalent Signatures
568==============================
569
570Signatures *S*:sub:`1` with *n* parameters, and *S*:sub:`2` with *m*
571parameters are *overload-equivalent* if:
572
573-  ``n = m``;
574
575-  Parameter type at some position in *S*:sub:`1` is a *type parameter*
576   (see :ref:`Type Parameters`), and a parameter type at the same position
577   in *S*:sub:`2` is any reference type or type parameter;
578
579-  Parameter type at some position in *S*:sub:`1` is *generic type*
580   ``G`` <``T``:sub:`1`, ``...``, ``T``:sub:`n`>, and a parameter type at the
581   same position in *S*:sub:`2` is also ``G`` with any list of type arguments
582   (see :ref:`Type Arguments`);
583
584-  All other parameter types in *S*:sub:`1` are equal to parameter types
585   in the same positions in *S*:sub:`2`.
586
587Parameter names and return types do not influence *overload equivalence*.
588Signatures in the following series are *overload-equivalent*:
589
590.. index::
591   overload-equivalent signature
592   signature
593   parameter
594   type parameter
595   reference type
596   generic type
597   type argument
598   overriding
599   parameter name
600   return type
601   overload equivalence
602
603.. code-block-meta:
604
605.. code-block:: typescript
606   :linenos:
607
608   (x: number): void
609   (y: number): void
610
611
612.. code-block-meta:
613
614.. code-block:: typescript
615   :linenos:
616
617   (x: number): void
618   (y: number): number
619
620
621.. code-block-meta:
622
623.. code-block:: typescript
624   :linenos:
625
626   class G<T>
627   (y: Number): void
628   (x: T): void
629
630
631.. code-block-meta:
632
633.. code-block:: typescript
634   :linenos:
635
636   class G<T>
637   (y: G<Number>): void
638   (x: G<T>): void
639
640
641.. code-block-meta:
642
643.. code-block:: typescript
644   :linenos:
645
646   class G<T, S>
647   (y: T): void
648   (x: S): void
649
650Signatures in the following series are not *overload-equivalent*:
651
652.. code-block-meta:
653
654.. code-block:: typescript
655   :linenos:
656
657   (x: number): void
658   (y: string): void
659
660
661.. code-block-meta:
662
663.. code-block:: typescript
664   :linenos:
665
666   class A { /*body*/}
667   class B extends A { /*body*/}
668   (x: A): void
669   (y: B): void
670
671
672|
673
674.. _Override-Compatible Signatures:
675
676Override-Compatible Signatures
677==============================
678
679If there are two classes, ``Base`` and ``Derived``, and class ``Derived``
680overrides the method ``foo()`` of ``Base``, then ``foo()`` in ``Base`` has
681signature ``S``:sub:`1` <``V``:sub:`1` ``, ... V``:sub:`k`>
682(``U``:sub:`1` ``, ..., U``:sub:`n`) ``:U``:sub:`n+1`, and ``foo()`` in
683``Derived`` has signature ``S``:sub:`2` <``W``:sub:`1` ``, ... W``:sub:`l`>
684(``T``:sub:`1` ``, ..., T``:sub:`m`) ``:T``:sub:`m+1` as illustrated by the
685example below:
686
687.. code-block:: typescript
688   :linenos:
689
690    class Base {
691       foo <V1, ... Vk> (p1: U1, ... pn: Un): Un+1
692    }
693    class Derived extends Base {
694       override foo <W1, ... Wl> (p1: T1, ... pm: Tm): Tm+1
695    }
696
697The signature ``S``:sub:`2` is override-compatible with ``S``:sub:`1` only
698if **all** of the following conditions are met:
699
7001. Number of parameters of both methods is the same, i.e., ``n = m``.
7012. Each type ``T``:sub:`i` is override-compatible with type ``U``:sub:`i`
702   for ``i`` in ``1..n+1``. Type override compatibility is defined below.
7033. Number of type parameters of either method is the same, i.e., ``k = l``.
7044. Constraints of ``W``:sub:`1`, ... ``W``:sub:`l` are to be contravariant
705   (see :ref:`Contravariance`) to the appropriate constraints of ``V``:sub:`1`,
706   ... ``V``:sub:`k`.
707
708.. index::
709   override-compatible signature
710   override compatibility
711   class
712   signature
713   method
714   parameter
715   type
716   contravariant
717   constraint
718   type parameter
719
720There are two cases of type override-compatibility, as types are used as either
721parameter types, or return types. There are five kinds of types for each case:
722
723- Class/interface type;
724- Function type;
725- Primitive type;
726- Array type;
727- Tuple type; and
728- Type parameter.
729
730Every type is override-compatible with itself (see :ref:`Invariance`).
731
732Mixed override-compatibility between types of different kinds is always false,
733except the compatibility with class type ``Object`` as any type is a subtype of
734``Object``.
735
736The following rule applies in case of generics:
737
738   - Derived class must have type parameter constraints to be type-compatible
739     (see :ref:`Type Compatibility`) with the respective type parameter
740     constraint in the base type;
741   - Otherwise, a :index:`compile-time error` occurs.
742
743.. index::
744   override compatibility
745   parameter type
746   class type
747   interface type
748   function type
749   primitive type
750   array type
751   tuple type
752   type parameter
753   subtype
754   object
755
756.. code-block:: typescript
757   :linenos:
758
759   class Base {}
760   class Derived extends Base {}
761   class A1 <CovariantTypeParameter extends Base> {}
762   class B1 <CovariantTypeParameter extends Derived> extends A1<CovariantTypeParameter> {}
763       // OK, derived class may have type compatible constraint of type parameters
764
765   class A2 <ContravariantTypeParameter extends Derived> {}
766   class B2 <ContravariantTypeParameter extends Base> extends A2<ContravariantTypeParameter> {}
767       // Compile-time error, derived class cannot have non-compatible constraints of type parameters
768
769
770Variances to be used for types that can be override-compatible in different
771positions are represented in the following table:
772
773+-+-----------------------+---------------------+-------------------+
774| | **Positions ==>**     | **Parameter Types** | **Return Types**  |
775+-+-----------------------+---------------------+-------------------+
776| | **Type Kinds**        |                     |                   |
777+=+=======================+=====================+===================+
778|1| Class/interface types | Contravariance >:   | Covariance <:     |
779+-+-----------------------+---------------------+-------------------+
780|2| Function types        | Covariance <:       | Contravariance >: |
781+-+-----------------------+---------------------+-------------------+
782|3| Primitive types       | Invariance          | Invariance        |
783+-+-----------------------+---------------------+-------------------+
784|4| Array types           | Covariance <:       | Covariance <:     |
785+-+-----------------------+---------------------+-------------------+
786|5| Tuple types           | Covariance <:       | Covariance <:     |
787+-+-----------------------+---------------------+-------------------+
788|6| Type parameter        | Contravariance >:   | Contravariance >: |
789| | constraint            |                     |                   |
790+-+-----------------------+---------------------+-------------------+
791
792
793.. index::
794   variance
795   covariance
796   contravariance
797   invariance
798   semantics
799
800The semantics is illustrated by the example below:
801
802.. code-block:: typescript
803   :linenos:
804
805    class Base {
806       kinds_of_parameters <T extends Derived, U extends Base>(
807          p1: Derived, p2: (q: Base)=>Derived, p3: number,
808          p4: Number, p5: Base[], p6: [Base, Base], p7: T, p8: U
809       )
810       kinds_of_return_type1(): Base
811       kinds_of_return_type2(): (q: Derived)=> Base
812       kinds_of_return_type3(): number
813       kinds_of_return_type4(): Number
814       kinds_of_return_type5(): Base[]
815       kinds_of_return_type6(): [Base, Base]
816       kinds_of_return_type7 <T extends Derived>(): T
817    }
818    class Derived extends Base {
819       // Overriding kinds for parameters
820       override kinds_of_parameters <T extends Base, U extends Object>(
821          p1: Base, // contravariant parameter type
822          p2: (q: Derived)=>Base, // Covariant parameter type, contravariant return type
823          p3: Number, // Compile-time error: parameter type is not override-compatible
824          p4: number, // Compile-time error: parameter type is not override-compatible
825          p5: Derived[], // Covariant array element type
826          p6: [Derived, Derived], // Covariant tuple type elements
827          p7: T, // Contravariance for constraints of type parameters
828          p8: U  // Contravariance for constraints of type parameters
829       )
830       // Overriding kinds for return type
831       override kinds_of_return_type1(): Derived // Covariant return type
832       override kinds_of_return_type2(): (q: Base)=> Derived // Contravariant parameter type, covariant return type
833       override kinds_of_return_type3(): Number // Compile-time error: return type is not override-compatible
834       override kinds_of_return_type4(): number // Compile-time error: return type is not override-compatible
835       override kinds_of_return_type5(): Derived[] // Covariant array element type
836       override kinds_of_return_type6(): [Derived, Derived] // Covariant tuple type elements
837       override kinds_of_return_type7 <T extends Base> (): T // OK, contravariance for constraints of the return type
838    }
839
840The example below illustrates override-compatibility with ``Object``:
841
842.. code-block:: typescript
843   :linenos:
844
845    class Base {
846       kinds_of_parameters( // It represents all possible parameter type kinds
847          p1: Derived, p2: (q: Base)=>Derived, p3: number,
848          p4: Number, p5: Base[], p6: [Base, Base]
849       )
850       kinds_of_return_type(): Object // It can be overridden by all subtypes except primitive ones
851    }
852    class Derived extends Base {
853       override kinds_of_parameters( // Object is a supertype for all types except primitive ones
854          p1: Object, p2: Object,
855          p3: Object, // Compile-time error: number and Object are not override-compatible
856          p4: Object, p5: Object, p6: Object
857       )
858    class Derived1 extends Base {
859       override kinds_of_return_type(): Base // Valid overriding
860    }
861    class Derived2 extends Base {
862       override kinds_of_return_type(): (q: Derived)=> Base // Valid overriding
863    }
864    class Derived3 extends Base {
865       override kinds_of_return_type(): number // Compile-time error: number and Object are not override-compatible
866    }
867    class Derived4 extends Base {
868       override kinds_of_return_type(): Number // Valid overriding
869    }
870    class Derived5 extends Base {
871       override kinds_of_return_type(): Base[] // Valid overriding
872    }
873    class Derived6 extends Base {
874       override kinds_of_return_type(): [Base, Base] // Valid overriding
875    }
876
877|
878
879.. _Overloading for Functions:
880
881Overloading for Functions
882=========================
883
884*Overloading* must only be considered for functions because inheritance for
885functions is not defined.
886
887The correctness check for functions overloading is performed if two or more
888functions with the same name are accessible (see :ref:`Accessible`) in a scope
889(see :ref:`Scopes`).
890
891A function can be declared in, or imported to a scope. To prevent uncontrolled
892overloading, mixing functions that are declared and imported, or imported from
893different compilation units, is not allowed. In particular, a
894:index:`compile-time error` occurs to same-name functions if:
895
896-  Functions are imported from different compilation units;
897
898-  Some functions are imported, while others are declared.
899
900It means that only the functions declared in the scope can be overloaded.
901The semantic check for these functions is as follows:
902
903-  If signatures of functions are *overload-equivalent*, then
904   a :index:`compile-time error` occurs.
905
906-  Otherwise, *overloading* is valid.
907
908.. index::
909   overloading
910   function
911   inheritance
912   access
913   scope
914   import
915   compilation unit
916   overload-equivalent signature
917
918|
919
920.. _Overloading and Overriding in Classes:
921
922Overloading and Overriding in Classes
923=====================================
924
925Both *overloading* and *overriding* must be considered in case of classes for
926methods and partly for constructors.
927
928**Note**: Only accessible (see :ref:`Accessible`) methods are subject for
929overloading and overriding. For example, neither overriding nor overloading
930is considered if a superclass contains a ``private`` method, and a subclass
931has a method with the same name. Accessors are considered methods here.
932
933An overriding member can keep or extend the access modifier (see
934:ref:`Access Modifiers`) of the inherited or implemented member. Otherwise, a
935:index:`compile-time error` occurs:
936
937.. index::
938   overloading
939   inheritance
940   overriding
941   private
942   method
943   superclass
944   access modifier
945
946.. code-block:: typescript
947   :linenos:
948
949   class Base {
950      public public_member() {}
951      protected protected_member() {}
952      internal internal_member() {}
953      private private_member() {}
954   }
955
956   interface Interface {
957      public_member() // All members are public in interfaces
958   }
959
960   class Derived extends Base implements Interface {
961      public override public_member() {}
962         // Public member can be overridden and/or implemented by the public one
963      public override protected_member() {}
964         // Protected member can be overridden by the protected or public one
965      internal internal_member() {}
966         // Internal member can be overridden by the internal one only
967      override private_member() {}
968         // A compile-time error occurs if an attempt is made to override private member
969   }
970
971Semantic rules that work in various contexts are represented in the following
972table:
973
974+-------------------------------------+----------------------------------------------+
975| **Context**                         | **Semantic Check**                           |
976+=====================================+==============================================+
977| Two *instance methods*,             | If signatures are *overload-equivalent*,     |
978| two *static methods* with the same  | (see :ref:`Overload-Equivalent Signatures`), |
979| name, or two *constructors* are     | then a :index:`compile-time error`           |
980| defined in the same class.          | occurs. Otherwise, *overloading* is used.    |
981+-------------------------------------+----------------------------------------------+
982
983.. index::
984   semantic check
985   instance method
986   method
987   static method
988   constructor
989   overload equivalence
990   overloading
991   overload-equivalent signature
992
993.. code-block:: typescript
994   :linenos:
995
996   class aClass {
997
998      instance_method_1() {}
999      instance_method_1() {} // compile-time error: instance method duplication
1000
1001      static static_method_1() {}
1002      static static_method_1() {} // compile-time error: static method duplication
1003
1004      instance_method_2() {}
1005      instance_method_2(p: number) {} // valid overloading
1006
1007      static static_method_2() {}
1008      static static_method_2(p: string) {} // valid overloading
1009
1010      constructor() {}
1011      constructor() {} // compile-time error: constructor duplication
1012
1013      constructor(p: number) {}
1014      constructor(p: string) {} // valid overloading
1015
1016   }
1017
1018+-------------------------------------+---------------------------------------------+
1019| An *instance method* is defined     | If signatures are *override-compatible*     |
1020| in a subclass with the same name    | (see :ref:`Override-Compatible Signatures`),|
1021| as the *instance method* in a       | then *overriding* is used.                  |
1022| superclass.                         | Otherwise, *overloading* is used.           |
1023+-------------------------------------+---------------------------------------------+
1024
1025.. code-block:: typescript
1026   :linenos:
1027
1028   class Base {
1029      method_1() {}
1030      method_2(p: number) {}
1031   }
1032   class Derived extends Base {
1033      override method_1() {} // overriding
1034      method_2(p: string) {} // overloading
1035   }
1036
1037+-------------------------------------+---------------------------------------------+
1038| A *static method* is defined        | If signatures are *overload-equivalent*     |
1039| in a subclass with the same name    | (see :ref:`Overload-Equivalent Signatures`),|
1040| as the *static method* in a         | then the static method in the subclass      |
1041| superclass.                         | *hides* the previous static method.         |
1042|                                     | Otherwise, *overloading* is used.           |
1043+-------------------------------------+---------------------------------------------+
1044
1045.. index::
1046   instance method
1047   static method
1048   subclass
1049   superclass
1050   override-compatible signature
1051   override-compatibility
1052   overloading
1053   hiding
1054   overriding
1055
1056.. code-block:: typescript
1057   :linenos:
1058
1059   class Base {
1060      static method_1() {}
1061      static method_2(p: number) {}
1062   }
1063   class Derived extends Base {
1064      static method_1() {} // hiding
1065      static method_2(p: string) {} // overloading
1066   }
1067
1068
1069+-------------------------------------+--------------------------------------------+
1070| A *constructor* is defined          | All base class constructors are available  |
1071| in a subclass.                      | for call in all derived class constructors.|
1072+-------------------------------------+--------------------------------------------+
1073
1074.. code-block:: typescript
1075   :linenos:
1076
1077   class Base {
1078      constructor() {}
1079      constructor(p: number) {}
1080   }
1081   class Derived extends Base {
1082      constructor(p: string) {
1083           super()
1084           super(5)
1085      }
1086   }
1087
1088.. index::
1089   constructor
1090   subclass
1091   class constructor
1092
1093|
1094
1095.. _Overloading and Overriding in Interfaces:
1096
1097Overloading and Overriding in Interfaces
1098========================================
1099
1100.. meta:
1101    frontend_status: Done
1102
1103+-------------------------------------+---------------------------------------------+
1104| **Context**                         | **Semantic Check**                          |
1105+=====================================+=============================================+
1106| A method is defined                 | If signatures are *override-compatible*     |
1107| in a subinterface with the same     | (see :ref:`Override-Compatible Signatures`),|
1108| name as the method in               | then *overriding* is used. Otherwise,       |
1109| the superinterface.                 | *overloading* is used.                      |
1110+-------------------------------------+---------------------------------------------+
1111
1112.. code-block:: typescript
1113   :linenos:
1114
1115   interface Base {
1116      method_1()
1117      method_2(p: number)
1118   }
1119   interface Derived extends Base {
1120      method_1() // overriding
1121      method_2(p: string) // overloading
1122   }
1123
1124+-------------------------------------+------------------------------------------+
1125| Two methods with the same           | A :index:`compile-time error` occurs.    |
1126| name are defined in the same        | Otherwise, *overloading* is used.        |
1127| interface.                          |                                          |
1128+-------------------------------------+------------------------------------------+
1129
1130.. index::
1131   method
1132   subinterface
1133   superinterface
1134   semantic check
1135   override compatibility
1136   override-compatible signature
1137
1138.. code-block:: typescript
1139   :linenos:
1140
1141   interface anInterface {
1142      instance_method_1()
1143      instance_method_1()  // Compile-time error: instance method duplication
1144
1145      instance_method_2()
1146      instance_method_2(p: number)  // Valid overloading
1147   }
1148
1149|
1150
1151.. _Overload Resolution:
1152
1153Overload Resolution
1154*******************
1155
1156.. meta:
1157    frontend_status: Done
1158
1159The *overload resolution* is used to select one entity to call from a set of
1160*potentially applicable candidates* in a function, method, or constructor call.
1161
1162The overload resolution is performed in two steps as follows:
1163
1164#. Select *applicable candidates* from *potentially applicable candidates*;
1165
1166#. If there is more than one *applicable candidate*, then select the best
1167   candidate.
1168
1169**Note**: The first step is performed in all cases, even if there is
1170only one *applicable candidate* to check *call signature compatibility*.
1171
1172.. index::
1173   overload resolution
1174   entity
1175   applicable candidate
1176   call signature compatibility
1177
1178|
1179
1180.. _Selection of Applicable Candidates:
1181
1182Selection of Applicable Candidates
1183==================================
1184
1185.. meta:
1186    frontend_status: Partly
1187    todo: adapt the implementation to the latest specification (handle rest, union, functional types properly)
1188    todo: make the ISA/assembler/runtime handle union types without collision - eg foo(arg: A|B) and foo(arg: C|D)
1189
1190The selection of *applicable candidates* is the process of checking
1191:ref:`Compatibility of Call Arguments` for all entities from the set of
1192*potentially applicable candidates*. If any argument is not compatible with
1193the corresponding parameter type, then the entity is deleted from the set.
1194
1195**Note**: Compile-time errors are not reported on this stage.
1196
1197After processing all entities, one of the following results is achieved:
1198
1199- Set is empty (all entities are deleted). A compile-time error occurs,
1200  and the *overload resolution* is completed.
1201
1202- Only one entity is left in the set. This is the entity to call, and
1203  the *overload resolution* is completed.
1204
1205- More than one entity is left in the set. The next step of the
1206  *overload resolution* is to be performed.
1207
1208.. index::
1209   applicable candidate
1210   compatibility
1211   call argument
1212   parameter type
1213   overload resolution
1214   overloaded function
1215
1216Two overloaded functions are considered in the following example:
1217
1218.. code-block:: typescript
1219   :linenos:
1220
1221   class Base { }
1222   class Derived extends Base { }
1223
1224   function foo(p: Base) { ... }     // #1
1225   function foo(p: Derived) { ... }  // #2
1226
1227   foo(new Derived) // two applicable candidates for this call
1228                    // next step of overload resolution is required
1229
1230   foo(new Base)    // one applicable candidate
1231                    // overload resolution is completed
1232                    // #1 will be called
1233
1234   foo(new Base, 5) // no candidates, compile-time error
1235
1236|
1237
1238.. _Selection of Best Candidate:
1239
1240Selection of Best Candidate
1241===========================
1242
1243.. meta:
1244    frontend_status: Partly
1245
1246If the set of *applicable candidates* has two or more candidates, then the
1247best candidate for the given list of arguments is to be identified, if possible.
1248
1249The selection of the best candidate is based on the following:
1250
1251- There are no candidates with the same list of parameters, as this situation
1252  is already forbidden by the compiler (on declaration or import site);
1253
1254- If several candidates can be called correctly by using the same argument list,
1255  then the same implicit argument transformations must be applied to make the
1256  call.
1257
1258Possible argument transformations are listed below:
1259
1260- :ref:`Implicit Conversions`;
1261
1262- Passing default values to fill any missing arguments
1263  (:ref:`Optional Parameters`);
1264
1265- Passing the empty array to replace a rest parameter that has no argument;
1266
1267- Folding several arguments to the array for a rest parameter.
1268
1269.. index::
1270   applicable candidate
1271   best candidate
1272   parameter
1273   compiler
1274   import site
1275   argument transformation
1276   value
1277   rest parameter
1278
1279The examples of transformations are presented below:
1280
1281.. code-block:: typescript
1282   :linenos:
1283
1284   function foo1(x: number) {}
1285   foo1(1) // implicit conversion int -> double
1286
1287   function foo2(x: Int) {}
1288   foo2(1) // implicit boxing
1289
1290   function foo3(x?: string) {}
1291   foo3() // passing default value -> foo(undefined)
1292
1293   function foo4(...x: int[]) {}
1294   foo4()     // passing empty array -> foo([])
1295   foo4(1, 2) // folding to array -> foo(...[1, 2])
1296
1297The candidate that does not require transformations for all arguments is the
1298*best candidate*. Other candidates are not considered.
1299
1300The examples below represent the best candidate selected without
1301transformation:
1302
1303.. code-block:: typescript
1304   :linenos:
1305
1306   function foo(i: int)    // #1
1307   function foo(n: number) // #2
1308
1309   let x: int = 1
1310   foo(x) // #1 - is the best candidate, no transformations
1311
1312   function goo(s: string)  // #1
1313   function goo(s?: string) // #2
1314
1315   goo("abc") // #1 - is the best candidate, no transformations
1316
1317   let x: string|undefined = "abc"
1318   goo(x) // #2 - is the best candidate, no transformations
1319
1320.. index::
1321   best candidate
1322   transformation
1323   argument
1324
1325If there is no such candidate, then each argument transformation of each
1326candidate is compared (taking optional and rest parameters into the account)
1327by calculating partial *better* relation:
1328
1329**Case 1**. No transformation is *better* than any transformation.
1330
1331**Case 2**. If argument type is of a numeric type, char, or its boxed
1332counterpart, then the candidate with a *shorter* conversion is *better*. E.g.,
1333the conversion of ``int`` to ``float`` is *better* than ``int`` to ``double``,
1334and ``int`` to ``Int`` is *better* than ``int`` to ``Long``.
1335
1336**Case 3**. In case of optional parameters, no parameter is *better*.
1337
1338**Case 4**. If the first candidate has several parameters, and the other
1339candidate has a rest parameter for the same arguments, then the first one
1340is *better*.
1341
1342**Case 5**. All other variants are considered *not comparable*.
1343
1344.. index::
1345   best candidate
1346   argument transformation
1347   numeric type
1348   char
1349   boxing
1350   conversion
1351   parameter
1352
1353.. code-block:: typescript
1354   :linenos:
1355
1356   // Case 1:
1357   function foo(n: number, s: string|null)  // #1
1358   function foo(n: number, s: string)       // #2
1359
1360   goo(1, "abc") // #2 is better, no transformation for 2nd argument
1361
1362   // Case 2:
1363   function foo(i: long)  // #1
1364   function foo(n: float) // #2
1365
1366   let x: int = 1
1367   foo(x) //  #1 is better, conversion is shorter
1368
1369   // Case 3:
1370   function foo(n: number, s?: string)  // #1
1371   function foo(n: number)              // #2
1372
1373   foo(1) // #2 is better, less parameters
1374
1375   // Case 4:
1376   function foo(sum: number, a: number, b: number)  // #1
1377   function foo(sum: number, ...x: number[])        // #2
1378
1379   foo(1, 2, 3) // #1 is better, non-rest parameters
1380
1381   // Case 5:
1382   class Base { }
1383   class Derived extends Base { }
1384
1385   function foo(p: Base) { ... }     // #1
1386   function foo(p: Derived) { ... }  // #2
1387
1388   foo(new Derived) // not comparable, no one is better
1389
1390If there is exactly one candidate that is *better* than others for at least
1391one argument and *not comparable* to other arguments, then this one is the
1392*best candidate* that is to be called.
1393
1394If no candidate is the *best candidate*, then a :index:`compile-time error`
1395occurs. Examples of error cases are presented below:
1396
1397.. code-block:: typescript
1398   :linenos:
1399
1400   class Base { }
1401   class Derived extends Base { }
1402
1403   function foo(p: Base) { ... }     // #1
1404   function foo(p: Derived) { ... }  // #2
1405
1406   foo(new Derived) // compile-time error, as
1407                    // there is no argument where one candidate is better
1408
1409   function goo(a: int; b: float)  // #1
1410   function goo(a: float, b: int)  // #2
1411
1412   goo(1, 1) // compile-time error, as
1413             // #1 is better for 1st argument,
1414             // #2 is better for 2nd argument.
1415
1416.. index::
1417   best candidate
1418   argument
1419
1420|
1421
1422.. _Overload Signatures:
1423
1424Overload Signatures
1425*******************
1426
1427|LANG| supports *overload signatures* to ensure better |TS| alignment for
1428functions (:ref:`Function Overload Signatures`), static and instance methods
1429(:ref:`Method Overload Signatures`), and constructors
1430(:ref:`Constructor Overload Signatures`).
1431
1432All signatures except the last *implementation signature* are considered
1433*syntactic sugar*. The compiler uses the *implementation signature* only
1434as it considers overloading, overriding, shadowing, or calls.
1435
1436.. index::
1437   overload signature
1438   alignment
1439   constructor
1440   implementation signature
1441   syntactic sugar
1442   signature
1443   overloading
1444   overriding
1445   shadowing
1446   call
1447
1448|
1449
1450.. _Overload Signature Correctness Check:
1451
1452Overload Signature Correctness Check
1453====================================
1454
1455If a function, method, or constructor has several *overload signatures*
1456that share the same body, then all first signatures without bodies must
1457*fit* into the *implementation signature* that has the body. Otherwise,
1458a :index:`compile-time error` occurs.
1459
1460Signature *S*:sub:`i` with *n* parameters *fits* into implementation signature
1461*IS* if **all** of the following conditions are met:
1462
1463- *S*:sub:`i` has *n* parameters, *IS* has *m* parameters, and:
1464
1465   -  ``n <= m``;
1466   -  All ``n`` parameter types in *S*:sub:`i` are compatible (see
1467      :ref:`Type Compatibility`) with parameter types in the same positions
1468      in *IS*:sub:`2`;
1469   -  All *IS* parameters in positions from ``n + 1`` up to ``m`` are optional
1470      (see :ref:`Optional Parameters`) if ``n < m``.
1471
1472- *IS* return type is ``void`` (see :ref:`Type void`), then *S*:sub:`i` return
1473  type must also be ``void``.
1474
1475- *IS* return type is not ``void``, then *S*:sub:`i` return type must be
1476  ``void`` (see :ref:`Type void`) or compatible with the return type of *IS*
1477  (see :ref:`Type Compatibility`).
1478
1479.. index::
1480   overload signature
1481   correctness check
1482   parameter
1483   implementation signature
1484   function
1485   method
1486   constructor
1487   compatibility
1488   return type
1489
1490The examples below represent valid overload signatures:
1491
1492.. code-block-meta:
1493   expect-cte:
1494
1495.. code-block:: typescript
1496   :linenos:
1497
1498    function f1(): void
1499    function f1(x: number): void
1500    function f1(x?: number): void {
1501        /*body*/
1502    }
1503
1504    function f2(x: number): void
1505    function f2(x: string): void
1506    function f2(x: number | string): void {
1507        /*body*/
1508    }
1509
1510    function f3(x: number): void
1511    function f3(x: string): number
1512    function f3(x: number | string): number {
1513        return 1
1514    }
1515
1516The examples below represent code with compile-time errors:
1517
1518.. code-block:: typescript
1519   :linenos:
1520
1521    function f4(x: number): void
1522    function f4(x: boolean): number // This signature does not fit
1523    function f4(x: number | string): void {
1524        /*body*/
1525    }
1526
1527    function f5(x: number): void
1528    function f5(x: string): number // Wrong return type
1529    function f5(x: number | string): void {
1530        /*body*/
1531    }
1532
1533|
1534
1535.. _Compatibility Features:
1536
1537Compatibility Features
1538**********************
1539
1540Some features are added to |LANG| in order to support smooth |TS| compatibility.
1541Using these features while doing the |LANG| programming is not recommended in
1542most cases.
1543
1544.. index::
1545   overload signature compatibility
1546   compatibility
1547
1548|
1549
1550.. _Extended Conditional Expressions:
1551
1552Extended Conditional Expressions
1553================================
1554
1555.. meta:
1556    frontend_status: Done
1557
1558|LANG| provides extended semantics for conditional expressions
1559to ensure better |TS| alignment.
1560It affects the semantics of
1561
1562-  Conditional expressions (see :ref:`Conditional Expressions`,
1563   :ref:`Conditional-And Expression`, :ref:`Conditional-Or Expression`, and
1564   :ref:`Logical Complement`);
1565
1566-  ``while`` and ``do`` statements (see :ref:`While Statements and Do Statements`);
1567
1568-  ``for`` statements (see :ref:`For Statements`);
1569
1570-  ``if`` statements (see :ref:`if Statements`);
1571
1572-  assignment (see :ref:`Simple Assignment Operator`).
1573
1574**Note:** The extended semantics is to be deprecated in one of the future
1575versions of the language.
1576
1577This approach is based on the concept of *truthiness* that extends the Boolean
1578logic to operands of non-Boolean types.
1579
1580Depending on the kind of the value type, the value of any valid expression can
1581be handled as ``true`` or ``false`` as described in the table below:
1582
1583.. index::
1584   extended conditional expression
1585   semantic alignment
1586   conditional-and expression
1587   conditional-or expression
1588   conditional expression
1589   while statement
1590   do statement
1591   for statement
1592   if statement
1593   truthiness
1594   Boolean
1595   value type
1596
1597+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+
1598| Value Type                           | When ``false``                         | When ``true``                     | |LANG| Code                     |
1599+======================================+========================================+===================================+=================================+
1600| ``string``                           | empty string                           | non-empty string                  | ``s.length == 0``               |
1601+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+
1602| ``boolean``                          | ``false``                              | ``true``                          | ``x``                           |
1603+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+
1604| ``enum``                             | ``enum`` constant                      | enum constant                     | ``x.getValue()``                |
1605|                                      |                                        |                                   |                                 |
1606|                                      | handled as ``false``                   | handled as ``true``               |                                 |
1607+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+
1608| ``number`` (``double``/``float``)    | ``0`` or ``NaN``                       | any other number                  | ``n != 0 && n != NaN``          |
1609+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+
1610| any integer type                     | ``== 0``                               | ``!= 0``                          | ``i != 0``                      |
1611+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+
1612| ``char``                             | ``== 0``                               | ``!= 0``                          | ``c != c'0'``                   |
1613+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+
1614| let T - is any nonNullish type                                                                                                                      |
1615+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+
1616| ``T | null``                         | ``== null``                            | ``!= null``                       | ``x != null``                   |
1617+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+
1618| ``T | undefined``                    | ``== undefined``                       | ``!= undefined``                  | ``x != undefined``              |
1619+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+
1620| ``T | undefined | null``             | ``== undefined`` or ``== null``        | ``!= undefined`` and ``!= null``  | ``x != undefined && x != null`` |
1621+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+
1622| Boxed primitive type                 | primitive type is ``false``            | primitive type is ``true``        | ``new Boolean(true) == true``   |
1623| (``Boolean``, ``Char``, ``Int`` ...) |                                        |                                   | ``new Int (0) == 0``            |
1624+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+
1625| any other nonNullish type            | ``never``                              | ``always``                        | ``new SomeType != null``        |
1626+--------------------------------------+----------------------------------------+-----------------------------------+---------------------------------+
1627
1628Extended semantics of :ref:`Conditional-And Expression` and
1629:ref:`Conditional-Or Expression` affects the resultant type of expressions
1630as follows:
1631
1632-  A *conditional-and* expression ``A && B`` is of type ``B`` if the result of
1633   ``A`` is handled as ``true``. Otherwise, it is of type ``A``.
1634
1635-  A *conditional-or* expression ``A || B`` is of type ``B`` if the result of
1636   ``A`` is handled as ``false``. Otherwise, it is of type ``A``.
1637
1638
1639The example below illustrates the way this approach works in practice. Any
1640``nonzero`` number is handled as ``true``. The loop continues until it becomes
1641``zero`` that is handled as ``false``:
1642
1643.. code-block-meta:
1644
1645.. code-block:: typescript
1646   :linenos:
1647
1648    for (let i = 10; i; i--) {
1649       console.log (i)
1650    }
1651    /* And the output will be
1652         10
1653         9
1654         8
1655         7
1656         6
1657         5
1658         4
1659         3
1660         2
1661         1
1662     */
1663
1664.. index::
1665   NaN
1666   nullish expression
1667   numeric expression
1668   conditional-and expression
1669   conditional-or expression
1670   loop
1671
1672
1673.. raw:: pdf
1674
1675   PageBreak
1676
1677
1678