Skip to content

Commit b4a2a9d

Browse files
committed
JS: Fix extraction of non-substitution template literal types
1 parent e1d0bbb commit b4a2a9d

File tree

5 files changed

+28
-6
lines changed

5 files changed

+28
-6
lines changed

javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import java.util.List;
66
import java.util.regex.Matcher;
77
import java.util.regex.Pattern;
8-
import java.util.stream.Collectors;
98

109
import com.google.gson.JsonArray;
1110
import com.google.gson.JsonElement;
@@ -1001,10 +1000,10 @@ private Node convertConditionalExpression(JsonObject node, SourceLocation loc) t
10011000
private Node convertConditionalType(JsonObject node, SourceLocation loc) throws ParseError {
10021001
return new ConditionalTypeExpr(
10031002
loc,
1004-
convertChild(node, "checkType"),
1005-
convertChild(node, "extendsType"),
1006-
convertChild(node, "trueType"),
1007-
convertChild(node, "falseType"));
1003+
convertChildAsType(node, "checkType"),
1004+
convertChildAsType(node, "extendsType"),
1005+
convertChildAsType(node, "trueType"),
1006+
convertChildAsType(node, "falseType"));
10081007
}
10091008

10101009
private SourceLocation getSourceRange(Position from, Position to) {
@@ -1613,6 +1612,10 @@ private Node convertLiteralType(JsonObject node, SourceLocation loc) throws Pars
16131612
literal = new Literal(loc, arg.getTokenType(), "-" + arg.getValue());
16141613
}
16151614
}
1615+
if (literal instanceof TemplateLiteral) {
1616+
// A LiteralType containing a NoSubstitutionTemplateLiteral must produce a TemplateLiteralTypeExpr
1617+
return new TemplateLiteralTypeExpr(literal.getLoc(), new ArrayList<>(), ((TemplateLiteral)literal).getQuasis());
1618+
}
16161619
return literal;
16171620
}
16181621

@@ -1842,7 +1845,7 @@ private Node convertOmittedExpression() {
18421845
}
18431846

18441847
private Node convertOptionalType(JsonObject node, SourceLocation loc) throws ParseError {
1845-
return new OptionalTypeExpr(loc, convertChild(node, "type"));
1848+
return new OptionalTypeExpr(loc, convertChildAsType(node, "type"));
18461849
}
18471850

18481851
private ITypeExpression asType(Node node) {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
| tst.ts:2:11:2:21 | `foo ${T1}` |
2+
| tst.ts:4:45:4:49 | `foo` |
3+
| tst.ts:4:53:4:57 | `bar` |
4+
| tst.ts:5:46:5:50 | `foo` |
5+
| tst.ts:5:54:5:63 | `bar ${K}` |
6+
| tst.ts:7:15:7:19 | `foo` |
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import javascript
2+
3+
query TemplateLiteralTypeExpr literalType() { any() }
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"include": ["."]
3+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
type T1 = 'foo' | 'bar';
2+
type T2 = `foo ${T1}`;
3+
4+
type FooToBar<K extends string> = K extends `foo` ? `bar` : K;
5+
type FooToBar2<K extends string> = K extends `foo` ? `bar ${K}` : K;
6+
7+
type Tuple = [`foo`?];

0 commit comments

Comments
 (0)