Skip to content

Commit 770a470

Browse files
authored
Merge pull request #2237 from asger-semmle/typescript3.7-rc
TS: Add support for TypeScript 3.7
2 parents d71fe0b + 57aa166 commit 770a470

54 files changed

Lines changed: 3102 additions & 124 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

change-notes/1.23/analysis-javascript.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
* The call graph has been improved to resolve method calls in more cases. This may produce more security alerts.
1414

15-
* TypeScript 3.6 features are supported.
15+
* TypeScript 3.6 and 3.7 features are now supported.
1616

1717
* Automatic classification of generated files has been improved, in particular files generated by Doxygen are now recognized.
1818

javascript/extractor/lib/typescript/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "typescript-parser-wrapper",
33
"private": true,
44
"dependencies": {
5-
"typescript": "3.6.3"
5+
"typescript": "^3.7.2"
66
},
77
"scripts": {
88
"build": "tsc --project tsconfig.json",

javascript/extractor/lib/typescript/src/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ function checkCycle(root: any) {
126126
function isBlacklistedProperty(k: string) {
127127
return k === "parent" || k === "pos" || k === "end"
128128
|| k === "symbol" || k === "localSymbol"
129-
|| k === "flowNode" || k === "returnFlowNode"
129+
|| k === "flowNode" || k === "returnFlowNode" || k === "endFlowNode"
130130
|| k === "nextContainer" || k === "locals"
131131
|| k === "bindDiagnostics" || k === "bindSuggestionDiagnostics";
132132
}

javascript/extractor/lib/typescript/src/type_table.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ export class TypeTable {
597597
let tupleType = tupleReference.target;
598598
let minLength = tupleType.minLength != null
599599
? tupleType.minLength
600-
: tupleReference.typeArguments.length;
600+
: this.typeChecker.getTypeArguments(tupleReference).length;
601601
let hasRestElement = tupleType.hasRestElement ? 't' : 'f';
602602
let prefix = `tuple;${minLength};${hasRestElement}`;
603603
return this.makeTypeStringVectorFromTypeReferenceArguments(prefix, type);
@@ -714,11 +714,12 @@ export class TypeTable {
714714
// There can be an extra type argument at the end, denoting an explicit 'this' type argument.
715715
// We discard the extra argument in our model.
716716
let target = type.target;
717-
if (type.typeArguments == null) return tag;
717+
let typeArguments = this.typeChecker.getTypeArguments(type);
718+
if (typeArguments == null) return tag;
718719
if (target.typeParameters != null) {
719-
return this.makeTypeStringVector(tag, type.typeArguments, target.typeParameters.length);
720+
return this.makeTypeStringVector(tag, typeArguments, target.typeParameters.length);
720721
} else {
721-
return this.makeTypeStringVector(tag, type.typeArguments);
722+
return this.makeTypeStringVector(tag, typeArguments);
722723
}
723724
}
724725

@@ -992,7 +993,7 @@ export class TypeTable {
992993
* `T` is the type parameter declared on the `Promise` interface.
993994
*/
994995
private getSelfType(type: ts.Type): ts.TypeReference {
995-
if (isTypeReference(type) && type.typeArguments != null && type.typeArguments.length > 0) {
996+
if (isTypeReference(type) && this.typeChecker.getTypeArguments(type).length > 0) {
996997
return type.target;
997998
}
998999
return null;
@@ -1181,8 +1182,9 @@ export class TypeTable {
11811182
if (isTypeReference(type)) {
11821183
// Note that this case also handles tuple types, since a tuple type is represented as
11831184
// a reference to a synthetic generic interface.
1184-
if (type.typeArguments != null) {
1185-
type.typeArguments.forEach(callback);
1185+
let typeArguments = this.typeChecker.getTypeArguments(type);
1186+
if (typeArguments != null) {
1187+
typeArguments.forEach(callback);
11861188
}
11871189
} else if (type.flags & ts.TypeFlags.UnionOrIntersection) {
11881190
(type as ts.UnionOrIntersectionType).types.forEach(callback);

javascript/extractor/lib/typescript/yarn.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,9 @@ tsutils@^2.12.1:
225225
dependencies:
226226
tslib "^1.8.1"
227227

228-
typescript@3.6.3:
229-
version "3.6.3"
230-
resolved "typescript-3.6.3.tgz#fea942fabb20f7e1ca7164ff626f1a9f3f70b4da"
228+
typescript@^3.7.2:
229+
version "3.7.2"
230+
resolved "typescript-3.7.2.tgz"
231231

232232
wrappy@1:
233233
version "1.0.2"

javascript/extractor/src/com/semmle/jcorn/CustomParser.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.semmle.js.ast.BlockStatement;
88
import com.semmle.js.ast.CallExpression;
99
import com.semmle.js.ast.CatchClause;
10+
import com.semmle.js.ast.Chainable;
1011
import com.semmle.js.ast.ClassExpression;
1112
import com.semmle.js.ast.ComprehensionBlock;
1213
import com.semmle.js.ast.ComprehensionExpression;
@@ -470,7 +471,8 @@ protected Pair<Expression, Boolean> parseSubscript(
470471

471472
Expression property = this.parsePropertyIdentifierOrIdentifier();
472473
MemberExpression node =
473-
new MemberExpression(start, base, property, false, false, isOnOptionalChain(false, base));
474+
new MemberExpression(
475+
start, base, property, false, false, Chainable.isOnOptionalChain(false, base));
474476
return Pair.make(this.finishNode(node), true);
475477
} else if (this.eat(doubleDot)) {
476478
SourceLocation start = new SourceLocation(startLoc);

javascript/extractor/src/com/semmle/jcorn/Parser.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,10 +1520,6 @@ protected Expression parseSubscripts(
15201520
}
15211521
}
15221522

1523-
protected boolean isOnOptionalChain(boolean optional, Expression base) {
1524-
return optional || base instanceof Chainable && ((Chainable) base).isOnOptionalChain();
1525-
}
1526-
15271523
/**
15281524
* Parse a single subscript {@code s}; if more subscripts could follow, return {@code Pair.make(s,
15291525
* true}, otherwise return {@code Pair.make(s, false)}.
@@ -1544,7 +1540,7 @@ protected Pair<Expression, Boolean> parseSubscript(
15441540
this.parseExpression(false, null),
15451541
true,
15461542
optional,
1547-
isOnOptionalChain(optional, base));
1543+
Chainable.isOnOptionalChain(optional, base));
15481544
this.expect(TokenType.bracketR);
15491545
return Pair.make(this.finishNode(node), true);
15501546
} else if (!noCalls && this.eat(TokenType.parenL)) {
@@ -1572,10 +1568,10 @@ protected Pair<Expression, Boolean> parseSubscript(
15721568
new ArrayList<>(),
15731569
exprList,
15741570
optional,
1575-
isOnOptionalChain(optional, base));
1571+
Chainable.isOnOptionalChain(optional, base));
15761572
return Pair.make(this.finishNode(node), true);
15771573
} else if (this.type == TokenType.backQuote) {
1578-
if (isOnOptionalChain(optional, base)) {
1574+
if (Chainable.isOnOptionalChain(optional, base)) {
15791575
this.raise(base, "An optional chain may not be used in a tagged template expression.");
15801576
}
15811577
TaggedTemplateExpression node =
@@ -1590,7 +1586,7 @@ protected Pair<Expression, Boolean> parseSubscript(
15901586
this.parseIdent(true),
15911587
false,
15921588
optional,
1593-
isOnOptionalChain(optional, base));
1589+
Chainable.isOnOptionalChain(optional, base));
15941590
return Pair.make(this.finishNode(node), true);
15951591
} else {
15961592
return Pair.make(base, false);
@@ -1832,7 +1828,7 @@ protected Expression parseNew() {
18321828
Expression callee =
18331829
this.parseSubscripts(this.parseExprAtom(null), innerStartPos, innerStartLoc, true);
18341830

1835-
if (isOnOptionalChain(false, callee))
1831+
if (Chainable.isOnOptionalChain(false, callee))
18361832
this.raise(callee, "An optional chain may not be used in a `new` expression.");
18371833

18381834
return parseNewArguments(startLoc, callee);
@@ -2314,7 +2310,7 @@ protected INode toAssignable(INode node, boolean isBinding) {
23142310
}
23152311

23162312
if (node instanceof MemberExpression) {
2317-
if (isOnOptionalChain(false, (MemberExpression) node))
2313+
if (Chainable.isOnOptionalChain(false, (MemberExpression) node))
23182314
this.raise(node, "Invalid left-hand side in assignment");
23192315
if (!isBinding) return node;
23202316
}

javascript/extractor/src/com/semmle/js/ast/Chainable.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,14 @@ public interface Chainable {
77

88
/** Is this on an optional chain? */
99
abstract boolean isOnOptionalChain();
10+
11+
/**
12+
* Returns true if a chainable node is on an optional chain.
13+
*
14+
* @param optional true if the node in question is itself optional (has the ?. token)
15+
* @param base the calle or base of the optional access
16+
*/
17+
public static boolean isOnOptionalChain(boolean optional, Expression base) {
18+
return optional || base instanceof Chainable && ((Chainable) base).isOnOptionalChain();
19+
}
1020
}

javascript/extractor/src/com/semmle/js/ast/DeclarationFlags.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ public class DeclarationFlags {
1717
public static final int protected_ = 1 << 6;
1818
public static final int optional = 1 << 7;
1919
public static final int definiteAssignmentAssertion = 1 << 8;
20+
public static final int declareKeyword = 1 << 9;
2021

2122
public static final int none = 0;
22-
public static final int numberOfFlags = 9;
23+
public static final int numberOfFlags = 10;
2324

2425
public static final List<String> names =
2526
Arrays.asList(
@@ -31,7 +32,8 @@ public class DeclarationFlags {
3132
"private",
3233
"protected",
3334
"optional",
34-
"definiteAssignmentAssertion");
35+
"definiteAssignmentAssertion",
36+
"declare");
3537

3638
public static final List<String> relationNames =
3739
Arrays.asList(
@@ -43,7 +45,8 @@ public class DeclarationFlags {
4345
"hasPrivateKeyword",
4446
"hasProtectedKeyword",
4547
"isOptionalMember",
46-
"hasDefiniteAssignmentAssertion");
48+
"hasDefiniteAssignmentAssertion",
49+
"hasDeclareKeyword");
4750

4851
public static boolean isComputed(int flags) {
4952
return (flags & computed) != 0;
@@ -81,6 +84,10 @@ public static boolean hasDefiniteAssignmentAssertion(int flags) {
8184
return (flags & definiteAssignmentAssertion) != 0;
8285
}
8386

87+
public static boolean hasDeclareKeyword(int flags) {
88+
return (flags & declareKeyword) != 0;
89+
}
90+
8491
/** Returns a mask with the computed bit set to the value of <tt>enable</tt>. */
8592
public static int getComputed(boolean enable) {
8693
return enable ? computed : 0;
@@ -128,6 +135,11 @@ public static int getDefiniteAssignmentAssertion(boolean enable) {
128135
return enable ? definiteAssignmentAssertion : 0;
129136
}
130137

138+
/** Returns a mask with the declare keyword bit set to the value of <tt>enable</tt>. */
139+
public static int getDeclareKeyword(boolean enable) {
140+
return enable ? declareKeyword : 0;
141+
}
142+
131143
/** Returns true if the <tt>n</tt>th bit is set in <tt>flags</tt>. */
132144
public static boolean hasNthFlag(int flags, int n) {
133145
return (flags & (1 << n)) != 0;

javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@
3434
import com.semmle.ts.ast.InterfaceDeclaration;
3535
import com.semmle.ts.ast.InterfaceTypeExpr;
3636
import com.semmle.ts.ast.IntersectionTypeExpr;
37-
import com.semmle.ts.ast.IsTypeExpr;
3837
import com.semmle.ts.ast.KeywordTypeExpr;
3938
import com.semmle.ts.ast.MappedTypeExpr;
4039
import com.semmle.ts.ast.NamespaceDeclaration;
4140
import com.semmle.ts.ast.NonNullAssertion;
4241
import com.semmle.ts.ast.OptionalTypeExpr;
4342
import com.semmle.ts.ast.ParenthesizedTypeExpr;
43+
import com.semmle.ts.ast.PredicateTypeExpr;
4444
import com.semmle.ts.ast.RestTypeExpr;
4545
import com.semmle.ts.ast.TupleTypeExpr;
4646
import com.semmle.ts.ast.TypeAliasDeclaration;
@@ -634,7 +634,7 @@ public R visit(TypeofTypeExpr nd, C c) {
634634
}
635635

636636
@Override
637-
public R visit(IsTypeExpr nd, C c) {
637+
public R visit(PredicateTypeExpr nd, C c) {
638638
return visit((TypeExpression) nd, c);
639639
}
640640

0 commit comments

Comments
 (0)