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. * 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();

View File

@@ -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.

View File

@@ -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) }
} }
/** /**

View File

@@ -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

View File

@@ -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 |

View File

@@ -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() }

View File

@@ -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;

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 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

View File

@@ -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