TypeScript: support optional and rest elements in static tuple type

This commit is contained in:
Asger F
2018-08-20 15:53:23 +01:00
parent 96005d2147
commit d26aa04642
4 changed files with 57 additions and 1 deletions

View File

@@ -2166,7 +2166,7 @@ class TupleType extends ArrayType, @tupletype {
}
/**
* Gets the number of elements in this tuple type.
* Gets the number of elements in this tuple type, including optional elements and the rest element.
*/
int getNumElementType() {
result = count(int i | exists(getElementType(i)))
@@ -2181,6 +2181,31 @@ class TupleType extends ArrayType, @tupletype {
PlainArrayType getUnderlyingArrayType() {
result.getArrayElementType() = getArrayElementType()
}
/**
* Gets the number of required tuple elements, that is, excluding optional and rest elements.
*
* For example, the minimum length of `[number, string?, ...number[]]` is 1.
*/
int getMinimumLength() {
tuple_type_min_length(this, result)
}
/**
* Holds if this tuple type ends with a rest element, such as `[number, ...string[]]`.
*/
predicate hasRestElement() {
tuple_type_rest(this)
}
/**
* Gets the type of the rest element, if there is one.
*
* For example, the rest element of `[number, ...string[]]` is `string`.
*/
Type getRestElementType() {
hasRestElement() and result = getElementType(getNumElementType() - 1)
}
}
/**

View File

@@ -738,6 +738,15 @@ self_types(
int selfType: @typereference ref
);
tuple_type_min_length(
unique int typ: @type ref,
int minLength: int ref
);
tuple_type_rest(
unique int typ: @type ref
);
// comments
comments (unique int id: @comment,
int kind: int ref,

View File

@@ -0,0 +1,10 @@
| tst.ts:34:5:34:9 | tuple | [number, string] | 0 | number | 2 | no-rest |
| tst.ts:34:5:34:9 | tuple | [number, string] | 1 | string | 2 | no-rest |
| tst.ts:36:5:36:28 | tupleWi ... Element | [number, string, number?] | 0 | number | 2 | no-rest |
| tst.ts:36:5:36:28 | tupleWi ... Element | [number, string, number?] | 1 | string | 2 | no-rest |
| tst.ts:36:5:36:28 | tupleWi ... Element | [number, string, number?] | 2 | number | 2 | no-rest |
| tst.ts:38:5:38:24 | tupleWithRestElement | [number, ...string[]] | 0 | number | 1 | string |
| tst.ts:38:5:38:24 | tupleWithRestElement | [number, ...string[]] | 1 | string | 1 | string |
| tst.ts:39:5:39:36 | tupleWi ... lements | [number, string?, ...number[]] | 0 | number | 1 | number |
| tst.ts:39:5:39:36 | tupleWi ... lements | [number, string?, ...number[]] | 1 | string | 1 | number |
| tst.ts:39:5:39:36 | tupleWi ... lements | [number, string?, ...number[]] | 2 | number | 1 | number |

View File

@@ -0,0 +1,12 @@
import javascript
string getRest(TupleType tuple) {
if tuple.hasRestElement() then
result = tuple.getRestElementType().toString()
else
result = "no-rest"
}
from Expr e, TupleType tuple, int n
where e.getType() = tuple
select e, tuple, n, tuple.getElementType(n), tuple.getMinimumLength(), getRest(tuple)