JS: Add TemplateLiteralTypeExpr

This commit is contained in:
Asger Feldthaus
2020-10-29 21:14:27 +00:00
parent 9da5c5cc70
commit 5676891e44
14 changed files with 210 additions and 7 deletions

View File

@@ -0,0 +1,49 @@
package com.semmle.ts.ast;
import java.util.ArrayList;
import java.util.List;
import com.semmle.js.ast.Expression;
import com.semmle.js.ast.INode;
import com.semmle.js.ast.Node;
import com.semmle.js.ast.SourceLocation;
import com.semmle.js.ast.TemplateElement;
import com.semmle.js.ast.TemplateLiteral;
import com.semmle.js.ast.Visitor;
/**
* A template literal used in a type, such as in <code>type T = `Hello, ${name}!`</code>.
*/
public class TemplateLiteralTypeExpr extends TypeExpression {
private final List<ITypeExpression> expressions;
private final List<TemplateElement> quasis;
private final List<Node> children;
public TemplateLiteralTypeExpr(
SourceLocation loc, List<ITypeExpression> expressions, List<TemplateElement> quasis) {
super("TemplateLiteralTypeExpr", loc);
this.expressions = expressions;
this.quasis = quasis;
this.children = TemplateLiteral.<Node>mergeChildren(expressions, quasis);
}
@Override
public <Q, A> A accept(Visitor<Q, A> v, Q q) {
return v.visit(this, q);
}
/** The type expressions in this template. */
public List<ITypeExpression> getExpressions() {
return expressions;
}
/** The template elements in this template. */
public List<TemplateElement> getQuasis() {
return quasis;
}
/** All type expressions and template elements in this template, in lexical order. */
public List<Node> getChildren() {
return children;
}
}

View File

@@ -145,6 +145,7 @@ import com.semmle.ts.ast.OptionalTypeExpr;
import com.semmle.ts.ast.ParenthesizedTypeExpr;
import com.semmle.ts.ast.PredicateTypeExpr;
import com.semmle.ts.ast.RestTypeExpr;
import com.semmle.ts.ast.TemplateLiteralTypeExpr;
import com.semmle.ts.ast.TupleTypeExpr;
import com.semmle.ts.ast.TypeAliasDeclaration;
import com.semmle.ts.ast.TypeAssertion;
@@ -576,6 +577,8 @@ public class TypeScriptASTConverter {
case "TemplateMiddle":
case "TemplateTail":
return convertTemplateElement(node, kind, loc);
case "TemplateLiteralType":
return convertTemplateLiteralType(node, loc);
case "ThisKeyword":
return convertThisKeyword(loc);
case "ThisType":
@@ -2152,6 +2155,19 @@ public class TypeScriptASTConverter {
return new TemplateLiteral(loc, expressions, quasis);
}
private Node convertTemplateLiteralType(JsonObject node, SourceLocation loc) throws ParseError {
List<TemplateElement> quasis;
List<ITypeExpression> expressions = new ArrayList<>();
quasis = new ArrayList<>();
quasis.add(convertChild(node, "head"));
for (JsonElement elt : node.get("templateSpans").getAsJsonArray()) {
JsonObject templateSpan = (JsonObject) elt;
expressions.add(convertChildAsType(templateSpan, "type"));
quasis.add(convertChild(templateSpan, "literal"));
}
return new TemplateLiteralTypeExpr(loc, expressions, quasis);
}
private Node convertTemplateElement(JsonObject node, String kind, SourceLocation loc) {
boolean tail = "TemplateTail".equals(kind);
if (loc.getSource().startsWith("`") || loc.getSource().startsWith("}")) {