support abstract signatures

This commit is contained in:
Erik Krogh Kristensen
2021-02-18 11:52:11 +01:00
parent f385c55f2c
commit 5ae3c5952c
10 changed files with 69 additions and 11 deletions

View File

@@ -947,6 +947,9 @@ export class TypeTable {
* Returns a unique string for the given call/constructor signature.
*/
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 numberOfTypeParameters = signature.typeParameters == null
? 0
@@ -978,7 +981,7 @@ export class TypeTable {
if (returnTypeId == 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 || []) {
tag += ";" + typeParameter.symbol.name;
let constraint = typeParameter.getConstraint();

View File

@@ -202,18 +202,22 @@ public class TypeExtractor {
private void extractSignature(int index) {
// Format is:
// kind;numTypeParams;requiredParams;restParamType;returnType(;paramName;paramType)*
// kind;isAbstract;numTypeParams;requiredParams;restParamType;returnType(;paramName;paramType)*
String[] parts = split(table.getSignatureString(index));
Label label = trapWriter.globalID("signature;" + index);
int kind = Integer.parseInt(parts[0]);
int numberOfTypeParameters = Integer.parseInt(parts[1]);
int requiredParameters = Integer.parseInt(parts[2]);
String restParamTypeTag = parts[3];
boolean isAbstract = parts[1].equals("t");
if (isAbstract) {
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()) {
trapWriter.addTuple(
"signature_rest_parameter", label, trapWriter.globalID("type;" + restParamTypeTag));
}
Label returnType = trapWriter.globalID("type;" + parts[4]);
Label returnType = trapWriter.globalID("type;" + parts[5]);
trapWriter.addTuple(
"signature_types",
label,
@@ -222,9 +226,9 @@ public class TypeExtractor {
numberOfTypeParameters,
requiredParameters);
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) {
int partIndex = 5 + (2 * i);
int partIndex = 6 + (2 * i);
String paramName = parts[partIndex];
String paramTypeId = parts[partIndex + 1];
if (paramTypeId.length() > 0) { // Unconstrained type parameters have an empty type ID.

View File

@@ -2794,6 +2794,11 @@ class CallSignatureType extends @signature_type {
* For example, for the signature `(...y: string[])`, this gets the type `string[]`.
*/
PlainArrayType getRestParameterArrayType() { signature_rest_parameter(this, result) }
/**
* Holds if this signature is abstract.
*/
predicate isAbstract() { is_abstract_signature(this) }
}
/**

View File

@@ -742,6 +742,10 @@ signature_types (
int required_params: int ref
);
is_abstract_signature(
unique int sig: @signature_type ref
);
signature_rest_parameter(
unique int sig: @signature_type ref,
int rest_param_arra_type: @type ref

View File

@@ -107,6 +107,13 @@ getExprType
| tst.ts:48:20:48:27 | "string" | "string" |
| tst.ts:49:11:49:11 | b | 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:7:5:7:5 | c | ValueOrArray<number> |
| 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:22:5:22:23 | aliasForNumberArray | Alias<number> |
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:5:1:5:50 | type Va ... ay<T>>; | ValueOrArray<T> |
| 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:40:18:40:24 | unknown | unknown |
| 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:10:1:16 | boolean | 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 |
| E | type_definition_objects.ts:6:8:6:16 | enum E {} |
| 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<number> | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} |
| 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<number> | type_alias.ts:5:1:5:50 | type Va ... ay<T>>; |
| 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:47:8:47:8 | e | unknown |
| tst.ts:48:14:48:14 | e | unknown |
abstractSignature
| (): HasArea |
| new (): HasArea |

View File

@@ -35,3 +35,5 @@ query predicate unknownType(Expr e, Type type) {
type = e.getType() and
e.getType() instanceof UnknownType
}
query CallSignatureType abstractSignature() { result.isAbstract() }

View File

@@ -49,3 +49,15 @@ catch (e: unknown) {
let b : string = e;
}
}
interface NonAbstractDummy {
getArea(): number;
}
interface HasArea {
getArea(): number;
}
// abstract construct signature!
let Ctor: abstract new () => HasArea = Shape;

View File

@@ -0,0 +1,3 @@
from int a, int b
where none()
select a, b

View File

@@ -742,6 +742,10 @@ signature_types (
int required_params: int ref
);
is_abstract_signature(
unique int sig: @signature_type ref
);
signature_rest_parameter(
unique int sig: @signature_type ref,
int rest_param_arra_type: @type ref

View File

@@ -1,4 +1,5 @@
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.rel: delete
is_abstract_signature: run is_abstract_signature.qlo