Merge pull request #2237 from asger-semmle/typescript3.7-rc

TS: Add support for TypeScript 3.7
This commit is contained in:
Max Schaefer 2019-11-04 16:36:11 +00:00 коммит произвёл GitHub
Родитель d71fe0bffd 57aa166bff
Коммит 770a4703c9
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
54 изменённых файлов: 3102 добавлений и 124 удалений

Просмотреть файл

@ -12,7 +12,7 @@
* The call graph has been improved to resolve method calls in more cases. This may produce more security alerts.
* TypeScript 3.6 features are supported.
* TypeScript 3.6 and 3.7 features are now supported.
* Automatic classification of generated files has been improved, in particular files generated by Doxygen are now recognized.

Просмотреть файл

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

Просмотреть файл

@ -126,7 +126,7 @@ function checkCycle(root: any) {
function isBlacklistedProperty(k: string) {
return k === "parent" || k === "pos" || k === "end"
|| k === "symbol" || k === "localSymbol"
|| k === "flowNode" || k === "returnFlowNode"
|| k === "flowNode" || k === "returnFlowNode" || k === "endFlowNode"
|| k === "nextContainer" || k === "locals"
|| k === "bindDiagnostics" || k === "bindSuggestionDiagnostics";
}

Просмотреть файл

@ -597,7 +597,7 @@ export class TypeTable {
let tupleType = tupleReference.target;
let minLength = tupleType.minLength != null
? tupleType.minLength
: tupleReference.typeArguments.length;
: this.typeChecker.getTypeArguments(tupleReference).length;
let hasRestElement = tupleType.hasRestElement ? 't' : 'f';
let prefix = `tuple;${minLength};${hasRestElement}`;
return this.makeTypeStringVectorFromTypeReferenceArguments(prefix, type);
@ -714,11 +714,12 @@ export class TypeTable {
// There can be an extra type argument at the end, denoting an explicit 'this' type argument.
// We discard the extra argument in our model.
let target = type.target;
if (type.typeArguments == null) return tag;
let typeArguments = this.typeChecker.getTypeArguments(type);
if (typeArguments == null) return tag;
if (target.typeParameters != null) {
return this.makeTypeStringVector(tag, type.typeArguments, target.typeParameters.length);
return this.makeTypeStringVector(tag, typeArguments, target.typeParameters.length);
} else {
return this.makeTypeStringVector(tag, type.typeArguments);
return this.makeTypeStringVector(tag, typeArguments);
}
}
@ -992,7 +993,7 @@ export class TypeTable {
* `T` is the type parameter declared on the `Promise` interface.
*/
private getSelfType(type: ts.Type): ts.TypeReference {
if (isTypeReference(type) && type.typeArguments != null && type.typeArguments.length > 0) {
if (isTypeReference(type) && this.typeChecker.getTypeArguments(type).length > 0) {
return type.target;
}
return null;
@ -1181,8 +1182,9 @@ export class TypeTable {
if (isTypeReference(type)) {
// Note that this case also handles tuple types, since a tuple type is represented as
// a reference to a synthetic generic interface.
if (type.typeArguments != null) {
type.typeArguments.forEach(callback);
let typeArguments = this.typeChecker.getTypeArguments(type);
if (typeArguments != null) {
typeArguments.forEach(callback);
}
} else if (type.flags & ts.TypeFlags.UnionOrIntersection) {
(type as ts.UnionOrIntersectionType).types.forEach(callback);

Просмотреть файл

@ -225,9 +225,9 @@ tsutils@^2.12.1:
dependencies:
tslib "^1.8.1"
typescript@3.6.3:
version "3.6.3"
resolved "typescript-3.6.3.tgz#fea942fabb20f7e1ca7164ff626f1a9f3f70b4da"
typescript@^3.7.2:
version "3.7.2"
resolved "typescript-3.7.2.tgz"
wrappy@1:
version "1.0.2"

Просмотреть файл

@ -7,6 +7,7 @@ import com.semmle.js.ast.AssignmentExpression;
import com.semmle.js.ast.BlockStatement;
import com.semmle.js.ast.CallExpression;
import com.semmle.js.ast.CatchClause;
import com.semmle.js.ast.Chainable;
import com.semmle.js.ast.ClassExpression;
import com.semmle.js.ast.ComprehensionBlock;
import com.semmle.js.ast.ComprehensionExpression;
@ -470,7 +471,8 @@ public class CustomParser extends FlowParser {
Expression property = this.parsePropertyIdentifierOrIdentifier();
MemberExpression node =
new MemberExpression(start, base, property, false, false, isOnOptionalChain(false, base));
new MemberExpression(
start, base, property, false, false, Chainable.isOnOptionalChain(false, base));
return Pair.make(this.finishNode(node), true);
} else if (this.eat(doubleDot)) {
SourceLocation start = new SourceLocation(startLoc);

Просмотреть файл

@ -1520,10 +1520,6 @@ public class Parser {
}
}
protected boolean isOnOptionalChain(boolean optional, Expression base) {
return optional || base instanceof Chainable && ((Chainable) base).isOnOptionalChain();
}
/**
* Parse a single subscript {@code s}; if more subscripts could follow, return {@code Pair.make(s,
* true}, otherwise return {@code Pair.make(s, false)}.
@ -1544,7 +1540,7 @@ public class Parser {
this.parseExpression(false, null),
true,
optional,
isOnOptionalChain(optional, base));
Chainable.isOnOptionalChain(optional, base));
this.expect(TokenType.bracketR);
return Pair.make(this.finishNode(node), true);
} else if (!noCalls && this.eat(TokenType.parenL)) {
@ -1572,10 +1568,10 @@ public class Parser {
new ArrayList<>(),
exprList,
optional,
isOnOptionalChain(optional, base));
Chainable.isOnOptionalChain(optional, base));
return Pair.make(this.finishNode(node), true);
} else if (this.type == TokenType.backQuote) {
if (isOnOptionalChain(optional, base)) {
if (Chainable.isOnOptionalChain(optional, base)) {
this.raise(base, "An optional chain may not be used in a tagged template expression.");
}
TaggedTemplateExpression node =
@ -1590,7 +1586,7 @@ public class Parser {
this.parseIdent(true),
false,
optional,
isOnOptionalChain(optional, base));
Chainable.isOnOptionalChain(optional, base));
return Pair.make(this.finishNode(node), true);
} else {
return Pair.make(base, false);
@ -1832,7 +1828,7 @@ public class Parser {
Expression callee =
this.parseSubscripts(this.parseExprAtom(null), innerStartPos, innerStartLoc, true);
if (isOnOptionalChain(false, callee))
if (Chainable.isOnOptionalChain(false, callee))
this.raise(callee, "An optional chain may not be used in a `new` expression.");
return parseNewArguments(startLoc, callee);
@ -2314,7 +2310,7 @@ public class Parser {
}
if (node instanceof MemberExpression) {
if (isOnOptionalChain(false, (MemberExpression) node))
if (Chainable.isOnOptionalChain(false, (MemberExpression) node))
this.raise(node, "Invalid left-hand side in assignment");
if (!isBinding) return node;
}

Просмотреть файл

@ -7,4 +7,14 @@ public interface Chainable {
/** Is this on an optional chain? */
abstract boolean isOnOptionalChain();
/**
* Returns true if a chainable node is on an optional chain.
*
* @param optional true if the node in question is itself optional (has the ?. token)
* @param base the calle or base of the optional access
*/
public static boolean isOnOptionalChain(boolean optional, Expression base) {
return optional || base instanceof Chainable && ((Chainable) base).isOnOptionalChain();
}
}

Просмотреть файл

@ -17,9 +17,10 @@ public class DeclarationFlags {
public static final int protected_ = 1 << 6;
public static final int optional = 1 << 7;
public static final int definiteAssignmentAssertion = 1 << 8;
public static final int declareKeyword = 1 << 9;
public static final int none = 0;
public static final int numberOfFlags = 9;
public static final int numberOfFlags = 10;
public static final List<String> names =
Arrays.asList(
@ -31,7 +32,8 @@ public class DeclarationFlags {
"private",
"protected",
"optional",
"definiteAssignmentAssertion");
"definiteAssignmentAssertion",
"declare");
public static final List<String> relationNames =
Arrays.asList(
@ -43,7 +45,8 @@ public class DeclarationFlags {
"hasPrivateKeyword",
"hasProtectedKeyword",
"isOptionalMember",
"hasDefiniteAssignmentAssertion");
"hasDefiniteAssignmentAssertion",
"hasDeclareKeyword");
public static boolean isComputed(int flags) {
return (flags & computed) != 0;
@ -81,6 +84,10 @@ public class DeclarationFlags {
return (flags & definiteAssignmentAssertion) != 0;
}
public static boolean hasDeclareKeyword(int flags) {
return (flags & declareKeyword) != 0;
}
/** Returns a mask with the computed bit set to the value of <tt>enable</tt>. */
public static int getComputed(boolean enable) {
return enable ? computed : 0;
@ -128,6 +135,11 @@ public class DeclarationFlags {
return enable ? definiteAssignmentAssertion : 0;
}
/** Returns a mask with the declare keyword bit set to the value of <tt>enable</tt>. */
public static int getDeclareKeyword(boolean enable) {
return enable ? declareKeyword : 0;
}
/** Returns true if the <tt>n</tt>th bit is set in <tt>flags</tt>. */
public static boolean hasNthFlag(int flags, int n) {
return (flags & (1 << n)) != 0;

Просмотреть файл

@ -34,13 +34,13 @@ import com.semmle.ts.ast.InferTypeExpr;
import com.semmle.ts.ast.InterfaceDeclaration;
import com.semmle.ts.ast.InterfaceTypeExpr;
import com.semmle.ts.ast.IntersectionTypeExpr;
import com.semmle.ts.ast.IsTypeExpr;
import com.semmle.ts.ast.KeywordTypeExpr;
import com.semmle.ts.ast.MappedTypeExpr;
import com.semmle.ts.ast.NamespaceDeclaration;
import com.semmle.ts.ast.NonNullAssertion;
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.TupleTypeExpr;
import com.semmle.ts.ast.TypeAliasDeclaration;
@ -634,7 +634,7 @@ public class DefaultVisitor<C, R> implements Visitor<C, R> {
}
@Override
public R visit(IsTypeExpr nd, C c) {
public R visit(PredicateTypeExpr nd, C c) {
return visit((TypeExpression) nd, c);
}

Просмотреть файл

@ -75,6 +75,11 @@ public abstract class MemberDefinition<V extends Expression> extends Node {
return DeclarationFlags.isReadonly(flags);
}
/** Returns true if this has the <tt>declare</tt> modifier. */
public boolean hasDeclareKeyword() {
return DeclarationFlags.hasDeclareKeyword(flags);
}
/**
* Returns the expression denoting the name of the member, or {@code null} if this is a
* call/construct signature.

Просмотреть файл

@ -30,13 +30,13 @@ import com.semmle.ts.ast.InferTypeExpr;
import com.semmle.ts.ast.InterfaceDeclaration;
import com.semmle.ts.ast.InterfaceTypeExpr;
import com.semmle.ts.ast.IntersectionTypeExpr;
import com.semmle.ts.ast.IsTypeExpr;
import com.semmle.ts.ast.KeywordTypeExpr;
import com.semmle.ts.ast.MappedTypeExpr;
import com.semmle.ts.ast.NamespaceDeclaration;
import com.semmle.ts.ast.NonNullAssertion;
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.TupleTypeExpr;
import com.semmle.ts.ast.TypeAliasDeclaration;
@ -717,8 +717,12 @@ public class NodeCopier implements Visitor<Void, INode> {
}
@Override
public INode visit(IsTypeExpr nd, Void c) {
return new IsTypeExpr(visit(nd.getLoc()), copy(nd.getLeft()), copy(nd.getRight()));
public INode visit(PredicateTypeExpr nd, Void c) {
return new PredicateTypeExpr(
visit(nd.getLoc()),
copy(nd.getExpression()),
copy(nd.getTypeExpr()),
nd.hasAssertsKeyword());
}
@Override

Просмотреть файл

@ -30,13 +30,13 @@ import com.semmle.ts.ast.InferTypeExpr;
import com.semmle.ts.ast.InterfaceDeclaration;
import com.semmle.ts.ast.InterfaceTypeExpr;
import com.semmle.ts.ast.IntersectionTypeExpr;
import com.semmle.ts.ast.IsTypeExpr;
import com.semmle.ts.ast.KeywordTypeExpr;
import com.semmle.ts.ast.MappedTypeExpr;
import com.semmle.ts.ast.NamespaceDeclaration;
import com.semmle.ts.ast.NonNullAssertion;
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.TupleTypeExpr;
import com.semmle.ts.ast.TypeAliasDeclaration;
@ -256,7 +256,7 @@ public interface Visitor<C, R> {
public R visit(TypeofTypeExpr nd, C c);
public R visit(IsTypeExpr nd, C c);
public R visit(PredicateTypeExpr nd, C c);
public R visit(InterfaceTypeExpr nd, C c);

Просмотреть файл

@ -125,13 +125,13 @@ import com.semmle.ts.ast.InferTypeExpr;
import com.semmle.ts.ast.InterfaceDeclaration;
import com.semmle.ts.ast.InterfaceTypeExpr;
import com.semmle.ts.ast.IntersectionTypeExpr;
import com.semmle.ts.ast.IsTypeExpr;
import com.semmle.ts.ast.KeywordTypeExpr;
import com.semmle.ts.ast.MappedTypeExpr;
import com.semmle.ts.ast.NamespaceDeclaration;
import com.semmle.ts.ast.NonNullAssertion;
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.TupleTypeExpr;
import com.semmle.ts.ast.TypeAliasDeclaration;
@ -1410,6 +1410,10 @@ public class ASTExtractor {
}
}
if (nd.hasDeclareKeyword()) {
trapwriter.addTuple("hasDeclareKeyword", methkey);
}
return methkey;
}
@ -1707,10 +1711,13 @@ public class ASTExtractor {
}
@Override
public Label visit(IsTypeExpr nd, Context c) {
public Label visit(PredicateTypeExpr nd, Context c) {
Label key = super.visit(nd, c);
visit(nd.getLeft(), key, 0, IdContext.varInTypeBind);
visit(nd.getRight(), key, 1, IdContext.typeBind);
visit(nd.getExpression(), key, 0, IdContext.varInTypeBind);
visit(nd.getTypeExpr(), key, 1, IdContext.typeBind);
if (nd.hasAssertsKeyword()) {
trapwriter.addTuple("hasAssertsKeyword", key);
}
return key;
}

Просмотреть файл

@ -46,9 +46,9 @@ import com.semmle.ts.ast.InferTypeExpr;
import com.semmle.ts.ast.InterfaceDeclaration;
import com.semmle.ts.ast.InterfaceTypeExpr;
import com.semmle.ts.ast.IntersectionTypeExpr;
import com.semmle.ts.ast.IsTypeExpr;
import com.semmle.ts.ast.NamespaceDeclaration;
import com.semmle.ts.ast.ParenthesizedTypeExpr;
import com.semmle.ts.ast.PredicateTypeExpr;
import com.semmle.ts.ast.TupleTypeExpr;
import com.semmle.ts.ast.TypeAliasDeclaration;
import com.semmle.ts.ast.UnionTypeExpr;
@ -660,8 +660,8 @@ public class ScopeManager {
}
@Override
public Void visit(IsTypeExpr nd, Void c) {
return nd.getRight().accept(this, c);
public Void visit(PredicateTypeExpr nd, Void c) {
return nd.getTypeExpr().accept(this, c);
}
@Override

Просмотреть файл

@ -16,11 +16,11 @@ import com.semmle.ts.ast.IndexedAccessTypeExpr;
import com.semmle.ts.ast.InferTypeExpr;
import com.semmle.ts.ast.InterfaceTypeExpr;
import com.semmle.ts.ast.IntersectionTypeExpr;
import com.semmle.ts.ast.IsTypeExpr;
import com.semmle.ts.ast.KeywordTypeExpr;
import com.semmle.ts.ast.MappedTypeExpr;
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.TupleTypeExpr;
import com.semmle.ts.ast.TypeParameter;
@ -159,7 +159,7 @@ public class TypeExprKinds {
}
@Override
public Integer visit(IsTypeExpr nd, Void c) {
public Integer visit(PredicateTypeExpr nd, Void c) {
return isTypeExpr;
}

Просмотреть файл

@ -17,6 +17,7 @@ import com.semmle.js.ast.BlockStatement;
import com.semmle.js.ast.BreakStatement;
import com.semmle.js.ast.CallExpression;
import com.semmle.js.ast.CatchClause;
import com.semmle.js.ast.Chainable;
import com.semmle.js.ast.ClassBody;
import com.semmle.js.ast.ClassDeclaration;
import com.semmle.js.ast.ClassExpression;
@ -126,13 +127,13 @@ import com.semmle.ts.ast.InferTypeExpr;
import com.semmle.ts.ast.InterfaceDeclaration;
import com.semmle.ts.ast.InterfaceTypeExpr;
import com.semmle.ts.ast.IntersectionTypeExpr;
import com.semmle.ts.ast.IsTypeExpr;
import com.semmle.ts.ast.KeywordTypeExpr;
import com.semmle.ts.ast.MappedTypeExpr;
import com.semmle.ts.ast.NamespaceDeclaration;
import com.semmle.ts.ast.NonNullAssertion;
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.TupleTypeExpr;
import com.semmle.ts.ast.TypeAliasDeclaration;
@ -877,7 +878,10 @@ public class TypeScriptASTConverter {
}
Expression callee = convertChild(node, "expression");
List<ITypeExpression> typeArguments = convertChildrenAsTypes(node, "typeArguments");
CallExpression call = new CallExpression(loc, callee, typeArguments, arguments, false, false);
boolean optional = node.has("questionDotToken");
boolean onOptionalChain = Chainable.isOnOptionalChain(optional, callee);
CallExpression call =
new CallExpression(loc, callee, typeArguments, arguments, optional, onOptionalChain);
attachResolvedSignature(call, node);
return call;
}
@ -1108,7 +1112,9 @@ public class TypeScriptASTConverter {
throws ParseError {
Expression object = convertChild(node, "expression");
Expression property = convertChild(node, "argumentExpression");
return new MemberExpression(loc, object, property, true, false, false);
boolean optional = node.has("questionDotToken");
boolean onOptionalChain = Chainable.isOnOptionalChain(optional, object);
return new MemberExpression(loc, object, property, true, optional, onOptionalChain);
}
private Node convertEmptyStatement(SourceLocation loc) {
@ -1584,10 +1590,14 @@ public class TypeScriptASTConverter {
private Node convertMetaProperty(JsonObject node, SourceLocation loc) throws ParseError {
Position metaStart = loc.getStart();
String keywordKind = syntaxKinds.get(node.getAsJsonPrimitive("keywordToken").getAsInt() + "").getAsString();
String keywordKind =
syntaxKinds.get(node.getAsJsonPrimitive("keywordToken").getAsInt() + "").getAsString();
String identifier = keywordKind.equals("ImportKeyword") ? "import" : "new";
Position metaEnd =
new Position(metaStart.getLine(), metaStart.getColumn() + identifier.length(), metaStart.getOffset() + identifier.length());
new Position(
metaStart.getLine(),
metaStart.getColumn() + identifier.length(),
metaStart.getOffset() + identifier.length());
SourceLocation metaLoc = new SourceLocation(identifier, metaStart, metaEnd);
Identifier meta = new Identifier(metaLoc, identifier);
return new MetaProperty(loc, meta, convertChild(node, "name"));
@ -1967,8 +1977,11 @@ public class TypeScriptASTConverter {
private Node convertPropertyAccessExpression(JsonObject node, SourceLocation loc)
throws ParseError {
Expression base = convertChild(node, "expression");
boolean optional = node.has("questionDotToken");
boolean onOptionalChain = Chainable.isOnOptionalChain(optional, base);
return new MemberExpression(
loc, convertChild(node, "expression"), convertChild(node, "name"), false, false, false);
loc, base, convertChild(node, "name"), false, optional, onOptionalChain);
}
private Node convertPropertyAssignment(JsonObject node, SourceLocation loc) throws ParseError {
@ -1996,6 +2009,9 @@ public class TypeScriptASTConverter {
if (node.get("exclamationToken") != null) {
flags |= DeclarationFlags.definiteAssignmentAssertion;
}
if (hasModifier(node, "DeclareKeyword")) {
flags |= DeclarationFlags.declareKeyword;
}
FieldDefinition fieldDefinition =
new FieldDefinition(
loc,
@ -2186,8 +2202,11 @@ public class TypeScriptASTConverter {
}
private Node convertTypePredicate(JsonObject node, SourceLocation loc) throws ParseError {
return new IsTypeExpr(
loc, convertChildAsType(node, "parameterName"), convertChildAsType(node, "type"));
return new PredicateTypeExpr(
loc,
convertChildAsType(node, "parameterName"),
convertChildAsType(node, "type"),
node.has("assertsModifier"));
}
private Node convertTypeReference(JsonObject node, SourceLocation loc) throws ParseError {

Просмотреть файл

@ -1,32 +0,0 @@
package com.semmle.ts.ast;
import com.semmle.js.ast.SourceLocation;
import com.semmle.js.ast.Visitor;
/**
* A type of form <tt>E is T</tt> where <tt>E</tt> is a parameter name or <tt>this</tt> and
* <tt>T</tt> is a type.
*/
public class IsTypeExpr extends TypeExpression {
private final ITypeExpression left; // Always Identifier or KeywordTypeExpr (in case of 'this')
private final ITypeExpression right;
public IsTypeExpr(SourceLocation loc, ITypeExpression left, ITypeExpression right) {
super("IsTypeExpr", loc);
this.left = left;
this.right = right;
}
public ITypeExpression getLeft() {
return left;
}
public ITypeExpression getRight() {
return right;
}
@Override
public <C, R> R accept(Visitor<C, R> v, C c) {
return v.visit(this, c);
}
}

Просмотреть файл

@ -0,0 +1,44 @@
package com.semmle.ts.ast;
import com.semmle.js.ast.SourceLocation;
import com.semmle.js.ast.Visitor;
/**
* A type of form <tt>E is T</tt>, <tt>asserts E is T</tt> or <tt>asserts E</tt> where <tt>E</tt> is
* a parameter name or <tt>this</tt> and <tt>T</tt> is a type.
*/
public class PredicateTypeExpr extends TypeExpression {
private final ITypeExpression expression;
private final ITypeExpression type;
private final boolean hasAssertsKeyword;
public PredicateTypeExpr(
SourceLocation loc,
ITypeExpression expression,
ITypeExpression type,
boolean hasAssertsKeyword) {
super("PredicateTypeExpr", loc);
this.expression = expression;
this.type = type;
this.hasAssertsKeyword = hasAssertsKeyword;
}
/** Returns the <tt>E</tt> in <tt>E is T</tt>. */
public ITypeExpression getExpression() {
return expression;
}
/** Returns the <tt>T</tt> in <tt>E is T</tt>. */
public ITypeExpression getTypeExpr() {
return type;
}
public boolean hasAssertsKeyword() {
return hasAssertsKeyword;
}
@Override
public <C, R> R accept(Visitor<C, R> v, C c) {
return v.visit(this, c);
}
}

Просмотреть файл

@ -0,0 +1,3 @@
base?.x.y;
base?.(x).y;
base?.[z].y;

Просмотреть файл

@ -0,0 +1,303 @@
#10000=@"/optionalChaining.ts;sourcefile"
files(#10000,"/optionalChaining.ts","optionalChaining","ts",0)
#10001=@"/;folder"
folders(#10001,"/","")
containerparent(#10001,#10000)
#10002=@"loc,{#10000},0,0,0,0"
locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},1,1"
#20002=*
lines(#20002,#20001,"base?.x.y;","
")
#20003=@"loc,{#10000},1,1,1,10"
locations_default(#20003,#10000,1,1,1,10)
hasLocation(#20002,#20003)
#20004=*
lines(#20004,#20001,"base?.(x).y;","
")
#20005=@"loc,{#10000},2,1,2,12"
locations_default(#20005,#10000,2,1,2,12)
hasLocation(#20004,#20005)
#20006=*
lines(#20006,#20001,"base?.[z].y;","
")
#20007=@"loc,{#10000},3,1,3,12"
locations_default(#20007,#10000,3,1,3,12)
hasLocation(#20006,#20007)
numlines(#20001,3,3,0)
#20008=*
tokeninfo(#20008,6,#20001,0,"base")
#20009=@"loc,{#10000},1,1,1,4"
locations_default(#20009,#10000,1,1,1,4)
hasLocation(#20008,#20009)
#20010=*
tokeninfo(#20010,8,#20001,1,"?.")
#20011=@"loc,{#10000},1,5,1,6"
locations_default(#20011,#10000,1,5,1,6)
hasLocation(#20010,#20011)
#20012=*
tokeninfo(#20012,6,#20001,2,"x")
#20013=@"loc,{#10000},1,7,1,7"
locations_default(#20013,#10000,1,7,1,7)
hasLocation(#20012,#20013)
#20014=*
tokeninfo(#20014,8,#20001,3,".")
#20015=@"loc,{#10000},1,8,1,8"
locations_default(#20015,#10000,1,8,1,8)
hasLocation(#20014,#20015)
#20016=*
tokeninfo(#20016,6,#20001,4,"y")
#20017=@"loc,{#10000},1,9,1,9"
locations_default(#20017,#10000,1,9,1,9)
hasLocation(#20016,#20017)
#20018=*
tokeninfo(#20018,8,#20001,5,";")
#20019=@"loc,{#10000},1,10,1,10"
locations_default(#20019,#10000,1,10,1,10)
hasLocation(#20018,#20019)
#20020=*
tokeninfo(#20020,6,#20001,6,"base")
#20021=@"loc,{#10000},2,1,2,4"
locations_default(#20021,#10000,2,1,2,4)
hasLocation(#20020,#20021)
#20022=*
tokeninfo(#20022,8,#20001,7,"?.")
#20023=@"loc,{#10000},2,5,2,6"
locations_default(#20023,#10000,2,5,2,6)
hasLocation(#20022,#20023)
#20024=*
tokeninfo(#20024,8,#20001,8,"(")
#20025=@"loc,{#10000},2,7,2,7"
locations_default(#20025,#10000,2,7,2,7)
hasLocation(#20024,#20025)
#20026=*
tokeninfo(#20026,6,#20001,9,"x")
#20027=@"loc,{#10000},2,8,2,8"
locations_default(#20027,#10000,2,8,2,8)
hasLocation(#20026,#20027)
#20028=*
tokeninfo(#20028,8,#20001,10,")")
#20029=@"loc,{#10000},2,9,2,9"
locations_default(#20029,#10000,2,9,2,9)
hasLocation(#20028,#20029)
#20030=*
tokeninfo(#20030,8,#20001,11,".")
#20031=@"loc,{#10000},2,10,2,10"
locations_default(#20031,#10000,2,10,2,10)
hasLocation(#20030,#20031)
#20032=*
tokeninfo(#20032,6,#20001,12,"y")
#20033=@"loc,{#10000},2,11,2,11"
locations_default(#20033,#10000,2,11,2,11)
hasLocation(#20032,#20033)
#20034=*
tokeninfo(#20034,8,#20001,13,";")
#20035=@"loc,{#10000},2,12,2,12"
locations_default(#20035,#10000,2,12,2,12)
hasLocation(#20034,#20035)
#20036=*
tokeninfo(#20036,6,#20001,14,"base")
#20037=@"loc,{#10000},3,1,3,4"
locations_default(#20037,#10000,3,1,3,4)
hasLocation(#20036,#20037)
#20038=*
tokeninfo(#20038,8,#20001,15,"?.")
#20039=@"loc,{#10000},3,5,3,6"
locations_default(#20039,#10000,3,5,3,6)
hasLocation(#20038,#20039)
#20040=*
tokeninfo(#20040,8,#20001,16,"[")
#20041=@"loc,{#10000},3,7,3,7"
locations_default(#20041,#10000,3,7,3,7)
hasLocation(#20040,#20041)
#20042=*
tokeninfo(#20042,6,#20001,17,"z")
#20043=@"loc,{#10000},3,8,3,8"
locations_default(#20043,#10000,3,8,3,8)
hasLocation(#20042,#20043)
#20044=*
tokeninfo(#20044,8,#20001,18,"]")
#20045=@"loc,{#10000},3,9,3,9"
locations_default(#20045,#10000,3,9,3,9)
hasLocation(#20044,#20045)
#20046=*
tokeninfo(#20046,8,#20001,19,".")
#20047=@"loc,{#10000},3,10,3,10"
locations_default(#20047,#10000,3,10,3,10)
hasLocation(#20046,#20047)
#20048=*
tokeninfo(#20048,6,#20001,20,"y")
#20049=@"loc,{#10000},3,11,3,11"
locations_default(#20049,#10000,3,11,3,11)
hasLocation(#20048,#20049)
#20050=*
tokeninfo(#20050,8,#20001,21,";")
#20051=@"loc,{#10000},3,12,3,12"
locations_default(#20051,#10000,3,12,3,12)
hasLocation(#20050,#20051)
#20052=*
tokeninfo(#20052,0,#20001,22,"")
#20053=@"loc,{#10000},4,1,4,0"
locations_default(#20053,#10000,4,1,4,0)
hasLocation(#20052,#20053)
toplevels(#20001,0)
#20054=@"loc,{#10000},1,1,4,0"
locations_default(#20054,#10000,1,1,4,0)
hasLocation(#20001,#20054)
#20055=*
stmts(#20055,2,#20001,0,"base?.x.y;")
hasLocation(#20055,#20003)
stmtContainers(#20055,#20001)
#20056=*
exprs(#20056,14,#20055,0,"base?.x.y")
#20057=@"loc,{#10000},1,1,1,9"
locations_default(#20057,#10000,1,1,1,9)
hasLocation(#20056,#20057)
enclosingStmt(#20056,#20055)
exprContainers(#20056,#20001)
#20058=*
exprs(#20058,14,#20056,0,"base?.x")
#20059=@"loc,{#10000},1,1,1,7"
locations_default(#20059,#10000,1,1,1,7)
hasLocation(#20058,#20059)
enclosingStmt(#20058,#20055)
exprContainers(#20058,#20001)
#20060=*
exprs(#20060,79,#20058,0,"base")
hasLocation(#20060,#20009)
enclosingStmt(#20060,#20055)
exprContainers(#20060,#20001)
literals("base","base",#20060)
#20061=@"var;{base};{#20000}"
variables(#20061,"base",#20000)
bind(#20060,#20061)
#20062=*
exprs(#20062,0,#20058,1,"x")
hasLocation(#20062,#20013)
enclosingStmt(#20062,#20055)
exprContainers(#20062,#20001)
literals("x","x",#20062)
isOptionalChaining(#20058)
#20063=*
exprs(#20063,0,#20056,1,"y")
hasLocation(#20063,#20017)
enclosingStmt(#20063,#20055)
exprContainers(#20063,#20001)
literals("y","y",#20063)
#20064=*
stmts(#20064,2,#20001,1,"base?.(x).y;")
hasLocation(#20064,#20005)
stmtContainers(#20064,#20001)
#20065=*
exprs(#20065,14,#20064,0,"base?.(x).y")
#20066=@"loc,{#10000},2,1,2,11"
locations_default(#20066,#10000,2,1,2,11)
hasLocation(#20065,#20066)
enclosingStmt(#20065,#20064)
exprContainers(#20065,#20001)
#20067=*
exprs(#20067,13,#20065,0,"base?.(x)")
#20068=@"loc,{#10000},2,1,2,9"
locations_default(#20068,#10000,2,1,2,9)
hasLocation(#20067,#20068)
enclosingStmt(#20067,#20064)
exprContainers(#20067,#20001)
#20069=*
exprs(#20069,79,#20067,-1,"base")
hasLocation(#20069,#20021)
enclosingStmt(#20069,#20064)
exprContainers(#20069,#20001)
literals("base","base",#20069)
bind(#20069,#20061)
#20070=*
exprs(#20070,79,#20067,0,"x")
hasLocation(#20070,#20027)
enclosingStmt(#20070,#20064)
exprContainers(#20070,#20001)
literals("x","x",#20070)
#20071=@"var;{x};{#20000}"
variables(#20071,"x",#20000)
bind(#20070,#20071)
isOptionalChaining(#20067)
#20072=*
exprs(#20072,0,#20065,1,"y")
hasLocation(#20072,#20033)
enclosingStmt(#20072,#20064)
exprContainers(#20072,#20001)
literals("y","y",#20072)
#20073=*
stmts(#20073,2,#20001,2,"base?.[z].y;")
hasLocation(#20073,#20007)
stmtContainers(#20073,#20001)
#20074=*
exprs(#20074,14,#20073,0,"base?.[z].y")
#20075=@"loc,{#10000},3,1,3,11"
locations_default(#20075,#10000,3,1,3,11)
hasLocation(#20074,#20075)
enclosingStmt(#20074,#20073)
exprContainers(#20074,#20001)
#20076=*
exprs(#20076,15,#20074,0,"base?.[z]")
#20077=@"loc,{#10000},3,1,3,9"
locations_default(#20077,#10000,3,1,3,9)
hasLocation(#20076,#20077)
enclosingStmt(#20076,#20073)
exprContainers(#20076,#20001)
#20078=*
exprs(#20078,79,#20076,0,"base")
hasLocation(#20078,#20037)
enclosingStmt(#20078,#20073)
exprContainers(#20078,#20001)
literals("base","base",#20078)
bind(#20078,#20061)
#20079=*
exprs(#20079,79,#20076,1,"z")
hasLocation(#20079,#20043)
enclosingStmt(#20079,#20073)
exprContainers(#20079,#20001)
literals("z","z",#20079)
#20080=@"var;{z};{#20000}"
variables(#20080,"z",#20000)
bind(#20079,#20080)
isOptionalChaining(#20076)
#20081=*
exprs(#20081,0,#20074,1,"y")
hasLocation(#20081,#20049)
enclosingStmt(#20081,#20073)
exprContainers(#20081,#20001)
literals("y","y",#20081)
#20082=*
entry_cfg_node(#20082,#20001)
#20083=@"loc,{#10000},1,1,1,0"
locations_default(#20083,#10000,1,1,1,0)
hasLocation(#20082,#20083)
#20084=*
exit_cfg_node(#20084,#20001)
hasLocation(#20084,#20053)
successor(#20073,#20078)
successor(#20081,#20074)
successor(#20079,#20076)
successor(#20078,#20079)
successor(#20076,#20081)
successor(#20078,#20084)
successor(#20074,#20084)
successor(#20064,#20069)
successor(#20072,#20065)
successor(#20070,#20067)
successor(#20069,#20070)
successor(#20067,#20072)
successor(#20069,#20073)
successor(#20065,#20073)
successor(#20055,#20060)
successor(#20063,#20056)
successor(#20062,#20058)
successor(#20060,#20062)
successor(#20058,#20063)
successor(#20060,#20064)
successor(#20056,#20064)
successor(#20082,#20055)
numlines(#10000,3,3,0)
filetype(#10000,"typescript")

Просмотреть файл

@ -1059,6 +1059,12 @@ class FieldDeclaration extends MemberDeclaration, @field {
/** Holds if this is a TypeScript field marked as definitely assigned with the `!` operator. */
predicate hasDefiniteAssignmentAssertion() { hasDefiniteAssignmentAssertion(this) }
override predicate isAmbient() {
hasDeclareKeyword(this)
or
getParent().isAmbient()
}
}
/**

Просмотреть файл

@ -914,20 +914,49 @@ class TypeofTypeExpr extends @typeoftypeexpr, TypeExpr {
}
/**
* A type of form `E is T` where `E` is a parameter name or `this`, and `T` is a type.
* A function return type that refines the type of one of its parameters or `this`.
*
* This can only occur as the return type of a function type.
* Examples:
* ```js
* function f(x): x is string {}
* function f(x): asserts x is string {}
* function f(x): asserts x {}
* ```
*/
class IsTypeExpr extends @istypeexpr, TypeExpr {
class PredicateTypeExpr extends @predicatetypeexpr, TypeExpr {
/**
* Gets the parameter name or `this` token `E` in `E is T`.
*/
VarTypeAccess getParameterName() { result = this.getChildTypeExpr(0) }
/**
* Gets the type `T` in `E is T`.
* Gets the type `T` in `E is T` or `asserts E is T`.
*
* Has no results for types of form `asserts E`.
*/
TypeExpr getPredicateType() { result = this.getChildTypeExpr(1) }
/**
* Holds if this is a type of form `asserts E is T` or `asserts E`.
*/
predicate hasAssertsKeyword() {
hasAssertsKeyword(this)
}
}
/**
* A function return type of form `x is T` or `asserts x is T`.
*
* Examples:
* ```js
* function f(x): x is string {}
* function f(x): asserts x is string {}
* ```
*/
class IsTypeExpr extends PredicateTypeExpr {
IsTypeExpr() {
exists(getPredicateType())
}
}
/**
@ -966,15 +995,16 @@ class ReadonlyTypeExpr extends @readonlytypeexpr, TypeExpr {
*
* This can occur as
* - part of the operand to a `typeof` type, or
* - as the first operand to an `is` type.
* - as the first operand to a predicate type
*
* For example, it may occur as the `E` in these examples:
* ```
* var x : typeof E
* function f(...) : E is T {}
* function f(...) : asserts E {}
* ```
*
* In the latter case, this may also refer to the pseudo-variable `this`.
* In the latter two cases, this may also refer to the pseudo-variable `this`.
*/
class VarTypeAccess extends @vartypeaccess, TypeExpr { }

Просмотреть файл

@ -200,8 +200,8 @@ case @stmt.kind of
isInstantiated(unique int decl: @namespacedeclaration ref);
@declarablestmt = @declstmt | @namespacedeclaration | @classdeclstmt | @functiondeclstmt | @enumdeclaration | @externalmoduledeclaration | @globalaugmentationdeclaration;
hasDeclareKeyword(unique int stmt: @declarablestmt ref);
@declarablenode = @declstmt | @namespacedeclaration | @classdeclstmt | @functiondeclstmt | @enumdeclaration | @externalmoduledeclaration | @globalaugmentationdeclaration | @field;
hasDeclareKeyword(unique int stmt: @declarablenode ref);
isForAwaitOf(unique int forof: @forofstmt ref);
@ -559,7 +559,7 @@ case @typeexpr.kind of
| 17 = @localvartypeaccess
| 18 = @qualifiedvartypeaccess
| 19 = @thisvartypeaccess
| 20 = @istypeexpr
| 20 = @predicatetypeexpr
| 21 = @interfacetypeexpr
| 22 = @typeparameter
| 23 = @plainfunctiontypeexpr
@ -637,6 +637,8 @@ case @type.kind of
@unionorintersectiontype = @uniontype | @intersectiontype;
@typevariabletype = @canonicaltypevariabletype | @lexicaltypevariabletype;
hasAssertsKeyword(int node: @predicatetypeexpr ref);
@typed_ast_node = @expr | @typeexpr | @function;
ast_node_type(
unique int node: @typed_ast_node ref,

Просмотреть файл

@ -850,7 +850,7 @@
<v>20</v>
</e>
<e>
<k>@istypeexpr</k>
<k>@predicatetypeexpr</k>
<v>86</v>
</e>
<e>
@ -7918,6 +7918,17 @@
<dependencies/>
</relation>
<relation>
<name>hasAssertsKeyword</name>
<cardinality>66</cardinality>
<columnsizes>
<e>
<k>node</k>
<v>66</v>
</e>
</columnsizes>
<dependencies/>
</relation>
<relation>
<name>isAbstractMember</name>
<cardinality>66</cardinality>
<columnsizes>

Просмотреть файл

@ -208,6 +208,8 @@
| nodeJsLib.js:1:18:1:43 | instance of function nodeJsModule |
| nodeJsLib.js:3:15:3:37 | function nodeJsFoo |
| nodeJsLib.js:3:15:3:37 | instance of function nodeJsFoo |
| nullish-coalescing-op.ts:1:1:3:1 | function test |
| nullish-coalescing-op.ts:1:1:3:1 | instance of function test |
| o.js:1:1:2:0 | exports object of module o |
| o.js:1:1:2:0 | module object of module o |
| objlit.js:1:14:1:15 | object literal |

Просмотреть файл

@ -204,6 +204,8 @@
| nodeJsClient.js:5:5:5:6 | x2 | nodeJsClient.js:5:10:5:15 | es.foo | esLib.js:3:8:3:24 | function foo |
| nodeJsClient.js:5:5:5:6 | x2 | nodeJsClient.js:5:10:5:15 | es.foo | file://:0:0:0:0 | indefinite value (call) |
| nodeJsClient.js:5:5:5:6 | x2 | nodeJsClient.js:5:10:5:15 | es.foo | file://:0:0:0:0 | indefinite value (heap) |
| nullish-coalescing-op.ts:2:7:2:7 | y | nullish-coalescing-op.ts:2:11:2:18 | x ?? 0.5 | file://:0:0:0:0 | indefinite value (call) |
| nullish-coalescing-op.ts:2:7:2:7 | y | nullish-coalescing-op.ts:2:11:2:18 | x ?? 0.5 | file://:0:0:0:0 | non-zero value |
| objlit.js:1:5:1:5 | A | objlit.js:1:9:1:15 | A \|\| {} | file://:0:0:0:0 | indefinite value (global) |
| objlit.js:1:5:1:5 | A | objlit.js:1:9:1:15 | A \|\| {} | objlit.js:1:14:1:15 | object literal |
| objlit.js:7:5:7:5 | B | objlit.js:7:9:7:10 | {} | objlit.js:7:9:7:10 | object literal |

Просмотреть файл

@ -40,6 +40,7 @@
| nestedImport.js:9:1:12:1 | instance of function tst | nestedImport.js:9:1:12:1 | instance of function tst |
| nodeJsLib.js:1:18:1:43 | instance of function nodeJsModule | nodeJsLib.js:1:18:1:43 | instance of function nodeJsModule |
| nodeJsLib.js:3:15:3:37 | instance of function nodeJsFoo | nodeJsLib.js:3:15:3:37 | instance of function nodeJsFoo |
| nullish-coalescing-op.ts:1:1:3:1 | instance of function test | nullish-coalescing-op.ts:1:1:3:1 | instance of function test |
| objlit.js:2:9:2:21 | instance of anonymous function | objlit.js:2:9:2:21 | instance of anonymous function |
| objlit.js:4:8:4:20 | instance of method baz | objlit.js:4:8:4:20 | instance of method baz |
| objlit.js:10:2:12:1 | instance of anonymous function | objlit.js:10:2:12:1 | instance of anonymous function |

Просмотреть файл

@ -0,0 +1,3 @@
function test(x) {
let y = x ?? 0.5;
}

Просмотреть файл

@ -113,6 +113,7 @@
| nodeJsClient.js:2:5:2:6 | es | nodeJsClient.js:2:10:2:27 | require('./esLib') | boolean, class, date, function, null, number, object, regular expression,string or undefined |
| nodeJsClient.js:4:5:4:6 | x1 | nodeJsClient.js:4:10:4:15 | nj.foo | boolean, class, date, function, null, number, object, regular expression,string or undefined |
| nodeJsClient.js:5:5:5:6 | x2 | nodeJsClient.js:5:10:5:15 | es.foo | boolean, class, date, function, null, number, object, regular expression,string or undefined |
| nullish-coalescing-op.ts:2:7:2:7 | y | nullish-coalescing-op.ts:2:11:2:18 | x ?? 0.5 | boolean, class, date, function, null, number, object, regular expression,string or undefined |
| objlit.js:1:5:1:5 | A | objlit.js:1:9:1:15 | A \|\| {} | boolean, class, date, function, null, number, object, regular expression,string or undefined |
| objlit.js:7:5:7:5 | B | objlit.js:7:9:7:10 | {} | object |
| objlit.js:14:5:14:6 | x1 | objlit.js:14:10:14:10 | A | boolean, class, date, function, null, number, object, regular expression,string or undefined |

Просмотреть файл

@ -1,7 +1,25 @@
| short-circuiting-typescript.ts:3:5:3:18 | x?.(o1 = null) | short-circuiting-typescript.ts:3:5:3:18 | x?.(o1 = null) |
| short-circuiting-typescript.ts:7:5:7:18 | x?.[o2 = null] | short-circuiting-typescript.ts:7:5:7:18 | x?.[o2 = null] |
| short-circuiting-typescript.ts:12:5:12:31 | x?.[o3 ... = null) | short-circuiting-typescript.ts:12:5:12:18 | x?.[o3 = null] |
| short-circuiting-typescript.ts:12:5:12:31 | x?.[o3 ... = null) | short-circuiting-typescript.ts:12:5:12:31 | x?.[o3 ... = null) |
| short-circuiting.js:3:5:3:18 | x?.(o1 = null) | short-circuiting.js:3:5:3:18 | x?.(o1 = null) |
| short-circuiting.js:7:5:7:18 | x?.[o2 = null] | short-circuiting.js:7:5:7:18 | x?.[o2 = null] |
| short-circuiting.js:12:5:12:31 | x?.[o3 ... = null) | short-circuiting.js:12:5:12:18 | x?.[o3 = null] |
| short-circuiting.js:12:5:12:31 | x?.[o3 ... = null) | short-circuiting.js:12:5:12:31 | x?.[o3 ... = null) |
| tst-typescript.ts:2:1:2:6 | a?.b.c | tst-typescript.ts:2:1:2:4 | a?.b |
| tst-typescript.ts:3:1:3:6 | a.b?.c | tst-typescript.ts:3:1:3:6 | a.b?.c |
| tst-typescript.ts:4:1:4:7 | a?.b?.c | tst-typescript.ts:4:1:4:4 | a?.b |
| tst-typescript.ts:4:1:4:7 | a?.b?.c | tst-typescript.ts:4:1:4:7 | a?.b?.c |
| tst-typescript.ts:7:1:7:7 | f?.()() | tst-typescript.ts:7:1:7:5 | f?.() |
| tst-typescript.ts:8:1:8:7 | f()?.() | tst-typescript.ts:8:1:8:7 | f()?.() |
| tst-typescript.ts:9:1:9:9 | f?.()?.() | tst-typescript.ts:9:1:9:5 | f?.() |
| tst-typescript.ts:9:1:9:9 | f?.()?.() | tst-typescript.ts:9:1:9:9 | f?.()?.() |
| tst-typescript.ts:12:1:12:8 | a?.m().b | tst-typescript.ts:12:1:12:4 | a?.m |
| tst-typescript.ts:13:1:13:9 | a.m?.().b | tst-typescript.ts:13:1:13:7 | a.m?.() |
| tst-typescript.ts:14:1:14:8 | a.m()?.b | tst-typescript.ts:14:1:14:8 | a.m()?.b |
| tst-typescript.ts:15:1:15:11 | a?.m?.()?.b | tst-typescript.ts:15:1:15:4 | a?.m |
| tst-typescript.ts:15:1:15:11 | a?.m?.()?.b | tst-typescript.ts:15:1:15:8 | a?.m?.() |
| tst-typescript.ts:15:1:15:11 | a?.m?.()?.b | tst-typescript.ts:15:1:15:11 | a?.m?.()?.b |
| tst.js:2:1:2:6 | a?.b.c | tst.js:2:1:2:4 | a?.b |
| tst.js:3:1:3:6 | a.b?.c | tst.js:3:1:3:6 | a.b?.c |
| tst.js:4:1:4:7 | a?.b?.c | tst.js:4:1:4:4 | a?.b |

Просмотреть файл

@ -1,7 +1,25 @@
| short-circuiting-typescript.ts:3:5:3:18 | x?.(o1 = null) |
| short-circuiting-typescript.ts:7:5:7:18 | x?.[o2 = null] |
| short-circuiting-typescript.ts:12:5:12:18 | x?.[o3 = null] |
| short-circuiting-typescript.ts:12:5:12:31 | x?.[o3 ... = null) |
| short-circuiting.js:3:5:3:18 | x?.(o1 = null) |
| short-circuiting.js:7:5:7:18 | x?.[o2 = null] |
| short-circuiting.js:12:5:12:18 | x?.[o3 = null] |
| short-circuiting.js:12:5:12:31 | x?.[o3 ... = null) |
| tst-typescript.ts:2:1:2:4 | a?.b |
| tst-typescript.ts:3:1:3:6 | a.b?.c |
| tst-typescript.ts:4:1:4:4 | a?.b |
| tst-typescript.ts:4:1:4:7 | a?.b?.c |
| tst-typescript.ts:7:1:7:5 | f?.() |
| tst-typescript.ts:8:1:8:7 | f()?.() |
| tst-typescript.ts:9:1:9:5 | f?.() |
| tst-typescript.ts:9:1:9:9 | f?.()?.() |
| tst-typescript.ts:12:1:12:4 | a?.m |
| tst-typescript.ts:13:1:13:7 | a.m?.() |
| tst-typescript.ts:14:1:14:8 | a.m()?.b |
| tst-typescript.ts:15:1:15:4 | a?.m |
| tst-typescript.ts:15:1:15:8 | a?.m?.() |
| tst-typescript.ts:15:1:15:11 | a?.m?.()?.b |
| tst.js:2:1:2:4 | a?.b |
| tst.js:3:1:3:6 | a.b?.c |
| tst.js:4:1:4:4 | a?.b |

Просмотреть файл

@ -1,3 +1,11 @@
| short-circuiting-typescript.ts:4:10:4:11 | o1 | file://:0:0:0:0 | null |
| short-circuiting-typescript.ts:4:10:4:11 | o1 | short-circuiting-typescript.ts:2:14:2:15 | object literal |
| short-circuiting-typescript.ts:8:10:8:11 | o2 | file://:0:0:0:0 | null |
| short-circuiting-typescript.ts:8:10:8:11 | o2 | short-circuiting-typescript.ts:6:14:6:15 | object literal |
| short-circuiting-typescript.ts:13:10:13:11 | o3 | file://:0:0:0:0 | null |
| short-circuiting-typescript.ts:13:10:13:11 | o3 | short-circuiting-typescript.ts:10:14:10:15 | object literal |
| short-circuiting-typescript.ts:14:10:14:11 | o4 | file://:0:0:0:0 | null |
| short-circuiting-typescript.ts:14:10:14:11 | o4 | short-circuiting-typescript.ts:11:14:11:15 | object literal |
| short-circuiting.js:4:10:4:11 | o1 | file://:0:0:0:0 | null |
| short-circuiting.js:4:10:4:11 | o1 | short-circuiting.js:2:14:2:15 | object literal |
| short-circuiting.js:8:10:8:11 | o2 | file://:0:0:0:0 | null |

Просмотреть файл

@ -1,8 +0,0 @@
| short-circuiting.js:4:10:4:11 | o1 | file://:0:0:0:0 | null |
| short-circuiting.js:4:10:4:11 | o1 | short-circuiting.js:2:14:2:15 | object literal |
| short-circuiting.js:8:10:8:11 | o2 | file://:0:0:0:0 | null |
| short-circuiting.js:8:10:8:11 | o2 | short-circuiting.js:6:14:6:15 | object literal |
| short-circuiting.js:13:10:13:11 | o3 | file://:0:0:0:0 | null |
| short-circuiting.js:13:10:13:11 | o3 | short-circuiting.js:10:14:10:15 | object literal |
| short-circuiting.js:14:10:14:11 | o4 | file://:0:0:0:0 | null |
| short-circuiting.js:14:10:14:11 | o4 | short-circuiting.js:11:14:11:15 | object literal |

Просмотреть файл

@ -1,7 +0,0 @@
import javascript
from CallExpr c, Expr arg
where
c.getCalleeName() = "DUMP" and
arg = c.getArgument(0)
select arg, arg.analyze().getAValue()

Просмотреть файл

@ -0,0 +1,15 @@
(function() {
var o1 = {};
x?.(o1 = null);
DUMP(o1);
var o2 = {};
x?.[o2 = null];
DUMP(o2);
var o3 = {},
o4 = {};
x?.[o3 = null]?.(o4 = null);
DUMP(o3);
DUMP(o4);
});

Просмотреть файл

@ -0,0 +1,15 @@
a.b.c;
a?.b.c;
a.b?.c;
a?.b?.c;
f()();
f?.()();
f()?.();
f?.()?.();
a.m().b;
a?.m().b;
a.m?.().b;
a.m()?.b;
a?.m?.()?.b;

Просмотреть файл

@ -0,0 +1 @@
| tst.ts:2:5:2:22 | declare x: number; | true |

Просмотреть файл

@ -0,0 +1,5 @@
import javascript
from FieldDeclaration f, boolean ambient
where if f.isAmbient() then ambient = true else ambient = false
select f, ambient

Просмотреть файл

@ -0,0 +1,3 @@
class C {
declare x: number;
}

Просмотреть файл

@ -1,10 +1,8 @@
| p1 | MyPromise<string> | string |
| p2 | MyPromise<any> | any |
| p3 | Promise<string> | string |
| p4 | PromiseLike<string> | string |
| p5 | PromiseLike<string> | string |
| p6 | Thenable<string> | string |
| p7 | Thenable<string> | string |
| p8 | ThenPromise<string> | string |
| p9 | JQueryPromise<string> | string |
| p10 | JQueryGenericPromise<string> | string |

Просмотреть файл

@ -1,5 +0,0 @@
import javascript
query predicate test_IsTypeExpr(IsTypeExpr type, VarTypeAccess res0, TypeExpr res1) {
res0 = type.getParameterName() and res1 = type.getPredicateType()
}

Просмотреть файл

@ -0,0 +1,13 @@
import javascript
query predicate test_IsTypeExpr(IsTypeExpr type, VarTypeAccess res0, TypeExpr res1) {
res0 = type.getParameterName() and res1 = type.getPredicateType()
}
query predicate test_PredicateTypeExpr(PredicateTypeExpr type, VarTypeAccess res0) {
res0 = type.getParameterName()
}
query predicate test_hasAssertsKeyword(PredicateTypeExpr type) {
type.hasAssertsKeyword()
}

Просмотреть файл

@ -105,6 +105,9 @@ test_VariableTypes
| tst.ts:135:5:135:24 | tupleWithRestElement | tupleWithRestElement | tst.ts:135:27:135:47 | [number ... ring[]] |
| tst.ts:136:5:136:36 | tupleWi ... lements | tupleWithOptionalAndRestElements | tst.ts:136:39:136:68 | [number ... mber[]] |
| tst.ts:137:5:137:15 | unknownType | unknownType | tst.ts:137:18:137:24 | unknown |
| 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 |
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 |
@ -148,6 +151,17 @@ test_IsTypeExpr
| tst.ts:76:21:76:32 | that is Leaf | tst.ts:76:21:76:24 | that | tst.ts:76:29:76:32 | Leaf |
| tst.ts:80:36:80:55 | x is Generic<Leaf[]> | tst.ts:80:36:80:36 | x | tst.ts:80:41:80:55 | Generic<Leaf[]> |
| tst.ts:81:38:81:50 | x is typeof x | tst.ts:81:38:81:38 | x | tst.ts:81:43:81:50 | typeof x |
| tst.ts:148:36:148:56 | asserts ... string | tst.ts:148:44:148:46 | val | tst.ts:148:51:148:56 | string |
test_PredicateTypeExpr
| tst.ts:75:17:75:28 | this is Leaf | tst.ts:75:17:75:20 | this |
| tst.ts:76:21:76:32 | that is Leaf | tst.ts:76:21:76:24 | that |
| tst.ts:80:36:80:55 | x is Generic<Leaf[]> | tst.ts:80:36:80:36 | x |
| tst.ts:81:38:81:50 | x is typeof x | tst.ts:81:38:81:38 | x |
| tst.ts:142:48:142:64 | asserts condition | tst.ts:142:56:142:64 | condition |
| tst.ts:148:36:148:56 | asserts ... string | tst.ts:148:44:148:46 | val |
test_hasAssertsKeyword
| tst.ts:142:48:142:64 | asserts condition |
| tst.ts:148:36:148:56 | asserts ... string |
test_ThisParameterTypes
| function hasThisParam | tst.ts:116:29:116:32 | void |
| method hasThisParam of interface InterfaceWithThisParam | tst.ts:119:22:119:43 | Interfa ... isParam |
@ -254,6 +268,8 @@ test_ReturnTypes
| tst.ts:94:1:94:37 | functio ... rn x; } | function f1 | tst.ts:94:23:94:23 | S |
| tst.ts:95:1:95:53 | functio ... x,y]; } | function f2 | tst.ts:95:31:95:35 | [S,T] |
| 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 |
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 |

Просмотреть файл

@ -11,7 +11,7 @@ import GenericTypeExpr
import IntersectionTypeExpr
import FunctionTypeReturns
import InterfaceTypeExpr
import IsTypeExpr
import PredicateTypeExpr
import ThisParameterTypes
import ChildIndex
import TypeArguments

Просмотреть файл

@ -138,3 +138,15 @@ let unknownType: unknown;
let taggedTemplateLiteralTypeArg1 = someTag<number>`Hello`;
let taggedTemplateLiteralTypeArg2 = someTag<number, string>`Hello`;
function assert(condition: any, msg?: string): asserts condition {
if (!condition) {
throw new AssertionError(msg)
}
}
function assertIsString(val: any): asserts val is string {
if (typeof val !== "string") {
throw new AssertionError("Not a string!");
}
}

Просмотреть файл

@ -93,6 +93,30 @@
| tst.ts:43:28:43:30 | foo | "foo" |
| tst.ts:43:33:43:37 | "foo" | "foo" |
| 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 |
| type_alias.ts:14:10:14:17 | property | string |
| type_alias.ts:17:5:17:8 | json | Json |
| type_alias.ts:21:18:21:35 | [key: string]: any | any |
| type_alias.ts:21:19:21:21 | key | string |
| type_alias.ts:23:7:23:12 | myNode | VirtualNode |
| type_alias.ts:24:5:27:5 | ["div", ... ]\\n ] | VirtualNode |
| type_alias.ts:24:6:24:10 | "div" | "div" |
| type_alias.ts:24:13:24:28 | { id: "parent" } | string \| { [key: string]: any; } |
| type_alias.ts:24:15:24:16 | id | string |
| type_alias.ts:24:19:24:26 | "parent" | "parent" |
| type_alias.ts:25:9:25:61 | ["div", ... child"] | VirtualNode |
| type_alias.ts:25:10:25:14 | "div" | "div" |
| type_alias.ts:25:17:25:37 | { id: " ... hild" } | string \| { [key: string]: any; } |
| type_alias.ts:25:19:25:20 | id | string |
| type_alias.ts:25:23:25:35 | "first-child" | "first-child" |
| type_alias.ts:25:40:25:60 | "I'm th ... child" | "I'm the first child" |
| type_alias.ts:26:9:26:63 | ["div", ... child"] | VirtualNode |
| type_alias.ts:26:10:26:14 | "div" | "div" |
| type_alias.ts:26:17:26:38 | { id: " ... hild" } | string \| { [key: string]: any; } |
| type_alias.ts:26:19:26:20 | id | string |
| type_alias.ts:26:23:26:36 | "second-child" | "second-child" |
| type_alias.ts:26:41:26:62 | "I'm th ... child" | "I'm the second child" |
| type_definition_objects.ts:1:13:1:17 | dummy | typeof dummy.ts |
| type_definition_objects.ts:1:24:1:32 | "./dummy" | any |
| type_definition_objects.ts:3:14:3:14 | C | C |
@ -115,4 +139,4 @@
| type_definitions.ts:16:5:16:9 | color | Color |
| type_definitions.ts:18:6:18:22 | EnumWithOneMember | EnumWithOneMember |
| type_definitions.ts:19:5:19:5 | e | EnumWithOneMember |
| type_definitions.ts:22:5:22:23 | aliasForNumberArray | number[] |
| type_definitions.ts:22:5:22:23 | aliasForNumberArray | Alias<number> |

Просмотреть файл

@ -1,8 +1,11 @@
| type_alias.ts:1:1:1:17 | type B = boolean; | boolean |
| type_alias.ts:5:1:5:50 | type Va ... ay<T>>; | ValueOrArray<T> |
| type_alias.ts:9:1:15:13 | type Js ... Json[]; | Json |
| type_alias.ts:19:1:21:57 | type Vi ... ode[]]; | VirtualNode |
| type_definition_objects.ts:3:8:3:17 | class C {} | C |
| type_definition_objects.ts:6:8:6:16 | enum E {} | E |
| type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} | I<S> |
| type_definitions.ts:8:1:10:1 | class C ... x: T\\n} | C<T> |
| type_definitions.ts:13:1:15:1 | enum Co ... blue\\n} | Color |
| type_definitions.ts:18:1:18:33 | enum En ... ember } | EnumWithOneMember |
| type_definitions.ts:21:1:21:20 | type Alias<T> = T[]; | T[] |
| type_definitions.ts:21:1:21:20 | type Alias<T> = T[]; | Alias<T> |

Просмотреть файл

@ -57,20 +57,56 @@
| tst.ts:37:17:37:18 | [] | [] |
| tst.ts:38:27:38:47 | [number ... ring[]] | [number, ...string[]] |
| tst.ts:38:28:38:33 | number | number |
| tst.ts:38:36:38:46 | ...string[] | string[] |
| tst.ts:38:36:38:46 | ...string[] | string |
| tst.ts:38:39:38:44 | string | string |
| tst.ts:38:39:38:46 | string[] | string[] |
| tst.ts:39:39:39:68 | [number ... mber[]] | [number, string?, ...number[]] |
| tst.ts:39:40:39:45 | number | number |
| tst.ts:39:48:39:53 | string | string |
| tst.ts:39:48:39:54 | string? | string |
| tst.ts:39:57:39:67 | ...number[] | number[] |
| tst.ts:39:57:39:67 | ...number[] | number |
| tst.ts:39:60:39:65 | number | number |
| tst.ts:39:60:39:67 | number[] | number[] |
| tst.ts:40:18:40:24 | unknown | unknown |
| 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 |
| type_alias.ts:5:6:5:17 | ValueOrArray | ValueOrArray<T> |
| type_alias.ts:5:19:5:19 | T | T |
| type_alias.ts:5:24:5:24 | T | T |
| type_alias.ts:5:24:5:49 | T \| Arr ... ray<T>> | ValueOrArray<T> |
| type_alias.ts:5:28:5:32 | Array | T[] |
| type_alias.ts:5:28:5:49 | Array<V ... ray<T>> | ValueOrArray<T>[] |
| type_alias.ts:5:34:5:45 | ValueOrArray | ValueOrArray<T> |
| type_alias.ts:5:34:5:48 | ValueOrArray<T> | ValueOrArray<T> |
| type_alias.ts:5:47:5:47 | T | T |
| type_alias.ts:7:8:7:19 | ValueOrArray | ValueOrArray<T> |
| type_alias.ts:7:8:7:27 | ValueOrArray<number> | ValueOrArray<number> |
| type_alias.ts:7:21:7:26 | number | number |
| type_alias.ts:9:6:9:9 | Json | Json |
| type_alias.ts:10:5:15:12 | \| strin ... Json[] | Json |
| type_alias.ts:10:7:10:12 | string | string |
| type_alias.ts:11:7:11:12 | number | number |
| type_alias.ts:12:7:12:13 | boolean | boolean |
| type_alias.ts:13:7:13:10 | null | null |
| type_alias.ts:14:7:14:34 | { [prop ... Json } | { [property: string]: Json; } |
| type_alias.ts:14:20:14:25 | string | string |
| type_alias.ts:14:29:14:32 | Json | Json |
| type_alias.ts:15:7:15:10 | Json | Json |
| type_alias.ts:15:7:15:12 | Json[] | Json[] |
| type_alias.ts:17:11:17:14 | Json | Json |
| type_alias.ts:19:6:19:16 | VirtualNode | VirtualNode |
| type_alias.ts:20:5:21:56 | \| strin ... Node[]] | VirtualNode |
| type_alias.ts:20:7:20:12 | string | string |
| type_alias.ts:21:7:21:56 | [string ... Node[]] | [string, { [key: string]: any; }, ...VirtualNod... |
| type_alias.ts:21:8:21:13 | string | string |
| type_alias.ts:21:16:21:37 | { [key: ... : any } | { [key: string]: any; } |
| type_alias.ts:21:24:21:29 | string | string |
| type_alias.ts:21:33:21:35 | any | any |
| type_alias.ts:21:40:21:55 | ...VirtualNode[] | VirtualNode |
| type_alias.ts:21:43:21:53 | VirtualNode | VirtualNode |
| type_alias.ts:21:43:21:55 | VirtualNode[] | VirtualNode[] |
| type_alias.ts:23:15:23:25 | VirtualNode | VirtualNode |
| type_definitions.ts:3:11:3:11 | I | I<S> |
| type_definitions.ts:3:13:3:13 | S | S |
| type_definitions.ts:4:6:4:6 | S | S |
@ -84,10 +120,10 @@
| type_definitions.ts:11:10:11:15 | number | number |
| type_definitions.ts:16:12:16:16 | Color | Color |
| type_definitions.ts:19:8:19:24 | EnumWithOneMember | EnumWithOneMember |
| type_definitions.ts:21:6:21:10 | Alias | T[] |
| type_definitions.ts:21:6:21:10 | Alias | Alias<T> |
| type_definitions.ts:21:12:21:12 | T | T |
| type_definitions.ts:21:17:21:17 | T | T |
| type_definitions.ts:21:17:21:19 | T[] | T[] |
| type_definitions.ts:22:26:22:30 | Alias | T[] |
| type_definitions.ts:22:26:22:38 | Alias<number> | number[] |
| type_definitions.ts:21:17:21:19 | T[] | Alias<T> |
| type_definitions.ts:22:26:22:30 | Alias | Alias<T> |
| type_definitions.ts:22:26:22:38 | Alias<number> | Alias<number> |
| type_definitions.ts:22:32:22:37 | number | number |

Просмотреть файл

@ -1,3 +1,5 @@
| Alias<T> | type_definitions.ts:21:1:21:20 | type Alias<T> = T[]; |
| Alias<number> | type_definitions.ts:21:1:21:20 | type Alias<T> = T[]; |
| C | type_definition_objects.ts:3:8:3:17 | class C {} |
| C<T> | type_definitions.ts:8:1:10:1 | class C ... x: T\\n} |
| C<number> | type_definitions.ts:8:1:10:1 | class C ... x: T\\n} |
@ -9,3 +11,7 @@
| EnumWithOneMember | type_definitions.ts:18:26:18:31 | member |
| I<S> | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} |
| I<number> | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} |
| Json | type_alias.ts:9:1:15:13 | type Js ... Json[]; |
| ValueOrArray<T> | type_alias.ts:5:1:5:50 | type Va ... ay<T>>; |
| ValueOrArray<number> | type_alias.ts:5:1:5:50 | type Va ... ay<T>>; |
| VirtualNode | type_alias.ts:19:1:21:57 | type Vi ... ode[]]; |

Просмотреть файл

@ -1,3 +1,27 @@
type B = boolean;
var b: B;
type ValueOrArray<T> = T | Array<ValueOrArray<T>>;
var c: ValueOrArray<number>;
type Json =
| string
| number
| boolean
| null
| { [property: string]: Json }
| Json[];
var json: Json;
type VirtualNode =
| string
| [string, { [key: string]: any }, ...VirtualNode[]];
const myNode: VirtualNode =
["div", { id: "parent" },
["div", { id: "first-child" }, "I'm the first child"],
["div", { id: "second-child" }, "I'm the second child"]
];

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

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