Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
lgtm,codescanning
* Fixed a bug that could cause extraction to fail when extracting a TypeScript
code base containing a template literal type without substitutions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
Expand Down Expand Up @@ -1001,10 +1000,10 @@ private Node convertConditionalExpression(JsonObject node, SourceLocation loc) t
private Node convertConditionalType(JsonObject node, SourceLocation loc) throws ParseError {
return new ConditionalTypeExpr(
loc,
convertChild(node, "checkType"),
convertChild(node, "extendsType"),
convertChild(node, "trueType"),
convertChild(node, "falseType"));
convertChildAsType(node, "checkType"),
convertChildAsType(node, "extendsType"),
convertChildAsType(node, "trueType"),
convertChildAsType(node, "falseType"));
}

private SourceLocation getSourceRange(Position from, Position to) {
Expand Down Expand Up @@ -1613,6 +1612,10 @@ private Node convertLiteralType(JsonObject node, SourceLocation loc) throws Pars
literal = new Literal(loc, arg.getTokenType(), "-" + arg.getValue());
}
}
if (literal instanceof TemplateLiteral) {
// A LiteralType containing a NoSubstitutionTemplateLiteral must produce a TemplateLiteralTypeExpr
return new TemplateLiteralTypeExpr(literal.getLoc(), new ArrayList<>(), ((TemplateLiteral)literal).getQuasis());
}
return literal;
}

Expand Down Expand Up @@ -1842,7 +1845,7 @@ private Node convertOmittedExpression() {
}

private Node convertOptionalType(JsonObject node, SourceLocation loc) throws ParseError {
return new OptionalTypeExpr(loc, convertChild(node, "type"));
return new OptionalTypeExpr(loc, convertChildAsType(node, "type"));
}

private ITypeExpression asType(Node node) {
Expand Down
269 changes: 242 additions & 27 deletions javascript/extractor/tests/ts/output/trap/importNonStrings.ts.trap
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,249 @@ hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},1,1"
toplevels(#20001,0)
#20002=@"loc,{#10000},1,1,1,1"
locations_default(#20002,#10000,1,1,1,1)
hasLocation(#20001,#20002)
#20003=*
js_parse_errors(#20003,#20001,"Error: Unsupported syntax in import","type Y = import(`Foo`);
")
#20004=@"loc,{#10000},2,10,2,10"
locations_default(#20004,#10000,2,10,2,10)
hasLocation(#20003,#20004)
#20005=*
lines(#20005,#20001,"type X = import(3);","
#20002=*
lines(#20002,#20001,"type X = import(3);","
")
#20006=@"loc,{#10000},1,1,1,19"
locations_default(#20006,#10000,1,1,1,19)
hasLocation(#20005,#20006)
#20007=*
lines(#20007,#20001,"type Y = import(`Foo`);","
#20003=@"loc,{#10000},1,1,1,19"
locations_default(#20003,#10000,1,1,1,19)
hasLocation(#20002,#20003)
#20004=*
lines(#20004,#20001,"type Y = import(`Foo`);","
")
#20008=@"loc,{#10000},2,1,2,23"
locations_default(#20008,#10000,2,1,2,23)
hasLocation(#20007,#20008)
#20009=*
lines(#20009,#20001,"type Z = import(Y);","
#20005=@"loc,{#10000},2,1,2,23"
locations_default(#20005,#10000,2,1,2,23)
hasLocation(#20004,#20005)
#20006=*
lines(#20006,#20001,"type Z = import(Y);","
")
#20010=@"loc,{#10000},3,1,3,19"
locations_default(#20010,#10000,3,1,3,19)
hasLocation(#20009,#20010)
numlines(#20001,3,0,0)
numlines(#10000,3,0,0)
#20007=@"loc,{#10000},3,1,3,19"
locations_default(#20007,#10000,3,1,3,19)
hasLocation(#20006,#20007)
numlines(#20001,3,3,0)
#20008=*
tokeninfo(#20008,7,#20001,0,"type")
#20009=@"loc,{#10000},1,1,1,4"
locations_default(#20009,#10000,1,1,1,4)
hasLocation(#20008,#20009)
#20010=*
tokeninfo(#20010,6,#20001,1,"X")
#20011=@"loc,{#10000},1,6,1,6"
locations_default(#20011,#10000,1,6,1,6)
hasLocation(#20010,#20011)
#20012=*
tokeninfo(#20012,8,#20001,2,"=")
#20013=@"loc,{#10000},1,8,1,8"
locations_default(#20013,#10000,1,8,1,8)
hasLocation(#20012,#20013)
#20014=*
tokeninfo(#20014,7,#20001,3,"import")
#20015=@"loc,{#10000},1,10,1,15"
locations_default(#20015,#10000,1,10,1,15)
hasLocation(#20014,#20015)
#20016=*
tokeninfo(#20016,8,#20001,4,"(")
#20017=@"loc,{#10000},1,16,1,16"
locations_default(#20017,#10000,1,16,1,16)
hasLocation(#20016,#20017)
#20018=*
tokeninfo(#20018,3,#20001,5,"3")
#20019=@"loc,{#10000},1,17,1,17"
locations_default(#20019,#10000,1,17,1,17)
hasLocation(#20018,#20019)
#20020=*
tokeninfo(#20020,8,#20001,6,")")
#20021=@"loc,{#10000},1,18,1,18"
locations_default(#20021,#10000,1,18,1,18)
hasLocation(#20020,#20021)
#20022=*
tokeninfo(#20022,8,#20001,7,";")
#20023=@"loc,{#10000},1,19,1,19"
locations_default(#20023,#10000,1,19,1,19)
hasLocation(#20022,#20023)
#20024=*
tokeninfo(#20024,7,#20001,8,"type")
#20025=@"loc,{#10000},2,1,2,4"
locations_default(#20025,#10000,2,1,2,4)
hasLocation(#20024,#20025)
#20026=*
tokeninfo(#20026,6,#20001,9,"Y")
#20027=@"loc,{#10000},2,6,2,6"
locations_default(#20027,#10000,2,6,2,6)
hasLocation(#20026,#20027)
#20028=*
tokeninfo(#20028,8,#20001,10,"=")
#20029=@"loc,{#10000},2,8,2,8"
locations_default(#20029,#10000,2,8,2,8)
hasLocation(#20028,#20029)
#20030=*
tokeninfo(#20030,7,#20001,11,"import")
#20031=@"loc,{#10000},2,10,2,15"
locations_default(#20031,#10000,2,10,2,15)
hasLocation(#20030,#20031)
#20032=*
tokeninfo(#20032,8,#20001,12,"(")
#20033=@"loc,{#10000},2,16,2,16"
locations_default(#20033,#10000,2,16,2,16)
hasLocation(#20032,#20033)
#20034=*
tokeninfo(#20034,4,#20001,13,"`Foo`")
#20035=@"loc,{#10000},2,17,2,21"
locations_default(#20035,#10000,2,17,2,21)
hasLocation(#20034,#20035)
#20036=*
tokeninfo(#20036,8,#20001,14,")")
#20037=@"loc,{#10000},2,22,2,22"
locations_default(#20037,#10000,2,22,2,22)
hasLocation(#20036,#20037)
#20038=*
tokeninfo(#20038,8,#20001,15,";")
#20039=@"loc,{#10000},2,23,2,23"
locations_default(#20039,#10000,2,23,2,23)
hasLocation(#20038,#20039)
#20040=*
tokeninfo(#20040,7,#20001,16,"type")
#20041=@"loc,{#10000},3,1,3,4"
locations_default(#20041,#10000,3,1,3,4)
hasLocation(#20040,#20041)
#20042=*
tokeninfo(#20042,6,#20001,17,"Z")
#20043=@"loc,{#10000},3,6,3,6"
locations_default(#20043,#10000,3,6,3,6)
hasLocation(#20042,#20043)
#20044=*
tokeninfo(#20044,8,#20001,18,"=")
#20045=@"loc,{#10000},3,8,3,8"
locations_default(#20045,#10000,3,8,3,8)
hasLocation(#20044,#20045)
#20046=*
tokeninfo(#20046,7,#20001,19,"import")
#20047=@"loc,{#10000},3,10,3,15"
locations_default(#20047,#10000,3,10,3,15)
hasLocation(#20046,#20047)
#20048=*
tokeninfo(#20048,8,#20001,20,"(")
#20049=@"loc,{#10000},3,16,3,16"
locations_default(#20049,#10000,3,16,3,16)
hasLocation(#20048,#20049)
#20050=*
tokeninfo(#20050,6,#20001,21,"Y")
#20051=@"loc,{#10000},3,17,3,17"
locations_default(#20051,#10000,3,17,3,17)
hasLocation(#20050,#20051)
#20052=*
tokeninfo(#20052,8,#20001,22,")")
#20053=@"loc,{#10000},3,18,3,18"
locations_default(#20053,#10000,3,18,3,18)
hasLocation(#20052,#20053)
#20054=*
tokeninfo(#20054,8,#20001,23,";")
#20055=@"loc,{#10000},3,19,3,19"
locations_default(#20055,#10000,3,19,3,19)
hasLocation(#20054,#20055)
#20056=*
tokeninfo(#20056,0,#20001,24,"")
#20057=@"loc,{#10000},4,1,4,0"
locations_default(#20057,#10000,4,1,4,0)
hasLocation(#20056,#20057)
toplevels(#20001,0)
#20058=@"loc,{#10000},1,1,4,0"
locations_default(#20058,#10000,1,1,4,0)
hasLocation(#20001,#20058)
#20059=@"local_type_name;{X};{#20000}"
local_type_names(#20059,"X",#20000)
#20060=@"local_type_name;{Y};{#20000}"
local_type_names(#20060,"Y",#20000)
#20061=@"local_type_name;{Z};{#20000}"
local_type_names(#20061,"Z",#20000)
#20062=*
stmts(#20062,35,#20001,0,"type X = import(3);")
hasLocation(#20062,#20003)
stmt_containers(#20062,#20001)
#20063=*
typeexprs(#20063,1,#20062,0,"X")
hasLocation(#20063,#20011)
enclosing_stmt(#20063,#20062)
expr_containers(#20063,#20001)
literals("X","X",#20063)
typedecl(#20063,#20059)
#20064=*
typeexprs(#20064,30,#20062,1,"import(3)")
#20065=@"loc,{#10000},1,10,1,18"
locations_default(#20065,#10000,1,10,1,18)
hasLocation(#20064,#20065)
enclosing_stmt(#20064,#20062)
expr_containers(#20064,#20001)
#20066=*
typeexprs(#20066,4,#20064,0,"3")
hasLocation(#20066,#20019)
enclosing_stmt(#20066,#20062)
expr_containers(#20066,#20001)
literals("3","3",#20066)
#20067=*
stmts(#20067,35,#20001,1,"type Y ... `Foo`);")
hasLocation(#20067,#20005)
stmt_containers(#20067,#20001)
#20068=*
typeexprs(#20068,1,#20067,0,"Y")
hasLocation(#20068,#20027)
enclosing_stmt(#20068,#20067)
expr_containers(#20068,#20001)
literals("Y","Y",#20068)
typedecl(#20068,#20060)
#20069=*
typeexprs(#20069,30,#20067,1,"import(`Foo`)")
#20070=@"loc,{#10000},2,10,2,22"
locations_default(#20070,#10000,2,10,2,22)
hasLocation(#20069,#20070)
enclosing_stmt(#20069,#20067)
expr_containers(#20069,#20001)
#20071=*
typeexprs(#20071,37,#20069,0,"`Foo`")
hasLocation(#20071,#20035)
enclosing_stmt(#20071,#20067)
expr_containers(#20071,#20001)
#20072=*
typeexprs(#20072,3,#20071,0,"`Foo`")
hasLocation(#20072,#20035)
enclosing_stmt(#20072,#20067)
expr_containers(#20072,#20001)
literals("Foo","Foo",#20072)
#20073=*
stmts(#20073,35,#20001,2,"type Z = import(Y);")
hasLocation(#20073,#20007)
stmt_containers(#20073,#20001)
#20074=*
typeexprs(#20074,1,#20073,0,"Z")
hasLocation(#20074,#20043)
enclosing_stmt(#20074,#20073)
expr_containers(#20074,#20001)
literals("Z","Z",#20074)
typedecl(#20074,#20061)
#20075=*
typeexprs(#20075,30,#20073,1,"import(Y)")
#20076=@"loc,{#10000},3,10,3,18"
locations_default(#20076,#10000,3,10,3,18)
hasLocation(#20075,#20076)
enclosing_stmt(#20075,#20073)
expr_containers(#20075,#20001)
#20077=*
typeexprs(#20077,0,#20075,0,"Y")
hasLocation(#20077,#20051)
enclosing_stmt(#20077,#20073)
expr_containers(#20077,#20001)
literals("Y","Y",#20077)
typebind(#20077,#20060)
#20078=*
entry_cfg_node(#20078,#20001)
#20079=@"loc,{#10000},1,1,1,0"
locations_default(#20079,#10000,1,1,1,0)
hasLocation(#20078,#20079)
#20080=*
exit_cfg_node(#20080,#20001)
hasLocation(#20080,#20057)
successor(#20073,#20080)
successor(#20067,#20073)
successor(#20062,#20067)
successor(#20078,#20062)
numlines(#10000,3,3,0)
filetype(#10000,"typescript")
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
| tst.ts:2:11:2:21 | `foo ${T1}` |
| tst.ts:4:45:4:49 | `foo` |
| tst.ts:4:53:4:57 | `bar` |
| tst.ts:5:46:5:50 | `foo` |
| tst.ts:5:54:5:63 | `bar ${K}` |
| tst.ts:7:15:7:19 | `foo` |
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import javascript

query TemplateLiteralTypeExpr literalType() { any() }
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"include": ["."]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type T1 = 'foo' | 'bar';
type T2 = `foo ${T1}`;

type FooToBar<K extends string> = K extends `foo` ? `bar` : K;
type FooToBar2<K extends string> = K extends `foo` ? `bar ${K}` : K;

type Tuple = [`foo`?];