Merge pull request #4043 from erik-krogh/ts4

JS: Add support for TypeScript 4
This commit is contained in:
Asger F
2020-08-28 14:02:08 +01:00
committed by GitHub
27 changed files with 3313 additions and 15 deletions

View File

@@ -30,7 +30,7 @@
- [yargs](https://www.npmjs.com/package/yargs)
- [webpack-dev-server](https://www.npmjs.com/package/webpack-dev-server)
* TypeScript 3.9 is now supported.
* TypeScript 4.0 is now supported.
* TypeScript code embedded in HTML and Vue files is now extracted and analyzed.

View File

@@ -2,7 +2,7 @@
"name": "typescript-parser-wrapper",
"private": true,
"dependencies": {
"typescript": "3.9.2"
"typescript": "4.0.2"
},
"scripts": {
"build": "tsc --project tsconfig.json",

View File

@@ -225,9 +225,9 @@ tsutils@^2.12.1:
dependencies:
tslib "^1.8.1"
typescript@3.9.2:
version "3.9.2"
resolved typescript-3.9.2.tgz#64e9c8e9be6ea583c54607677dd4680a1cf35db9
typescript@4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.2.tgz#7ea7c88777c723c681e33bf7988be5d008d05ac2"
wrappy@1:
version "1.0.2"

View File

@@ -711,7 +711,7 @@ public class NodeCopier implements Visitor<Void, INode> {
@Override
public INode visit(TupleTypeExpr nd, Void c) {
return new TupleTypeExpr(visit(nd.getLoc()), copy(nd.getElementTypes()));
return new TupleTypeExpr(visit(nd.getLoc()), copy(nd.getElementTypes()), copy(nd.getElementNames()));
}
@Override

View File

@@ -1830,6 +1830,10 @@ public class ASTExtractor {
@Override
public Label visit(TupleTypeExpr nd, Context c) {
Label key = super.visit(nd, c);
if (nd.getElementNames() != null) {
// Element names are index -1, -2, -3...
visitAll(nd.getElementNames(), key, IdContext.typeLabel, -1, -1);
}
visitAll(nd.getElementTypes(), key, IdContext.typeBind, 0);
return key;
}

View File

@@ -1551,8 +1551,27 @@ public class CFGExtractor {
@Override
public Void visit(AssignmentExpression nd, SuccessorInfo i) {
visitAssign(nd, nd.getLeft(), nd.getRight());
succ(nd, i.getGuardedSuccessors(nd));
// `a &&= b` expands to `a || (a = b);`
// The CFG is a conditional assignment, so we go through the assignment `nd` last.
if ("&&=".equals(nd.getOperator()) || "||=".equals(nd.getOperator()) || "??=".equals(nd.getOperator())) {
if ("&&=".equals(nd.getOperator())) {
// from lhs to rhs on truthy. from lhs to false-branch on falsy.
visit(nd.getLeft(), First.of(nd.getRight()), i.getSuccessors(false));
} else if ("||=".equals(nd.getOperator())) {
// from lhs to true-branch on truthy. from lhs to rhs on falsy.
visit(nd.getLeft(), i.getSuccessors(true), First.of(nd.getRight()));
} else { // "??="
// the union of the above - truthyness is unknown.
visit(nd.getLeft(), union(First.of(nd.getRight()), i.getAllSuccessors()), null);
}
visit(nd.getRight(), First.of(nd), null); // from right to assignment.
succ(nd, i.getGuardedSuccessors(nd));
} else {
visitAssign(nd, nd.getLeft(), nd.getRight());
succ(nd, i.getGuardedSuccessors(nd));
}
return null;
}

View File

@@ -79,6 +79,9 @@ public class ExprKinds {
binOpKinds.put("**", 87);
binOpKinds.put("**=", 88);
binOpKinds.put("??", 107);
binOpKinds.put("&&=", 116);
binOpKinds.put("||=", 117);
binOpKinds.put("??=", 118);
}
private static final Map<String, Integer> unOpKinds = new LinkedHashMap<String, Integer>();

View File

@@ -5,6 +5,7 @@ import java.util.Collections;
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;
@@ -586,6 +587,8 @@ public class TypeScriptASTConverter {
return convertTryStatement(node, loc);
case "TupleType":
return convertTupleType(node, loc);
case "NamedTupleMember":
return convertNamedTupleMember(node, loc);
case "TypeAliasDeclaration":
return convertTypeAliasDeclaration(node, loc);
case "TypeAssertionExpression":
@@ -850,6 +853,9 @@ public class TypeScriptASTConverter {
case ">>=":
case "<<=":
case ">>>=":
case "??=":
case "&&=":
case "||=":
return new AssignmentExpression(loc, operator, convertLValue(left), right);
default:
@@ -2178,7 +2184,22 @@ public class TypeScriptASTConverter {
}
private Node convertTupleType(JsonObject node, SourceLocation loc) throws ParseError {
return new TupleTypeExpr(loc, convertChildrenAsTypes(node, "elementTypes"));
List<Identifier> names = new ArrayList<>();
for (JsonElement element : node.get("elements").getAsJsonArray()) {
Identifier id = null;
if (getKind(element).equals("NamedTupleMember")) {
id = (Identifier)convertNode(element.getAsJsonObject().get("name").getAsJsonObject());
}
names.add(id);
}
return new TupleTypeExpr(loc, convertChildrenAsTypes(node, "elements"), names);
}
// This method just does a trivial forward to the type. The names have already been extracted in `convertTupleType`.
private Node convertNamedTupleMember(JsonObject node, SourceLocation loc) throws ParseError {
return convertChild(node, "type");
}
private Node convertTypeAliasDeclaration(JsonObject node, SourceLocation loc) throws ParseError {

View File

@@ -1,5 +1,6 @@
package com.semmle.ts.ast;
import com.semmle.js.ast.Identifier;
import com.semmle.js.ast.SourceLocation;
import com.semmle.js.ast.Visitor;
import java.util.List;
@@ -7,16 +8,22 @@ import java.util.List;
/** A tuple type, such as <tt>[number, string]</tt>. */
public class TupleTypeExpr extends TypeExpression {
private final List<ITypeExpression> elementTypes;
private final List<Identifier> elementNames;
public TupleTypeExpr(SourceLocation loc, List<ITypeExpression> elementTypes) {
public TupleTypeExpr(SourceLocation loc, List<ITypeExpression> elementTypes, List<Identifier> elementNames) {
super("TupleTypeExpr", loc);
this.elementTypes = elementTypes;
this.elementNames = elementNames;
}
public List<ITypeExpression> getElementTypes() {
return elementTypes;
}
public List<Identifier> getElementNames() {
return elementNames;
}
@Override
public <C, R> R accept(Visitor<C, R> v, C c) {
return v.visit(this, c);

View File

@@ -1851,7 +1851,8 @@ class AssignExpr extends @assignexpr, Assignment {
private class TCompoundAssignExpr =
@assignaddexpr or @assignsubexpr or @assignmulexpr or @assigndivexpr or @assignmodexpr or
@assignexpexpr or @assignlshiftexpr or @assignrshiftexpr or @assignurshiftexpr or
@assignorexpr or @assignxorexpr or @assignandexpr;
@assignorexpr or @assignxorexpr or @assignandexpr or @assignlogandexpr or @assignlogorexpr or
@assignnullishcoalescingexpr;
/**
* A compound assign expression.
@@ -1997,6 +1998,39 @@ class AssignXOrExpr extends @assignxorexpr, CompoundAssignExpr { }
*/
class AssignAndExpr extends @assignandexpr, CompoundAssignExpr { }
/**
* A logical-'or'-assign expression.
*
* Example:
*
* ```
* x ||= y
* ```
*/
class AssignLogOrExpr extends @assignlogandexpr, CompoundAssignExpr { }
/**
* A logical-'and'-assign expression.
*
* Example:
*
* ```
* x &&= y
* ```
*/
class AssignLogAndExpr extends @assignlogorexpr, CompoundAssignExpr { }
/**
* A 'nullish-coalescing'-assign expression.
*
* Example:
*
* ```
* x ??= y
* ```
*/
class AssignNullishCoalescingExpr extends @assignnullishcoalescingexpr, CompoundAssignExpr { }
/**
* An update expression, that is, an increment or decrement expression.
*

View File

@@ -856,13 +856,22 @@ class ParenthesizedTypeExpr extends @parenthesizedtypeexpr, TypeExpr {
*/
class TupleTypeExpr extends @tupletypeexpr, TypeExpr {
/** Gets the `n`th element type in the tuple, starting at 0. */
TypeExpr getElementType(int n) { result = getChildTypeExpr(n) }
TypeExpr getElementType(int n) { result = getChildTypeExpr(n) and n >= 0 }
/** Gets any of the element types in the tuple. */
TypeExpr getAnElementType() { result = getElementType(_) }
/** Gets the number of elements in the tuple type. */
int getNumElementType() { result = count(getAnElementType()) }
/**
* Gets the name of the `n`th tuple member, starting at 0.
* Only has a result if the tuple members are named.
*/
Identifier getElementName(int n) {
// Type element names are at indices -1, -2, -3, ...
result = getChild(-(n + 1)) and n >= 0
}
}
/**

View File

@@ -351,6 +351,9 @@ case @expr.kind of
| 113 = @e4x_xml_dynamic_qualident
| 114 = @e4x_xml_dotdotexpr
| 115 = @importmetaexpr
| 116 = @assignlogandexpr
| 117 = @assignlogorexpr
| 118 = @assignnullishcoalescingexpr
;
@varaccess = @proper_varaccess | @export_varaccess;
@@ -372,7 +375,7 @@ case @expr.kind of
@binaryexpr = @comparison | @lshiftexpr | @rshiftexpr | @urshiftexpr | @addexpr | @subexpr | @mulexpr | @divexpr | @modexpr | @expexpr | @bitorexpr | @xorexpr | @bitandexpr | @inexpr | @instanceofexpr | @logandexpr | @logorexpr | @nullishcoalescingexpr;
@assignment = @assignexpr | @assignaddexpr | @assignsubexpr | @assignmulexpr | @assigndivexpr | @assignmodexpr | @assignexpexpr | @assignlshiftexpr | @assignrshiftexpr | @assignurshiftexpr | @assignorexpr | @assignxorexpr | @assignandexpr;
@assignment = @assignexpr | @assignaddexpr | @assignsubexpr | @assignmulexpr | @assigndivexpr | @assignmodexpr | @assignexpexpr | @assignlshiftexpr | @assignrshiftexpr | @assignurshiftexpr | @assignorexpr | @assignxorexpr | @assignandexpr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr;
@updateexpr = @preincexpr | @postincexpr | @predecexpr | @postdecexpr;

View File

@@ -422,6 +422,18 @@
<v>222</v>
</e>
<e>
<k>@assignlogandexpr</k>
<v>1</v>
</e>
<e>
<k>@assignlogorexpr</k>
<v>1</v>
</e>
<e>
<k>@assignnullishcoalescingexpr</k>
<v>1</v>
</e>
<e>
<k>@preincexpr</k>
<v>1792</v>
</e>

View File

@@ -0,0 +1,9 @@
let a = 2;
let b = 3;
a = 23;
a += 19;
a &&= 4;
a ||= 5;
a ??= 6;

View File

@@ -1,4 +1,25 @@
test_getParent
| assignment2.ts:1:5:1:5 | a | assignment2.ts:1:5:1:9 | a = 2 |
| assignment2.ts:1:5:1:9 | a = 2 | assignment2.ts:1:1:1:10 | let a = 2; |
| assignment2.ts:1:9:1:9 | 2 | assignment2.ts:1:5:1:9 | a = 2 |
| assignment2.ts:2:5:2:5 | b | assignment2.ts:2:5:2:9 | b = 3 |
| assignment2.ts:2:5:2:9 | b = 3 | assignment2.ts:2:1:2:10 | let b = 3; |
| assignment2.ts:2:9:2:9 | 3 | assignment2.ts:2:5:2:9 | b = 3 |
| assignment2.ts:4:1:4:1 | a | assignment2.ts:4:1:4:6 | a = 23 |
| assignment2.ts:4:1:4:6 | a = 23 | assignment2.ts:4:1:4:7 | a = 23; |
| assignment2.ts:4:5:4:6 | 23 | assignment2.ts:4:1:4:6 | a = 23 |
| assignment2.ts:5:1:5:1 | a | assignment2.ts:5:1:5:7 | a += 19 |
| assignment2.ts:5:1:5:7 | a += 19 | assignment2.ts:5:1:5:8 | a += 19; |
| assignment2.ts:5:6:5:7 | 19 | assignment2.ts:5:1:5:7 | a += 19 |
| assignment2.ts:7:1:7:1 | a | assignment2.ts:7:1:7:7 | a &&= 4 |
| assignment2.ts:7:1:7:7 | a &&= 4 | assignment2.ts:7:1:7:8 | a &&= 4; |
| assignment2.ts:7:7:7:7 | 4 | assignment2.ts:7:1:7:7 | a &&= 4 |
| assignment2.ts:8:1:8:1 | a | assignment2.ts:8:1:8:7 | a \|\|= 5 |
| assignment2.ts:8:1:8:7 | a \|\|= 5 | assignment2.ts:8:1:8:8 | a \|\|= 5; |
| assignment2.ts:8:7:8:7 | 5 | assignment2.ts:8:1:8:7 | a \|\|= 5 |
| assignment2.ts:9:1:9:1 | a | assignment2.ts:9:1:9:7 | a ??= 6 |
| assignment2.ts:9:1:9:7 | a ??= 6 | assignment2.ts:9:1:9:8 | a ??= 6; |
| assignment2.ts:9:7:9:7 | 6 | assignment2.ts:9:1:9:7 | a ??= 6 |
| assignment.js:1:1:1:1 | a | assignment.js:1:1:1:6 | a = 23 |
| assignment.js:1:1:1:6 | a = 23 | assignment.js:1:1:1:7 | a = 23; |
| assignment.js:1:5:1:6 | 23 | assignment.js:1:1:1:6 | a = 23 |
@@ -468,6 +489,27 @@ test_getParent
| update.js:4:1:4:1 | b | update.js:4:1:4:3 | b-- |
| update.js:4:1:4:3 | b-- | update.js:4:1:4:4 | b--; |
test_getTopLevel
| assignment2.ts:1:5:1:5 | a | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:1:5:1:9 | a = 2 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:1:9:1:9 | 2 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:2:5:2:5 | b | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:2:5:2:9 | b = 3 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:2:9:2:9 | 3 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:4:1:4:1 | a | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:4:1:4:6 | a = 23 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:4:5:4:6 | 23 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:5:1:5:1 | a | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:5:1:5:7 | a += 19 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:5:6:5:7 | 19 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:7:1:7:1 | a | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:7:1:7:7 | a &&= 4 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:7:7:7:7 | 4 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:8:1:8:1 | a | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:8:1:8:7 | a \|\|= 5 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:8:7:8:7 | 5 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:9:1:9:1 | a | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:9:1:9:7 | a ??= 6 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:9:7:9:7 | 6 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment.js:1:1:1:1 | a | assignment.js:1:1:12:7 | <toplevel> |
| assignment.js:1:1:1:6 | a = 23 | assignment.js:1:1:12:7 | <toplevel> |
| assignment.js:1:5:1:6 | 23 | assignment.js:1:1:12:7 | <toplevel> |
@@ -937,6 +979,20 @@ test_getTopLevel
| update.js:4:1:4:1 | b | update.js:1:1:5:0 | <toplevel> |
| update.js:4:1:4:3 | b-- | update.js:1:1:5:0 | <toplevel> |
test_getChild
| assignment2.ts:1:5:1:9 | a = 2 | 0 | assignment2.ts:1:5:1:5 | a |
| assignment2.ts:1:5:1:9 | a = 2 | 1 | assignment2.ts:1:9:1:9 | 2 |
| assignment2.ts:2:5:2:9 | b = 3 | 0 | assignment2.ts:2:5:2:5 | b |
| assignment2.ts:2:5:2:9 | b = 3 | 1 | assignment2.ts:2:9:2:9 | 3 |
| assignment2.ts:4:1:4:6 | a = 23 | 0 | assignment2.ts:4:1:4:1 | a |
| assignment2.ts:4:1:4:6 | a = 23 | 1 | assignment2.ts:4:5:4:6 | 23 |
| assignment2.ts:5:1:5:7 | a += 19 | 0 | assignment2.ts:5:1:5:1 | a |
| assignment2.ts:5:1:5:7 | a += 19 | 1 | assignment2.ts:5:6:5:7 | 19 |
| assignment2.ts:7:1:7:7 | a &&= 4 | 0 | assignment2.ts:7:1:7:1 | a |
| assignment2.ts:7:1:7:7 | a &&= 4 | 1 | assignment2.ts:7:7:7:7 | 4 |
| assignment2.ts:8:1:8:7 | a \|\|= 5 | 0 | assignment2.ts:8:1:8:1 | a |
| assignment2.ts:8:1:8:7 | a \|\|= 5 | 1 | assignment2.ts:8:7:8:7 | 5 |
| assignment2.ts:9:1:9:7 | a ??= 6 | 0 | assignment2.ts:9:1:9:1 | a |
| assignment2.ts:9:1:9:7 | a ??= 6 | 1 | assignment2.ts:9:7:9:7 | 6 |
| assignment.js:1:1:1:6 | a = 23 | 0 | assignment.js:1:1:1:1 | a |
| assignment.js:1:1:1:6 | a = 23 | 1 | assignment.js:1:5:1:6 | 23 |
| assignment.js:2:1:2:7 | a += 19 | 0 | assignment.js:2:1:2:1 | a |
@@ -1213,6 +1269,20 @@ test_getChild
| update.js:3:1:3:3 | --b | 0 | update.js:3:3:3:3 | b |
| update.js:4:1:4:3 | b-- | 0 | update.js:4:1:4:1 | b |
test_isPure
| assignment2.ts:1:5:1:5 | a |
| assignment2.ts:1:9:1:9 | 2 |
| assignment2.ts:2:5:2:5 | b |
| assignment2.ts:2:9:2:9 | 3 |
| assignment2.ts:4:1:4:1 | a |
| assignment2.ts:4:5:4:6 | 23 |
| assignment2.ts:5:1:5:1 | a |
| assignment2.ts:5:6:5:7 | 19 |
| assignment2.ts:7:1:7:1 | a |
| assignment2.ts:7:7:7:7 | 4 |
| assignment2.ts:8:1:8:1 | a |
| assignment2.ts:8:7:8:7 | 5 |
| assignment2.ts:9:1:9:1 | a |
| assignment2.ts:9:7:9:7 | 6 |
| assignment.js:1:1:1:1 | a |
| assignment.js:1:5:1:6 | 23 |
| assignment.js:2:1:2:1 | a |
@@ -1708,6 +1778,27 @@ test_stripParens
| primaries.js:28:2:28:5 | (42) | primaries.js:28:3:28:4 | 42 |
| unary.js:6:5:6:7 | (0) | unary.js:6:6:6:6 | 0 |
test_getContainer
| assignment2.ts:1:5:1:5 | a | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:1:5:1:9 | a = 2 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:1:9:1:9 | 2 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:2:5:2:5 | b | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:2:5:2:9 | b = 3 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:2:9:2:9 | 3 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:4:1:4:1 | a | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:4:1:4:6 | a = 23 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:4:5:4:6 | 23 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:5:1:5:1 | a | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:5:1:5:7 | a += 19 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:5:6:5:7 | 19 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:7:1:7:1 | a | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:7:1:7:7 | a &&= 4 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:7:7:7:7 | 4 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:8:1:8:1 | a | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:8:1:8:7 | a \|\|= 5 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:8:7:8:7 | 5 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:9:1:9:1 | a | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:9:1:9:7 | a ??= 6 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment2.ts:9:7:9:7 | 6 | assignment2.ts:1:1:9:8 | <toplevel> |
| assignment.js:1:1:1:1 | a | assignment.js:1:1:12:7 | <toplevel> |
| assignment.js:1:1:1:6 | a = 23 | assignment.js:1:1:12:7 | <toplevel> |
| assignment.js:1:5:1:6 | 23 | assignment.js:1:1:12:7 | <toplevel> |
@@ -2177,6 +2268,27 @@ test_getContainer
| update.js:4:1:4:1 | b | update.js:1:1:5:0 | <toplevel> |
| update.js:4:1:4:3 | b-- | update.js:1:1:5:0 | <toplevel> |
test_getEnclosingStmt
| assignment2.ts:1:5:1:5 | a | assignment2.ts:1:1:1:10 | let a = 2; |
| assignment2.ts:1:5:1:9 | a = 2 | assignment2.ts:1:1:1:10 | let a = 2; |
| assignment2.ts:1:9:1:9 | 2 | assignment2.ts:1:1:1:10 | let a = 2; |
| assignment2.ts:2:5:2:5 | b | assignment2.ts:2:1:2:10 | let b = 3; |
| assignment2.ts:2:5:2:9 | b = 3 | assignment2.ts:2:1:2:10 | let b = 3; |
| assignment2.ts:2:9:2:9 | 3 | assignment2.ts:2:1:2:10 | let b = 3; |
| assignment2.ts:4:1:4:1 | a | assignment2.ts:4:1:4:7 | a = 23; |
| assignment2.ts:4:1:4:6 | a = 23 | assignment2.ts:4:1:4:7 | a = 23; |
| assignment2.ts:4:5:4:6 | 23 | assignment2.ts:4:1:4:7 | a = 23; |
| assignment2.ts:5:1:5:1 | a | assignment2.ts:5:1:5:8 | a += 19; |
| assignment2.ts:5:1:5:7 | a += 19 | assignment2.ts:5:1:5:8 | a += 19; |
| assignment2.ts:5:6:5:7 | 19 | assignment2.ts:5:1:5:8 | a += 19; |
| assignment2.ts:7:1:7:1 | a | assignment2.ts:7:1:7:8 | a &&= 4; |
| assignment2.ts:7:1:7:7 | a &&= 4 | assignment2.ts:7:1:7:8 | a &&= 4; |
| assignment2.ts:7:7:7:7 | 4 | assignment2.ts:7:1:7:8 | a &&= 4; |
| assignment2.ts:8:1:8:1 | a | assignment2.ts:8:1:8:8 | a \|\|= 5; |
| assignment2.ts:8:1:8:7 | a \|\|= 5 | assignment2.ts:8:1:8:8 | a \|\|= 5; |
| assignment2.ts:8:7:8:7 | 5 | assignment2.ts:8:1:8:8 | a \|\|= 5; |
| assignment2.ts:9:1:9:1 | a | assignment2.ts:9:1:9:8 | a ??= 6; |
| assignment2.ts:9:1:9:7 | a ??= 6 | assignment2.ts:9:1:9:8 | a ??= 6; |
| assignment2.ts:9:7:9:7 | 6 | assignment2.ts:9:1:9:8 | a ??= 6; |
| assignment.js:1:1:1:1 | a | assignment.js:1:1:1:7 | a = 23; |
| assignment.js:1:1:1:6 | a = 23 | assignment.js:1:1:1:7 | a = 23; |
| assignment.js:1:5:1:6 | 23 | assignment.js:1:1:1:7 | a = 23; |
@@ -2612,6 +2724,14 @@ test_getEnclosingStmt
| update.js:4:1:4:1 | b | update.js:4:1:4:4 | b--; |
| update.js:4:1:4:3 | b-- | update.js:4:1:4:4 | b--; |
test_inNullSensitiveContext
| assignment2.ts:5:1:5:1 | a |
| assignment2.ts:5:6:5:7 | 19 |
| assignment2.ts:7:1:7:1 | a |
| assignment2.ts:7:7:7:7 | 4 |
| assignment2.ts:8:1:8:1 | a |
| assignment2.ts:8:7:8:7 | 5 |
| assignment2.ts:9:1:9:1 | a |
| assignment2.ts:9:7:9:7 | 6 |
| assignment.js:2:1:2:1 | a |
| assignment.js:2:6:2:7 | 19 |
| assignment.js:3:1:3:1 | a |

View File

@@ -3,3 +3,7 @@ import javascript
query predicate test_TupleTypeExpr(TupleTypeExpr type, int n, int res0, TypeExpr res1) {
res0 = type.getNumElementType() and res1 = type.getElementType(n)
}
query predicate test_TupleTypeElementName(TupleTypeExpr type, int n, Identifier name) {
name = type.getElementName(n)
}

View File

@@ -108,6 +108,15 @@ test_VariableTypes
| tst.ts:142:17:142:25 | condition | condition | tst.ts:142:28:142:30 | any |
| tst.ts:142:33:142:35 | msg | msg | tst.ts:142:39:142:44 | string |
| tst.ts:148:25:148:27 | val | val | tst.ts:148:30:148:32 | any |
| tst.ts:157:32:157:34 | arr | arr | tst.ts:157:37:157:56 | readonly [any, ...T] |
| tst.ts:164:47:164:50 | arr1 | arr1 | tst.ts:164:53:164:53 | T |
| tst.ts:164:56:164:59 | arr2 | arr2 | tst.ts:164:62:164:62 | U |
| tst.ts:169:31:169:31 | x | x | tst.ts:169:34:169:64 | [first: ... number] |
| tst.ts:180:5:180:7 | foo | foo | tst.ts:180:10:180:21 | StrStrNumNum |
| tst.ts:184:7:184:8 | a1 | a1 | tst.ts:184:12:184:17 | number |
| tst.ts:185:7:185:8 | a2 | a2 | tst.ts:185:12:185:17 | number |
| tst.ts:186:7:186:8 | a3 | a3 | tst.ts:186:12:186:17 | number |
| tst.ts:192:18:192:18 | x | x | tst.ts:192:21:192:43 | [first: ... number] |
test_QualifiedTypeAccess
| tst.ts:63:19:63:21 | N.I | tst.ts:63:19:63:19 | N | tst.ts:63:21:63:21 | I |
| tst.ts:64:20:64:24 | N.M.I | tst.ts:64:20:64:22 | N.M | tst.ts:64:24:64:24 | I |
@@ -198,6 +207,27 @@ test_TupleTypeExpr
| tst.ts:136:39:136:68 | [number ... mber[]] | 0 | 3 | tst.ts:136:40:136:45 | number |
| tst.ts:136:39:136:68 | [number ... mber[]] | 1 | 3 | tst.ts:136:48:136:54 | string? |
| tst.ts:136:39:136:68 | [number ... mber[]] | 2 | 3 | tst.ts:136:57:136:67 | ...number[] |
| tst.ts:157:46:157:56 | [any, ...T] | 0 | 2 | tst.ts:157:47:157:49 | any |
| tst.ts:157:46:157:56 | [any, ...T] | 1 | 2 | tst.ts:157:52:157:55 | ...T |
| tst.ts:164:66:164:77 | [...T, ...U] | 0 | 2 | tst.ts:164:67:164:70 | ...T |
| tst.ts:164:66:164:77 | [...T, ...U] | 1 | 2 | tst.ts:164:73:164:76 | ...U |
| tst.ts:169:34:169:64 | [first: ... number] | 0 | 2 | tst.ts:169:42:169:47 | number |
| tst.ts:169:34:169:64 | [first: ... number] | 1 | 2 | tst.ts:169:58:169:63 | number |
| tst.ts:175:16:175:31 | [string, string] | 0 | 2 | tst.ts:175:17:175:22 | string |
| tst.ts:175:16:175:31 | [string, string] | 1 | 2 | tst.ts:175:25:175:30 | string |
| tst.ts:176:16:176:31 | [number, number] | 0 | 2 | tst.ts:176:17:176:22 | number |
| tst.ts:176:16:176:31 | [number, number] | 1 | 2 | tst.ts:176:25:176:30 | number |
| tst.ts:179:21:179:44 | [...Str ... umbers] | 0 | 2 | tst.ts:179:22:179:31 | ...Strings |
| tst.ts:179:21:179:44 | [...Str ... umbers] | 1 | 2 | tst.ts:179:34:179:43 | ...Numbers |
| tst.ts:192:21:192:43 | [first: ... number] | 0 | 2 | tst.ts:192:29:192:34 | number |
| tst.ts:192:21:192:43 | [first: ... number] | 1 | 2 | tst.ts:192:37:192:42 | number |
| tst.ts:192:47:192:70 | [number ... number] | 0 | 2 | tst.ts:192:48:192:53 | number |
| tst.ts:192:47:192:70 | [number ... number] | 1 | 2 | tst.ts:192:64:192:69 | number |
test_TupleTypeElementName
| tst.ts:169:34:169:64 | [first: ... number] | 0 | tst.ts:169:35:169:39 | first |
| tst.ts:169:34:169:64 | [first: ... number] | 1 | tst.ts:169:50:169:55 | second |
| tst.ts:192:21:192:43 | [first: ... number] | 0 | tst.ts:192:22:192:26 | first |
| tst.ts:192:47:192:70 | [number ... number] | 1 | tst.ts:192:56:192:61 | second |
test_FieldTypes
| tst.ts:15:3:15:22 | numberField: number; | tst.ts:15:16:15:21 | number |
| tst.ts:16:3:16:22 | stringField: string; | tst.ts:16:16:16:21 | string |
@@ -219,6 +249,8 @@ test_ArrayTypeExpr
| tst.ts:81:27:81:34 | string[] | tst.ts:81:27:81:32 | string |
| tst.ts:135:39:135:46 | string[] | tst.ts:135:39:135:44 | string |
| tst.ts:136:60:136:67 | number[] | tst.ts:136:60:136:65 | number |
| tst.ts:157:25:157:29 | any[] | tst.ts:157:25:157:27 | any |
| tst.ts:163:21:163:25 | any[] | tst.ts:163:21:163:23 | any |
test_TypeAccessHelpers
| tst.ts:65:18:65:24 | Generic | 1 | 0 | tst.ts:65:26:65:31 | number |
| tst.ts:66:18:66:32 | N.InnerGeneric1 | 1 | 0 | tst.ts:66:34:66:39 | number |
@@ -270,6 +302,9 @@ test_ReturnTypes
| tst.ts:96:1:96:52 | functio ... rn x; } | function f3 | tst.ts:96:38:96:38 | S |
| tst.ts:142:1:146:1 | functio ... )\\n }\\n} | function assert | tst.ts:142:48:142:64 | asserts condition |
| tst.ts:148:1:152:1 | functio ... ;\\n }\\n} | function assertIsString | tst.ts:148:36:148:56 | asserts ... string |
| tst.ts:164:1:166:1 | functio ... rr2];\\n} | function concat | tst.ts:164:66:164:77 | [...T, ...U] |
| tst.ts:169:1:172:1 | functio ... + b;\\n} | function labelOnTupleElements | tst.ts:169:68:169:73 | number |
| tst.ts:192:1:194:1 | functio ... rn x;\\n} | function weirdId | tst.ts:192:47:192:70 | [number ... number] |
test_KeyofTypeExpr
| tst.ts:49:16:49:30 | keyof Interface | tst.ts:49:22:49:30 | Interface |
| tst.ts:113:26:113:35 | keyof Node | tst.ts:113:32:113:35 | Node |

View File

@@ -150,3 +150,45 @@ function assertIsString(val: any): asserts val is string {
throw new AssertionError("Not a string!");
}
}
// TypeScript 4.0
// spreads in tuple type syntax can now be generic
function tail<T extends any[]>(arr: readonly [any, ...T]) {
const [_ignored, ...rest] = arr;
return rest;
}
// spread in tuple in non-last position
type Arr = readonly any[];
function concat<T extends Arr, U extends Arr>(arr1: T, arr2: U): [...T, ...U] {
return [...arr1, ...arr2];
}
// labelled tuple elements
function labelOnTupleElements(x: [first: number, second: number]): number {
let [a, b] = x;
return a + b;
}
// spread elements can occur anywhere in a tuple not just at the end!
type Strings = [string, string];
type Numbers = [number, number];
// [string, string, number, number]
type StrStrNumNum = [...Strings, ...Numbers];
var foo: StrStrNumNum;
// Short-Circuiting Assignment Operators
function shortAssignment() {
let a1 : number = parseInt("foo");
let a2 : number = parseInt("bar");
let a3 : number = a1 ||= a2;
let a4 = a2 &&= a3;
let a5 = a3 ??= a4;
}
// only label on some tuple elements (is a type-error)
function weirdId(x: [first: number, number]): [number, second: number] {
return x;
}

View File

@@ -67,12 +67,10 @@
| tst.ts:26:15:26:24 | () => void | () => void |
| tst.ts:27:5:27:17 | undefinedType | undefined |
| tst.ts:28:5:28:12 | nullType | null |
| tst.ts:28:22:28:25 | null | null |
| tst.ts:29:5:29:13 | neverType | () => never |
| tst.ts:29:16:29:26 | () => never | () => never |
| tst.ts:30:5:30:14 | symbolType | symbol |
| tst.ts:31:7:31:22 | uniqueSymbolType | typeof uniqueSymbolType |
| tst.ts:31:41:31:44 | null | null |
| tst.ts:32:5:32:14 | objectType | object |
| tst.ts:33:5:33:16 | intersection | string & { x: string; } |
| tst.ts:33:29:33:29 | x | string |
@@ -92,6 +90,13 @@
| tst.ts:43:26:43:48 | { foo: ... s const | { readonly foo: "foo"; } |
| tst.ts:43:28:43:30 | foo | "foo" |
| tst.ts:43:33:43:37 | "foo" | "foo" |
| tst.ts:47:8:47:8 | e | unknown |
| tst.ts:48:7:48:14 | typeof e | "string" \| "number" \| "bigint" \| "boolean" \| "s... |
| tst.ts:48:7:48:27 | typeof ... string" | boolean |
| tst.ts:48:14:48:14 | e | unknown |
| tst.ts:48:20:48:27 | "string" | "string" |
| tst.ts:49:11:49:11 | b | string |
| tst.ts:49:24:49:24 | e | string |
| type_alias.ts:3:5:3:5 | b | boolean |
| type_alias.ts:7:5:7:5 | c | ValueOrArray<number> |
| type_alias.ts:14:9:14:32 | [proper ... ]: Json | any |

View File

@@ -68,6 +68,7 @@
| tst.ts:39:60:39:65 | number | number |
| tst.ts:39:60:39:67 | number[] | number[] |
| tst.ts:40:18:40:24 | unknown | unknown |
| tst.ts:49:15:49:20 | string | string |
| type_alias.ts:1:6:1:6 | B | boolean |
| type_alias.ts:1:10:1:16 | boolean | boolean |
| type_alias.ts:3:8:3:8 | B | boolean |

View File

@@ -1 +1,3 @@
| tst.ts:40:5:40:15 | unknownType | unknown |
| tst.ts:47:8:47:8 | e | unknown |
| tst.ts:48:14:48:14 | e | unknown |

View File

@@ -41,3 +41,11 @@ let unknownType: unknown;
let constArrayLiteral = [1, 2] as const;
let constObjectLiteral = { foo: "foo" } as const;
try { }
catch (e: unknown) {
if (typeof e === "string") {
let b : string = e;
}
}

View File

@@ -3048,6 +3048,239 @@ nodes
| torrents.js:7:25:7:27 | loc |
| torrents.js:7:25:7:27 | loc |
| torrents.js:7:25:7:27 | loc |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:24:9:30 | req.url |
| typescript.ts:9:24:9:30 | req.url |
| typescript.ts:9:24:9:30 | req.url |
| typescript.ts:9:24:9:30 | req.url |
| typescript.ts:9:24:9:30 | req.url |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:12:29:12:32 | path |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:20:15:20:18 | path |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:21:39:21:43 | path3 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:23:15:23:18 | path |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:24:39:24:43 | path4 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:30:15:30:18 | path |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| typescript.ts:32:29:32:33 | path6 |
| views.js:1:43:1:55 | req.params[0] |
| views.js:1:43:1:55 | req.params[0] |
| views.js:1:43:1:55 | req.params[0] |
@@ -7362,6 +7595,310 @@ edges
| torrents.js:6:24:6:27 | name | torrents.js:6:12:6:45 | dir + " ... t.data" |
| torrents.js:6:24:6:27 | name | torrents.js:6:12:6:45 | dir + " ... t.data" |
| torrents.js:6:24:6:27 | name | torrents.js:6:12:6:45 | dir + " ... t.data" |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:12:29:12:32 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:20:15:20:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:23:15:23:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:7:9:48 | path | typescript.ts:30:15:30:18 | path |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:37 | url.par ... , true) | typescript.ts:9:14:9:43 | url.par ... ).query |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:43 | url.par ... ).query | typescript.ts:9:14:9:48 | url.par ... ry.path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:14:9:48 | url.par ... ry.path | typescript.ts:9:7:9:48 | path |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:9:24:9:30 | req.url | typescript.ts:9:14:9:37 | url.par ... , true) |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:7:20:18 | path3 | typescript.ts:21:39:21:43 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:20:15:20:18 | path | typescript.ts:20:7:20:18 | path3 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:7:23:18 | path4 | typescript.ts:24:39:24:43 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:23:15:23:18 | path | typescript.ts:23:7:23:18 | path4 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:7:30:18 | path6 | typescript.ts:32:29:32:33 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| typescript.ts:30:15:30:18 | path | typescript.ts:30:7:30:18 | path6 |
| views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] |
#select
| TaintedPath-es6.js:10:26:10:45 | join("public", path) | TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:10:26:10:45 | join("public", path) | This path depends on $@. | TaintedPath-es6.js:7:20:7:26 | req.url | a user-provided value |
@@ -7497,4 +8034,8 @@ edges
| tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:26:18:26:45 | path.sp ... hatever | This path depends on $@. | tainted-string-steps.js:6:24:6:30 | req.url | a user-provided value |
| tainted-string-steps.js:27:18:27:36 | path.split(unknown) | tainted-string-steps.js:6:24:6:30 | req.url | tainted-string-steps.js:27:18:27:36 | path.split(unknown) | This path depends on $@. | tainted-string-steps.js:6:24:6:30 | req.url | a user-provided value |
| torrents.js:7:25:7:27 | loc | torrents.js:5:13:5:38 | parseTo ... t).name | torrents.js:7:25:7:27 | loc | This path depends on $@. | torrents.js:5:13:5:38 | parseTo ... t).name | a user-provided value |
| typescript.ts:12:29:12:32 | path | typescript.ts:9:24:9:30 | req.url | typescript.ts:12:29:12:32 | path | This path depends on $@. | typescript.ts:9:24:9:30 | req.url | a user-provided value |
| typescript.ts:21:39:21:43 | path3 | typescript.ts:9:24:9:30 | req.url | typescript.ts:21:39:21:43 | path3 | This path depends on $@. | typescript.ts:9:24:9:30 | req.url | a user-provided value |
| typescript.ts:24:39:24:43 | path4 | typescript.ts:9:24:9:30 | req.url | typescript.ts:24:39:24:43 | path4 | This path depends on $@. | typescript.ts:9:24:9:30 | req.url | a user-provided value |
| typescript.ts:32:29:32:33 | path6 | typescript.ts:9:24:9:30 | req.url | typescript.ts:32:29:32:33 | path6 | This path depends on $@. | typescript.ts:9:24:9:30 | req.url | a user-provided value |
| views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | This path depends on $@. | views.js:1:43:1:55 | req.params[0] | a user-provided value |

View File

@@ -0,0 +1,34 @@
var fs = require('fs'),
http = require('http'),
url = require('url'),
sanitize = require('sanitize-filename'),
pathModule = require('path')
;
var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
// BAD: This could read any file on the file system
res.write(fs.readFileSync(path));
if (path === 'foo.txt')
res.write(fs.readFileSync(path)); // GOOD: Path is compared to white-list
let path2 = path;
path2 ||= res.write(fs.readFileSync(path2)); // GOOD: path is falsy
let path3 = path;
path3 &&= res.write(fs.readFileSync(path3)); // BAD: path is truthy
let path4 = path;
path4 ??= res.write(fs.readFileSync(path4)); // GOOD - path is null or undefined - but we don't capture that. [INCONSISTENCY]
let path5 = path;
path5 &&= "clean";
res.write(fs.readFileSync(path5)); // GOOD: path is either falsy or "clean";
let path6 = path;
path6 ||= "clean";
res.write(fs.readFileSync(path6)); // BAD: path can still be tainted
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: add support for TypeScript 4.0
compatibility: backwards