TS: add support for bigints

This commit is contained in:
Asger F
2019-01-14 17:34:27 +00:00
parent 1c6deb65cd
commit 3ed9575529
20 changed files with 119 additions and 6 deletions

View File

@@ -1,5 +1,6 @@
package com.semmle.js.extractor;
import com.semmle.jcorn.TokenType;
import com.semmle.js.ast.DefaultVisitor;
import com.semmle.js.ast.INode;
import com.semmle.js.ast.Identifier;
@@ -64,6 +65,7 @@ public class TypeExprKinds {
private static final int importVarTypeAccess = 32;
private static final int optionalTypeExpr = 33;
private static final int restTypeExpr = 34;
private static final int bigintLiteralTypeExpr = 35;
public static int getTypeExprKind(final INode type, final IdContext idcontext) {
Integer kind = type.accept(new DefaultVisitor<Void, Integer>() {
@@ -159,6 +161,7 @@ public class TypeExprKinds {
@Override
public Integer visit(Literal nd, Void c) {
TokenType type = nd.getTokenType();
if (nd.getValue() == null) {
// We represent the null type as a keyword type in QL, but in the extractor AST
// it is a Literal because the TypeScript AST does not distinguish those.
@@ -167,12 +170,14 @@ public class TypeExprKinds {
// - TypeScript documentation does not treat the null type as a literal type.
// - There is an "undefined" type, but there is no "undefined" literal.
return keywordTypeExpr;
} else if (nd.getValue() instanceof String) {
} else if (type == TokenType.string) {
return stringLiteralTypeExpr;
} else if (nd.getValue() instanceof Number) {
} else if (type == TokenType.num) {
return numberLiteralTypeExpr;
} else if (nd.getValue() instanceof Boolean) {
} else if (type == TokenType._true || type == TokenType._false) {
return booeleanLiteralTypeExpr;
} else if (type == TokenType.bigint) {
return bigintLiteralTypeExpr;
} else {
throw new CatastrophicError("Unsupported literal type expression kind: " + nd.getValue().getClass());
}

View File

@@ -369,6 +369,10 @@ public class TypeScriptASTConverter {
return convertAsExpression(node, loc);
case "AwaitExpression":
return convertAwaitExpression(node, loc);
case "BigIntKeyword":
return convertKeywordTypeExpr(node, loc, "bigint");
case "BigIntLiteral":
return convertBigIntLiteral(node, loc);
case "BinaryExpression":
return convertBinaryExpression(node, loc);
case "Block":
@@ -822,6 +826,12 @@ public class TypeScriptASTConverter {
return new AwaitExpression(loc, convertChild(node, "expression"));
}
private Node convertBigIntLiteral(JsonObject node, SourceLocation loc) throws ParseError {
String text = node.get("text").getAsString();
String value = text.substring(0, text.length() - 1); // Remove the 'n' suffix.
return new Literal(loc, TokenType.bigint, value);
}
private Node convertBinaryExpression(JsonObject node, SourceLocation loc) throws ParseError {
Expression left = convertChild(node, "left");
Expression right = convertChild(node, "right");

View File

@@ -31,6 +31,7 @@ public class TypeExtractor {
private static final int thisKind = 20;
private static final int numberLiteralTypeKind = 21;
private static final int stringLiteralTypeKind = 22;
private static final int bigintLiteralTypeKind = 25;
static {
tagToKind.put("any", 0);
@@ -57,6 +58,8 @@ public class TypeExtractor {
tagToKind.put("numlit", numberLiteralTypeKind);
tagToKind.put("strlit", stringLiteralTypeKind);
tagToKind.put("unknown", 23);
tagToKind.put("bigint", 24);
tagToKind.put("bigintlit", bigintLiteralTypeKind);
}
private static final Map<String, Integer> symbolKind = new LinkedHashMap<String, Integer>();
@@ -126,6 +129,7 @@ public class TypeExtractor {
case numberLiteralTypeKind:
case stringLiteralTypeKind:
case bigintLiteralTypeKind:
firstChild = parts.length; // No children.
// The string value may contain `;` so don't use the split().
String value = contents.substring(parts[0].length() + 1);