Merge pull request #2379 from asger-semmle/typescript-fixes

TS: A bunch of TypeScript fixes
This commit is contained in:
Esben Sparre Andreasen
2019-11-22 13:31:30 +01:00
committed by GitHub
58 changed files with 3116 additions and 80 deletions

View File

@@ -1816,7 +1816,7 @@ class Type extends @type {
*
* For example, for a type `(S & T) | U` this gets the types `S`, `T`, and `U`.
*/
Type unfold() {
Type unfoldUnionAndIntersection() {
not result instanceof UnionOrIntersectionType and
(
result = this
@@ -1829,6 +1829,27 @@ class Type extends @type {
)
}
/**
* Repeatedly unfolds unions, intersections, and type aliases and gets any of the underlying types,
* or this type itself if it is not a union or intersection.
*
* For example, the type `(S & T) | U` unfolds to `S`, `T`, and `U`.
*
* If this is a type alias, the alias is itself included in the result, but this is not the case for intermediate type aliases.
* For example:
* ```js
* type One = number | string;
* type Two = One | Function & {x: string};
* One; // unfolds to number, string, and One
* Two; // unfolds to number, string, One, Function, {x: string}, and Two
* ```
*/
Type unfold() {
result = unfoldUnionAndIntersection()
or
result = this.(TypeAliasReference).getAliasedType().unfoldUnionAndIntersection()
}
/**
* Holds if this refers to the given named type, or is declared as a subtype thereof,
* or is a union or intersection containing such a type.
@@ -2287,6 +2308,24 @@ class EnumLiteralType extends TypeReference {
EnumMember getEnumMember() { result = declaration }
}
/**
* A type that refers to a type alias.
*/
class TypeAliasReference extends TypeReference {
TypeAliasReference() {
type_alias(this, _)
}
/**
* Gets the type behind the type alias.
*
* For example, for `type B<T> = T[][]`, this maps the type `B<number>` to `number[][]`.
*/
Type getAliasedType() {
type_alias(this, result)
}
}
/**
* An anonymous interface type, such as `{ x: number }`.
*/
@@ -2516,17 +2555,19 @@ class CallSignatureType extends @signature_type {
predicate hasTypeParameters() { getNumTypeParameter() > 0 }
/**
* Gets the type of the `n`th parameter of this signature.
* Gets the type of the `n`th parameter declared in this signature.
*
* If the `n`th parameter is a rest parameter `...T[]`, gets type `T`.
*/
Type getParameter(int n) { n >= 0 and result = getChild(n + getNumTypeParameter()) }
/**
* Gets the type of a parameter of this signature.
* Gets the type of a parameter of this signature, including the rest parameter, if any.
*/
Type getAParameter() { result = getParameter(_) }
/**
* Gets the number of parameters.
* Gets the number of parameters, including the rest parameter, if any.
*/
int getNumParameter() { result = count(int i | exists(getParameter(i))) }
@@ -2538,7 +2579,7 @@ class CallSignatureType extends @signature_type {
/**
* Gets the number of optional parameters, that is,
* parameters that are marked as optional with the `?` suffix.
* parameters that are marked as optional with the `?` suffix or is a rest parameter.
*/
int getNumOptionalParameter() { result = getNumParameter() - getNumRequiredParameter() }
@@ -2552,7 +2593,9 @@ class CallSignatureType extends @signature_type {
}
/**
* Holds if the `n`th parameter is declared optional with the `?` suffix.
* Holds if the `n`th parameter is declared optional with the `?` suffix or is the rest parameter.
*
* Note that rest parameters are not considered optional in this sense.
*/
predicate isOptionalParameter(int n) {
exists(getParameter(n)) and
@@ -2571,6 +2614,30 @@ class CallSignatureType extends @signature_type {
* Gets the name of a parameter of this signature.
*/
string getAParameterName() { result = getParameterName(_) }
/**
* Holds if this signature declares a rest parameter, such as `(x: number, ...y: string[])`.
*/
predicate hasRestParameter() { signature_rest_parameter(this, _) }
/**
* Gets the type of the rest parameter, if any.
*
* For example, for the signature `(...y: string[])`, this gets the type `string`.
*/
Type getRestParameterType() {
hasRestParameter() and
result = getParameter(getNumParameter() - 1)
}
/**
* Gets the type of the rest parameter as an array, if it exists.
*
* For example, for the signature `(...y: string[])`, this gets the type `string[]`.
*/
PlainArrayType getRestParameterArrayType() {
signature_rest_parameter(this, result)
}
}
/**

View File

@@ -749,6 +749,21 @@ class Parameter extends BindingPattern {
JSDocTag getJSDocTag() {
none() // overridden in SimpleParameter
}
/**
* Holds if this is a parameter declared optional with the `?` token.
*
* Note that this does not hold for rest parameters, and does not in general
* hold for parameters with defaults.
*
* For example, `x`, is declared optional below:
* ```
* function f(x?: number) {}
* ```
*/
predicate isDeclaredOptional() {
isOptionalParameterDeclaration(this)
}
}
/**

View File

@@ -520,6 +520,7 @@ hasProtectedKeyword (int id: @property ref);
hasReadonlyKeyword (int id: @property ref);
isOptionalMember (int id: @property ref);
hasDefiniteAssignmentAssertion (int id: @field_or_vardeclarator ref);
isOptionalParameterDeclaration (unique int parameter: @pattern ref);
#keyset[constructor, param_index]
parameter_fields(
@@ -703,6 +704,10 @@ type_property(
varchar(900) name: string ref,
int propertyType: @type ref);
type_alias(
unique int aliasType: @type ref,
int underlyingType: @type ref);
@literaltype = @stringliteraltype | @numberliteraltype | @booleanliteraltype | @bigintliteraltype;
@type_with_literal_value = @stringliteraltype | @numberliteraltype | @bigintliteraltype;
type_literal_value(
@@ -717,6 +722,11 @@ signature_types (
int required_params: int ref
);
signature_rest_parameter(
unique int sig: @signature_type ref,
int rest_param_arra_type: @type ref
);
case @signature_type.kind of
0 = @function_signature_type
| 1 = @constructor_signature_type

View File

@@ -8006,6 +8006,17 @@
<dependencies/>
</relation>
<relation>
<name>isOptionalParameterDeclaration</name>
<cardinality>3966</cardinality>
<columnsizes>
<e>
<k>parameter</k>
<v>3966</v>
</e>
</columnsizes>
<dependencies/>
</relation>
<relation>
<name>parameter_fields</name>
<cardinality>2693</cardinality>
<columnsizes>
@@ -13516,6 +13527,54 @@
<dependencies/>
</relation>
<relation>
<name>type_alias</name>
<cardinality>1386</cardinality>
<columnsizes>
<e>
<k>aliasType</k>
<v>1386</v>
</e>
<e>
<k>underlyingType</k>
<v>1361</v>
</e>
</columnsizes>
<dependencies>
<dep>
<src>underlyingType</src>
<trg>aliasType</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>1</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>aliasType</src>
<trg>underlyingType</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>1</v>
</b>
</bs>
</hist>
</val>
</dep>
</dependencies>
</relation>
<relation>
<name>type_literal_value</name>
<cardinality>31882</cardinality>
<columnsizes>
@@ -14222,6 +14281,54 @@
</dependencies>
</relation>
<relation>
<name>signature_rest_parameter</name>
<cardinality>19521</cardinality>
<columnsizes>
<e>
<k>sig</k>
<v>19521</v>
</e>
<e>
<k>rest_param_arra_type</k>
<v>14259</v>
</e>
</columnsizes>
<dependencies>
<dep>
<src>rest_param_arra_type</src>
<trg>sig</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>1</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>sig</src>
<trg>rest_param_arra_type</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>1</v>
</b>
</bs>
</hist>
</val>
</dep>
</dependencies>
</relation>
<relation>
<name>type_contains_signature</name>
<cardinality>87640</cardinality>
<columnsizes>