mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
support abstract signatures
This commit is contained in:
@@ -947,6 +947,9 @@ export class TypeTable {
|
|||||||
* Returns a unique string for the given call/constructor signature.
|
* Returns a unique string for the given call/constructor signature.
|
||||||
*/
|
*/
|
||||||
private getSignatureString(kind: ts.SignatureKind, signature: AugmentedSignature): string {
|
private getSignatureString(kind: ts.SignatureKind, signature: AugmentedSignature): string {
|
||||||
|
let modifiers : ts.ModifiersArray = signature.getDeclaration()?.modifiers;
|
||||||
|
let isAbstract = modifiers && modifiers.filter(modifier => modifier.kind == ts.SyntaxKind.AbstractKeyword).length > 0
|
||||||
|
|
||||||
let parameters = signature.getParameters();
|
let parameters = signature.getParameters();
|
||||||
let numberOfTypeParameters = signature.typeParameters == null
|
let numberOfTypeParameters = signature.typeParameters == null
|
||||||
? 0
|
? 0
|
||||||
@@ -978,7 +981,7 @@ export class TypeTable {
|
|||||||
if (returnTypeId == null) {
|
if (returnTypeId == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let tag = `${kind};${numberOfTypeParameters};${requiredParameters};${restParameterTag};${returnTypeId}`;
|
let tag = `${kind};${isAbstract ? "t" : "f"};${numberOfTypeParameters};${requiredParameters};${restParameterTag};${returnTypeId}`;
|
||||||
for (let typeParameter of signature.typeParameters || []) {
|
for (let typeParameter of signature.typeParameters || []) {
|
||||||
tag += ";" + typeParameter.symbol.name;
|
tag += ";" + typeParameter.symbol.name;
|
||||||
let constraint = typeParameter.getConstraint();
|
let constraint = typeParameter.getConstraint();
|
||||||
|
|||||||
@@ -202,18 +202,22 @@ public class TypeExtractor {
|
|||||||
|
|
||||||
private void extractSignature(int index) {
|
private void extractSignature(int index) {
|
||||||
// Format is:
|
// Format is:
|
||||||
// kind;numTypeParams;requiredParams;restParamType;returnType(;paramName;paramType)*
|
// kind;isAbstract;numTypeParams;requiredParams;restParamType;returnType(;paramName;paramType)*
|
||||||
String[] parts = split(table.getSignatureString(index));
|
String[] parts = split(table.getSignatureString(index));
|
||||||
Label label = trapWriter.globalID("signature;" + index);
|
Label label = trapWriter.globalID("signature;" + index);
|
||||||
int kind = Integer.parseInt(parts[0]);
|
int kind = Integer.parseInt(parts[0]);
|
||||||
int numberOfTypeParameters = Integer.parseInt(parts[1]);
|
boolean isAbstract = parts[1].equals("t");
|
||||||
int requiredParameters = Integer.parseInt(parts[2]);
|
if (isAbstract) {
|
||||||
String restParamTypeTag = parts[3];
|
trapWriter.addTuple("is_abstract_signature", label);
|
||||||
|
}
|
||||||
|
int numberOfTypeParameters = Integer.parseInt(parts[2]);
|
||||||
|
int requiredParameters = Integer.parseInt(parts[3]);
|
||||||
|
String restParamTypeTag = parts[4];
|
||||||
if (!restParamTypeTag.isEmpty()) {
|
if (!restParamTypeTag.isEmpty()) {
|
||||||
trapWriter.addTuple(
|
trapWriter.addTuple(
|
||||||
"signature_rest_parameter", label, trapWriter.globalID("type;" + restParamTypeTag));
|
"signature_rest_parameter", label, trapWriter.globalID("type;" + restParamTypeTag));
|
||||||
}
|
}
|
||||||
Label returnType = trapWriter.globalID("type;" + parts[4]);
|
Label returnType = trapWriter.globalID("type;" + parts[5]);
|
||||||
trapWriter.addTuple(
|
trapWriter.addTuple(
|
||||||
"signature_types",
|
"signature_types",
|
||||||
label,
|
label,
|
||||||
@@ -222,9 +226,9 @@ public class TypeExtractor {
|
|||||||
numberOfTypeParameters,
|
numberOfTypeParameters,
|
||||||
requiredParameters);
|
requiredParameters);
|
||||||
trapWriter.addTuple("signature_contains_type", returnType, label, -1);
|
trapWriter.addTuple("signature_contains_type", returnType, label, -1);
|
||||||
int numberOfParameters = (parts.length - 5) / 2; // includes type parameters
|
int numberOfParameters = (parts.length - 6) / 2; // includes type parameters
|
||||||
for (int i = 0; i < numberOfParameters; ++i) {
|
for (int i = 0; i < numberOfParameters; ++i) {
|
||||||
int partIndex = 5 + (2 * i);
|
int partIndex = 6 + (2 * i);
|
||||||
String paramName = parts[partIndex];
|
String paramName = parts[partIndex];
|
||||||
String paramTypeId = parts[partIndex + 1];
|
String paramTypeId = parts[partIndex + 1];
|
||||||
if (paramTypeId.length() > 0) { // Unconstrained type parameters have an empty type ID.
|
if (paramTypeId.length() > 0) { // Unconstrained type parameters have an empty type ID.
|
||||||
|
|||||||
@@ -2794,6 +2794,11 @@ class CallSignatureType extends @signature_type {
|
|||||||
* For example, for the signature `(...y: string[])`, this gets the type `string[]`.
|
* For example, for the signature `(...y: string[])`, this gets the type `string[]`.
|
||||||
*/
|
*/
|
||||||
PlainArrayType getRestParameterArrayType() { signature_rest_parameter(this, result) }
|
PlainArrayType getRestParameterArrayType() { signature_rest_parameter(this, result) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if this signature is abstract.
|
||||||
|
*/
|
||||||
|
predicate isAbstract() { is_abstract_signature(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -742,6 +742,10 @@ signature_types (
|
|||||||
int required_params: int ref
|
int required_params: int ref
|
||||||
);
|
);
|
||||||
|
|
||||||
|
is_abstract_signature(
|
||||||
|
unique int sig: @signature_type ref
|
||||||
|
);
|
||||||
|
|
||||||
signature_rest_parameter(
|
signature_rest_parameter(
|
||||||
unique int sig: @signature_type ref,
|
unique int sig: @signature_type ref,
|
||||||
int rest_param_arra_type: @type ref
|
int rest_param_arra_type: @type ref
|
||||||
|
|||||||
@@ -107,6 +107,13 @@ getExprType
|
|||||||
| tst.ts:48:20:48:27 | "string" | "string" |
|
| tst.ts:48:20:48:27 | "string" | "string" |
|
||||||
| tst.ts:49:11:49:11 | b | string |
|
| tst.ts:49:11:49:11 | b | string |
|
||||||
| tst.ts:49:24:49:24 | e | string |
|
| tst.ts:49:24:49:24 | e | string |
|
||||||
|
| tst.ts:55:3:55:9 | getArea | () => number |
|
||||||
|
| tst.ts:55:3:55:20 | getArea(): number; | () => number |
|
||||||
|
| tst.ts:59:3:59:9 | getArea | () => number |
|
||||||
|
| tst.ts:59:3:59:20 | getArea(): number; | () => number |
|
||||||
|
| tst.ts:63:5:63:8 | Ctor | abstract new () => HasArea |
|
||||||
|
| tst.ts:63:11:63:36 | abstrac ... HasArea | abstract new () => HasArea |
|
||||||
|
| tst.ts:63:40:63:44 | Shape | any |
|
||||||
| type_alias.ts:3:5:3:5 | b | boolean |
|
| type_alias.ts:3:5:3:5 | b | boolean |
|
||||||
| type_alias.ts:7:5:7:5 | c | ValueOrArray<number> |
|
| type_alias.ts:7:5:7:5 | c | ValueOrArray<number> |
|
||||||
| type_alias.ts:14:9:14:32 | [proper ... ]: Json | any |
|
| type_alias.ts:14:9:14:32 | [proper ... ]: Json | any |
|
||||||
@@ -156,6 +163,8 @@ getExprType
|
|||||||
| type_definitions.ts:19:5:19:5 | e | EnumWithOneMember |
|
| type_definitions.ts:19:5:19:5 | e | EnumWithOneMember |
|
||||||
| type_definitions.ts:22:5:22:23 | aliasForNumberArray | Alias<number> |
|
| type_definitions.ts:22:5:22:23 | aliasForNumberArray | Alias<number> |
|
||||||
getTypeDefinitionType
|
getTypeDefinitionType
|
||||||
|
| tst.ts:54:1:56:1 | interfa ... mber;\\n} | NonAbstractDummy |
|
||||||
|
| tst.ts:58:1:60:1 | interfa ... mber;\\n} | HasArea |
|
||||||
| type_alias.ts:1:1:1:17 | type B = boolean; | boolean |
|
| type_alias.ts:1:1:1:17 | type B = boolean; | boolean |
|
||||||
| type_alias.ts:5:1:5:50 | type Va ... ay<T>>; | ValueOrArray<T> |
|
| type_alias.ts:5:1:5:50 | type Va ... ay<T>>; | ValueOrArray<T> |
|
||||||
| type_alias.ts:9:1:15:13 | type Js ... Json[]; | Json |
|
| type_alias.ts:9:1:15:13 | type Js ... Json[]; | Json |
|
||||||
@@ -245,6 +254,12 @@ getTypeExprType
|
|||||||
| tst.ts:39:60:39:67 | number[] | number[] |
|
| tst.ts:39:60:39:67 | number[] | number[] |
|
||||||
| tst.ts:40:18:40:24 | unknown | unknown |
|
| tst.ts:40:18:40:24 | unknown | unknown |
|
||||||
| tst.ts:49:15:49:20 | string | string |
|
| tst.ts:49:15:49:20 | string | string |
|
||||||
|
| tst.ts:54:11:54:26 | NonAbstractDummy | NonAbstractDummy |
|
||||||
|
| tst.ts:55:14:55:19 | number | number |
|
||||||
|
| tst.ts:58:11:58:17 | HasArea | HasArea |
|
||||||
|
| tst.ts:59:14:59:19 | number | number |
|
||||||
|
| tst.ts:63:11:63:36 | abstrac ... HasArea | abstract new () => HasArea |
|
||||||
|
| tst.ts:63:30:63:36 | HasArea | HasArea |
|
||||||
| type_alias.ts:1:6:1:6 | B | boolean |
|
| type_alias.ts:1:6:1:6 | B | boolean |
|
||||||
| type_alias.ts:1:10:1:16 | boolean | boolean |
|
| type_alias.ts:1:10:1:16 | boolean | boolean |
|
||||||
| type_alias.ts:3:8:3:8 | B | boolean |
|
| type_alias.ts:3:8:3:8 | B | boolean |
|
||||||
@@ -317,9 +332,11 @@ referenceDefinition
|
|||||||
| Color.red | type_definitions.ts:14:3:14:5 | red |
|
| Color.red | type_definitions.ts:14:3:14:5 | red |
|
||||||
| E | type_definition_objects.ts:6:8:6:16 | enum E {} |
|
| E | type_definition_objects.ts:6:8:6:16 | enum E {} |
|
||||||
| EnumWithOneMember | type_definitions.ts:18:26:18:31 | member |
|
| EnumWithOneMember | type_definitions.ts:18:26:18:31 | member |
|
||||||
|
| HasArea | tst.ts:58:1:60:1 | interfa ... mber;\\n} |
|
||||||
| I<S> | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} |
|
| I<S> | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} |
|
||||||
| I<number> | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} |
|
| I<number> | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} |
|
||||||
| Json | type_alias.ts:9:1:15:13 | type Js ... Json[]; |
|
| Json | type_alias.ts:9:1:15:13 | type Js ... Json[]; |
|
||||||
|
| NonAbstractDummy | tst.ts:54:1:56:1 | interfa ... mber;\\n} |
|
||||||
| ValueOrArray<T> | type_alias.ts:5:1:5:50 | type Va ... ay<T>>; |
|
| ValueOrArray<T> | type_alias.ts:5:1:5:50 | type Va ... ay<T>>; |
|
||||||
| ValueOrArray<number> | type_alias.ts:5:1:5:50 | type Va ... ay<T>>; |
|
| ValueOrArray<number> | type_alias.ts:5:1:5:50 | type Va ... ay<T>>; |
|
||||||
| VirtualNode | type_alias.ts:19:1:21:57 | type Vi ... ode[]]; |
|
| VirtualNode | type_alias.ts:19:1:21:57 | type Vi ... ode[]]; |
|
||||||
@@ -356,3 +373,6 @@ unknownType
|
|||||||
| tst.ts:40:5:40:15 | unknownType | unknown |
|
| tst.ts:40:5:40:15 | unknownType | unknown |
|
||||||
| tst.ts:47:8:47:8 | e | unknown |
|
| tst.ts:47:8:47:8 | e | unknown |
|
||||||
| tst.ts:48:14:48:14 | e | unknown |
|
| tst.ts:48:14:48:14 | e | unknown |
|
||||||
|
abstractSignature
|
||||||
|
| (): HasArea |
|
||||||
|
| new (): HasArea |
|
||||||
|
|||||||
@@ -35,3 +35,5 @@ query predicate unknownType(Expr e, Type type) {
|
|||||||
type = e.getType() and
|
type = e.getType() and
|
||||||
e.getType() instanceof UnknownType
|
e.getType() instanceof UnknownType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query CallSignatureType abstractSignature() { result.isAbstract() }
|
||||||
|
|||||||
@@ -48,4 +48,16 @@ catch (e: unknown) {
|
|||||||
if (typeof e === "string") {
|
if (typeof e === "string") {
|
||||||
let b : string = e;
|
let b : string = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface NonAbstractDummy {
|
||||||
|
getArea(): number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface HasArea {
|
||||||
|
getArea(): number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// abstract construct signature!
|
||||||
|
let Ctor: abstract new () => HasArea = Shape;
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
from int a, int b
|
||||||
|
where none()
|
||||||
|
select a, b
|
||||||
@@ -742,6 +742,10 @@ signature_types (
|
|||||||
int required_params: int ref
|
int required_params: int ref
|
||||||
);
|
);
|
||||||
|
|
||||||
|
is_abstract_signature(
|
||||||
|
unique int sig: @signature_type ref
|
||||||
|
);
|
||||||
|
|
||||||
signature_rest_parameter(
|
signature_rest_parameter(
|
||||||
unique int sig: @signature_type ref,
|
unique int sig: @signature_type ref,
|
||||||
int rest_param_arra_type: @type ref
|
int rest_param_arra_type: @type ref
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
description: add support for TypeScript 4.2
|
description: add support for TypeScript 4.2
|
||||||
compatibility: full
|
compatibility: backwards
|
||||||
tuple_type_rest_index.rel: run tuple_type_rest_index.qlo
|
tuple_type_rest_index.rel: run tuple_type_rest_index.qlo
|
||||||
tuple_type_rest.rel: delete
|
tuple_type_rest.rel: delete
|
||||||
|
is_abstract_signature: run is_abstract_signature.qlo
|
||||||
Reference in New Issue
Block a user